phpunit-4.7.0 3.0 MB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719387203872138722387233872438725387263872738728387293873038731387323873338734387353873638737387383873938740387413874238743387443874538746387473874838749387503875138752387533875438755387563875738758387593876038761387623876338764387653876638767387683876938770387713877238773387743877538776387773877838779387803878138782387833878438785387863878738788387893879038791387923879338794387953879638797387983879938800388013880238803388043880538806388073880838809388103881138812388133881438815388163881738818388193882038821388223882338824388253882638827388283882938830388313883238833388343883538836388373883838839388403884138842388433884438845388463884738848388493885038851388523885338854388553885638857388583885938860388613886238863388643886538866388673886838869388703887138872388733887438875388763887738878388793888038881388823888338884388853888638887388883888938890388913889238893388943889538896388973889838899389003890138902389033890438905389063890738908389093891038911389123891338914389153891638917389183891938920389213892238923389243892538926389273892838929389303893138932389333893438935389363893738938389393894038941389423894338944389453894638947389483894938950389513895238953389543895538956389573895838959389603896138962389633896438965389663896738968389693897038971389723897338974389753897638977389783897938980389813898238983389843898538986389873898838989389903899138992389933899438995389963899738998389993900039001390023900339004390053900639007390083900939010390113901239013390143901539016390173901839019390203902139022390233902439025390263902739028390293903039031390323903339034390353903639037390383903939040390413904239043390443904539046390473904839049390503905139052390533905439055390563905739058390593906039061390623906339064390653906639067390683906939070390713907239073390743907539076390773907839079390803908139082390833908439085390863908739088390893909039091390923909339094390953909639097390983909939100391013910239103391043910539106391073910839109391103911139112391133911439115391163911739118391193912039121391223912339124391253912639127391283912939130391313913239133391343913539136391373913839139391403914139142391433914439145391463914739148391493915039151391523915339154391553915639157391583915939160391613916239163391643916539166391673916839169391703917139172391733917439175391763917739178391793918039181391823918339184391853918639187391883918939190391913919239193391943919539196391973919839199392003920139202392033920439205392063920739208392093921039211392123921339214392153921639217392183921939220392213922239223392243922539226392273922839229392303923139232392333923439235392363923739238392393924039241392423924339244392453924639247392483924939250392513925239253392543925539256392573925839259392603926139262392633926439265392663926739268392693927039271392723927339274392753927639277392783927939280392813928239283392843928539286392873928839289392903929139292392933929439295392963929739298392993930039301393023930339304393053930639307393083930939310393113931239313393143931539316393173931839319393203932139322393233932439325393263932739328393293933039331393323933339334393353933639337393383933939340393413934239343393443934539346393473934839349393503935139352393533935439355393563935739358393593936039361393623936339364393653936639367393683936939370393713937239373393743937539376393773937839379393803938139382393833938439385393863938739388393893939039391393923939339394393953939639397393983939939400394013940239403394043940539406394073940839409394103941139412394133941439415394163941739418394193942039421394223942339424394253942639427394283942939430394313943239433394343943539436394373943839439394403944139442394433944439445394463944739448394493945039451394523945339454394553945639457394583945939460394613946239463394643946539466394673946839469394703947139472394733947439475394763947739478394793948039481394823948339484394853948639487394883948939490394913949239493394943949539496394973949839499395003950139502395033950439505395063950739508395093951039511395123951339514395153951639517395183951939520395213952239523395243952539526395273952839529395303953139532395333953439535395363953739538395393954039541395423954339544395453954639547395483954939550395513955239553395543955539556395573955839559395603956139562395633956439565395663956739568395693957039571395723957339574395753957639577395783957939580395813958239583395843958539586395873958839589395903959139592395933959439595395963959739598395993960039601396023960339604396053960639607396083960939610396113961239613396143961539616396173961839619396203962139622396233962439625396263962739628396293963039631396323963339634396353963639637396383963939640396413964239643396443964539646396473964839649396503965139652396533965439655396563965739658396593966039661396623966339664396653966639667396683966939670396713967239673396743967539676396773967839679396803968139682396833968439685396863968739688396893969039691396923969339694396953969639697396983969939700397013970239703397043970539706397073970839709397103971139712397133971439715397163971739718397193972039721397223972339724397253972639727397283972939730397313973239733397343973539736397373973839739397403974139742397433974439745397463974739748397493975039751397523975339754397553975639757397583975939760397613976239763397643976539766397673976839769397703977139772397733977439775397763977739778397793978039781397823978339784397853978639787397883978939790397913979239793397943979539796397973979839799398003980139802398033980439805398063980739808398093981039811398123981339814398153981639817398183981939820398213982239823398243982539826398273982839829398303983139832398333983439835398363983739838398393984039841398423984339844398453984639847398483984939850398513985239853398543985539856398573985839859398603986139862398633986439865398663986739868398693987039871398723987339874398753987639877398783987939880398813988239883398843988539886398873988839889398903989139892398933989439895398963989739898398993990039901399023990339904399053990639907399083990939910399113991239913399143991539916399173991839919399203992139922399233992439925399263992739928399293993039931399323993339934399353993639937399383993939940399413994239943399443994539946399473994839949399503995139952399533995439955399563995739958399593996039961399623996339964399653996639967399683996939970399713997239973399743997539976399773997839979399803998139982399833998439985399863998739988399893999039991399923999339994399953999639997399983999940000400014000240003400044000540006400074000840009400104001140012400134001440015400164001740018400194002040021400224002340024400254002640027400284002940030400314003240033400344003540036400374003840039400404004140042400434004440045400464004740048400494005040051400524005340054400554005640057400584005940060400614006240063400644006540066400674006840069400704007140072400734007440075400764007740078400794008040081400824008340084400854008640087400884008940090400914009240093400944009540096400974009840099401004010140102401034010440105401064010740108401094011040111401124011340114401154011640117401184011940120401214012240123401244012540126401274012840129401304013140132401334013440135401364013740138401394014040141401424014340144401454014640147401484014940150401514015240153401544015540156401574015840159401604016140162401634016440165401664016740168401694017040171401724017340174401754017640177401784017940180401814018240183401844018540186401874018840189401904019140192401934019440195401964019740198401994020040201402024020340204402054020640207402084020940210402114021240213402144021540216402174021840219402204022140222402234022440225402264022740228402294023040231402324023340234402354023640237402384023940240402414024240243402444024540246402474024840249402504025140252402534025440255402564025740258402594026040261402624026340264402654026640267402684026940270402714027240273402744027540276402774027840279402804028140282402834028440285402864028740288402894029040291402924029340294402954029640297402984029940300403014030240303403044030540306403074030840309403104031140312403134031440315403164031740318403194032040321403224032340324403254032640327403284032940330403314033240333403344033540336403374033840339403404034140342403434034440345403464034740348403494035040351403524035340354403554035640357403584035940360403614036240363403644036540366403674036840369403704037140372403734037440375403764037740378403794038040381403824038340384403854038640387403884038940390403914039240393403944039540396403974039840399404004040140402404034040440405404064040740408404094041040411404124041340414404154041640417404184041940420404214042240423404244042540426404274042840429404304043140432404334043440435404364043740438404394044040441404424044340444404454044640447404484044940450404514045240453404544045540456404574045840459404604046140462404634046440465404664046740468404694047040471404724047340474404754047640477404784047940480404814048240483404844048540486404874048840489404904049140492404934049440495404964049740498404994050040501405024050340504405054050640507405084050940510405114051240513405144051540516405174051840519405204052140522405234052440525405264052740528405294053040531405324053340534405354053640537405384053940540405414054240543405444054540546405474054840549405504055140552405534055440555405564055740558405594056040561405624056340564405654056640567405684056940570405714057240573405744057540576405774057840579405804058140582405834058440585405864058740588405894059040591405924059340594405954059640597405984059940600406014060240603406044060540606406074060840609406104061140612406134061440615406164061740618406194062040621406224062340624406254062640627406284062940630406314063240633406344063540636406374063840639406404064140642406434064440645406464064740648406494065040651406524065340654406554065640657406584065940660406614066240663406644066540666406674066840669406704067140672406734067440675406764067740678406794068040681406824068340684406854068640687406884068940690406914069240693406944069540696406974069840699407004070140702407034070440705407064070740708407094071040711407124071340714407154071640717407184071940720407214072240723407244072540726407274072840729407304073140732407334073440735407364073740738407394074040741407424074340744407454074640747407484074940750407514075240753407544075540756407574075840759407604076140762407634076440765407664076740768407694077040771407724077340774407754077640777407784077940780407814078240783407844078540786407874078840789407904079140792407934079440795407964079740798407994080040801408024080340804408054080640807408084080940810408114081240813408144081540816408174081840819408204082140822408234082440825408264082740828408294083040831408324083340834408354083640837408384083940840408414084240843408444084540846408474084840849408504085140852408534085440855408564085740858408594086040861408624086340864408654086640867408684086940870408714087240873408744087540876408774087840879408804088140882408834088440885408864088740888408894089040891408924089340894408954089640897408984089940900409014090240903409044090540906409074090840909409104091140912409134091440915409164091740918409194092040921409224092340924409254092640927409284092940930409314093240933409344093540936409374093840939409404094140942409434094440945409464094740948409494095040951409524095340954409554095640957409584095940960409614096240963409644096540966409674096840969409704097140972409734097440975409764097740978409794098040981409824098340984409854098640987409884098940990409914099240993409944099540996409974099840999410004100141002410034100441005410064100741008410094101041011410124101341014410154101641017410184101941020410214102241023410244102541026410274102841029410304103141032410334103441035410364103741038410394104041041410424104341044410454104641047410484104941050410514105241053410544105541056410574105841059410604106141062410634106441065410664106741068410694107041071410724107341074410754107641077410784107941080410814108241083410844108541086410874108841089410904109141092410934109441095410964109741098410994110041101411024110341104411054110641107411084110941110411114111241113411144111541116411174111841119411204112141122411234112441125411264112741128411294113041131411324113341134411354113641137411384113941140411414114241143411444114541146411474114841149411504115141152411534115441155411564115741158411594116041161411624116341164411654116641167411684116941170411714117241173411744117541176411774117841179411804118141182411834118441185411864118741188411894119041191411924119341194411954119641197411984119941200412014120241203412044120541206412074120841209412104121141212412134121441215412164121741218412194122041221412224122341224412254122641227412284122941230412314123241233412344123541236412374123841239412404124141242412434124441245412464124741248412494125041251412524125341254412554125641257412584125941260412614126241263412644126541266412674126841269412704127141272412734127441275412764127741278412794128041281412824128341284412854128641287412884128941290412914129241293412944129541296412974129841299413004130141302413034130441305413064130741308413094131041311413124131341314413154131641317413184131941320413214132241323413244132541326413274132841329413304133141332413334133441335413364133741338413394134041341413424134341344413454134641347413484134941350413514135241353413544135541356413574135841359413604136141362413634136441365413664136741368413694137041371413724137341374413754137641377413784137941380413814138241383413844138541386413874138841389413904139141392413934139441395413964139741398413994140041401414024140341404414054140641407414084140941410414114141241413414144141541416414174141841419414204142141422414234142441425414264142741428414294143041431414324143341434414354143641437414384143941440414414144241443414444144541446414474144841449414504145141452414534145441455414564145741458414594146041461414624146341464414654146641467414684146941470414714147241473414744147541476414774147841479414804148141482414834148441485414864148741488414894149041491414924149341494414954149641497414984149941500415014150241503415044150541506415074150841509415104151141512415134151441515415164151741518415194152041521415224152341524415254152641527415284152941530415314153241533415344153541536415374153841539415404154141542415434154441545415464154741548415494155041551415524155341554415554155641557415584155941560415614156241563415644156541566415674156841569415704157141572415734157441575415764157741578415794158041581415824158341584415854158641587415884158941590415914159241593415944159541596415974159841599416004160141602416034160441605416064160741608416094161041611416124161341614416154161641617416184161941620416214162241623416244162541626416274162841629416304163141632416334163441635416364163741638416394164041641416424164341644416454164641647416484164941650416514165241653416544165541656416574165841659416604166141662416634166441665416664166741668416694167041671416724167341674416754167641677416784167941680416814168241683416844168541686416874168841689416904169141692416934169441695416964169741698416994170041701417024170341704417054170641707417084170941710417114171241713417144171541716417174171841719417204172141722417234172441725417264172741728417294173041731417324173341734417354173641737417384173941740417414174241743417444174541746417474174841749417504175141752417534175441755417564175741758417594176041761417624176341764417654176641767417684176941770417714177241773417744177541776417774177841779417804178141782417834178441785417864178741788417894179041791417924179341794417954179641797417984179941800418014180241803418044180541806418074180841809418104181141812418134181441815418164181741818418194182041821418224182341824418254182641827418284182941830418314183241833418344183541836418374183841839418404184141842418434184441845418464184741848418494185041851418524185341854418554185641857418584185941860418614186241863418644186541866418674186841869418704187141872418734187441875418764187741878418794188041881418824188341884418854188641887418884188941890418914189241893418944189541896418974189841899419004190141902419034190441905419064190741908419094191041911419124191341914419154191641917419184191941920419214192241923419244192541926419274192841929419304193141932419334193441935419364193741938419394194041941419424194341944419454194641947419484194941950419514195241953419544195541956419574195841959419604196141962419634196441965419664196741968419694197041971419724197341974419754197641977419784197941980419814198241983419844198541986419874198841989419904199141992419934199441995419964199741998419994200042001420024200342004420054200642007420084200942010420114201242013420144201542016420174201842019420204202142022420234202442025420264202742028420294203042031420324203342034420354203642037420384203942040420414204242043420444204542046420474204842049420504205142052420534205442055420564205742058420594206042061420624206342064420654206642067420684206942070420714207242073420744207542076420774207842079420804208142082420834208442085420864208742088420894209042091420924209342094420954209642097420984209942100421014210242103421044210542106421074210842109421104211142112421134211442115421164211742118421194212042121421224212342124421254212642127421284212942130421314213242133421344213542136421374213842139421404214142142421434214442145421464214742148421494215042151421524215342154421554215642157421584215942160421614216242163421644216542166421674216842169421704217142172421734217442175421764217742178421794218042181421824218342184421854218642187421884218942190421914219242193421944219542196421974219842199422004220142202422034220442205422064220742208422094221042211422124221342214422154221642217422184221942220422214222242223422244222542226422274222842229422304223142232422334223442235422364223742238422394224042241422424224342244422454224642247422484224942250422514225242253422544225542256422574225842259422604226142262422634226442265422664226742268422694227042271422724227342274422754227642277422784227942280422814228242283422844228542286422874228842289422904229142292422934229442295422964229742298422994230042301423024230342304423054230642307423084230942310423114231242313423144231542316423174231842319423204232142322423234232442325423264232742328423294233042331423324233342334423354233642337423384233942340423414234242343423444234542346423474234842349423504235142352423534235442355423564235742358423594236042361423624236342364423654236642367423684236942370423714237242373423744237542376423774237842379423804238142382423834238442385423864238742388423894239042391423924239342394423954239642397423984239942400424014240242403424044240542406424074240842409424104241142412424134241442415424164241742418424194242042421424224242342424424254242642427424284242942430424314243242433424344243542436424374243842439424404244142442424434244442445424464244742448424494245042451424524245342454424554245642457424584245942460424614246242463424644246542466424674246842469424704247142472424734247442475424764247742478424794248042481424824248342484424854248642487424884248942490424914249242493424944249542496424974249842499425004250142502425034250442505425064250742508425094251042511425124251342514425154251642517425184251942520425214252242523425244252542526425274252842529425304253142532425334253442535425364253742538425394254042541425424254342544425454254642547425484254942550425514255242553425544255542556425574255842559425604256142562425634256442565425664256742568425694257042571425724257342574425754257642577425784257942580425814258242583425844258542586425874258842589425904259142592425934259442595425964259742598425994260042601426024260342604426054260642607426084260942610426114261242613426144261542616426174261842619426204262142622426234262442625426264262742628426294263042631426324263342634426354263642637426384263942640426414264242643426444264542646426474264842649426504265142652426534265442655426564265742658426594266042661426624266342664426654266642667426684266942670426714267242673426744267542676426774267842679426804268142682426834268442685426864268742688426894269042691426924269342694426954269642697426984269942700427014270242703427044270542706427074270842709427104271142712427134271442715427164271742718427194272042721427224272342724427254272642727427284272942730427314273242733427344273542736427374273842739427404274142742427434274442745427464274742748427494275042751427524275342754427554275642757427584275942760427614276242763427644276542766427674276842769427704277142772427734277442775427764277742778427794278042781427824278342784427854278642787427884278942790427914279242793427944279542796427974279842799428004280142802428034280442805428064280742808428094281042811428124281342814428154281642817428184281942820428214282242823428244282542826428274282842829428304283142832428334283442835428364283742838428394284042841428424284342844428454284642847428484284942850428514285242853428544285542856428574285842859428604286142862428634286442865428664286742868428694287042871428724287342874428754287642877428784287942880428814288242883428844288542886428874288842889428904289142892428934289442895428964289742898428994290042901429024290342904429054290642907429084290942910429114291242913429144291542916429174291842919429204292142922429234292442925429264292742928429294293042931429324293342934429354293642937429384293942940429414294242943429444294542946429474294842949429504295142952429534295442955429564295742958429594296042961429624296342964429654296642967429684296942970429714297242973429744297542976429774297842979429804298142982429834298442985429864298742988429894299042991429924299342994429954299642997429984299943000430014300243003430044300543006430074300843009430104301143012430134301443015430164301743018430194302043021430224302343024430254302643027430284302943030430314303243033430344303543036430374303843039430404304143042430434304443045430464304743048430494305043051430524305343054430554305643057430584305943060430614306243063430644306543066430674306843069430704307143072430734307443075430764307743078430794308043081430824308343084430854308643087430884308943090430914309243093430944309543096430974309843099431004310143102431034310443105431064310743108431094311043111431124311343114431154311643117431184311943120431214312243123431244312543126431274312843129431304313143132431334313443135431364313743138431394314043141431424314343144431454314643147431484314943150431514315243153431544315543156431574315843159431604316143162431634316443165431664316743168431694317043171431724317343174431754317643177431784317943180431814318243183431844318543186431874318843189431904319143192431934319443195431964319743198431994320043201432024320343204432054320643207432084320943210432114321243213432144321543216432174321843219432204322143222432234322443225432264322743228432294323043231432324323343234432354323643237432384323943240432414324243243432444324543246432474324843249432504325143252432534325443255432564325743258432594326043261432624326343264432654326643267432684326943270432714327243273432744327543276432774327843279432804328143282432834328443285432864328743288432894329043291432924329343294432954329643297432984329943300433014330243303433044330543306433074330843309433104331143312433134331443315433164331743318433194332043321433224332343324433254332643327433284332943330433314333243333433344333543336433374333843339433404334143342433434334443345433464334743348433494335043351433524335343354433554335643357433584335943360433614336243363433644336543366433674336843369433704337143372433734337443375433764337743378433794338043381433824338343384433854338643387433884338943390433914339243393433944339543396433974339843399434004340143402434034340443405434064340743408434094341043411434124341343414434154341643417434184341943420434214342243423434244342543426434274342843429434304343143432434334343443435434364343743438434394344043441434424344343444434454344643447434484344943450434514345243453434544345543456434574345843459434604346143462434634346443465434664346743468434694347043471434724347343474434754347643477434784347943480434814348243483434844348543486434874348843489434904349143492434934349443495434964349743498434994350043501435024350343504435054350643507435084350943510435114351243513435144351543516435174351843519435204352143522435234352443525435264352743528435294353043531435324353343534435354353643537435384353943540435414354243543435444354543546435474354843549435504355143552435534355443555435564355743558435594356043561435624356343564435654356643567435684356943570435714357243573435744357543576435774357843579435804358143582435834358443585435864358743588435894359043591435924359343594435954359643597435984359943600436014360243603436044360543606436074360843609436104361143612436134361443615436164361743618436194362043621436224362343624436254362643627436284362943630436314363243633436344363543636436374363843639436404364143642436434364443645436464364743648436494365043651436524365343654436554365643657436584365943660436614366243663436644366543666436674366843669436704367143672436734367443675436764367743678436794368043681436824368343684436854368643687436884368943690436914369243693436944369543696436974369843699437004370143702437034370443705437064370743708437094371043711437124371343714437154371643717437184371943720437214372243723437244372543726437274372843729437304373143732437334373443735437364373743738437394374043741437424374343744437454374643747437484374943750437514375243753437544375543756437574375843759437604376143762437634376443765437664376743768437694377043771437724377343774437754377643777437784377943780437814378243783437844378543786437874378843789437904379143792437934379443795437964379743798437994380043801438024380343804438054380643807438084380943810438114381243813438144381543816438174381843819438204382143822438234382443825438264382743828438294383043831438324383343834438354383643837438384383943840438414384243843438444384543846438474384843849438504385143852438534385443855438564385743858438594386043861438624386343864438654386643867438684386943870438714387243873438744387543876438774387843879438804388143882438834388443885438864388743888438894389043891438924389343894438954389643897438984389943900439014390243903439044390543906439074390843909439104391143912439134391443915439164391743918439194392043921439224392343924439254392643927439284392943930439314393243933439344393543936439374393843939439404394143942439434394443945439464394743948439494395043951439524395343954439554395643957439584395943960439614396243963439644396543966439674396843969439704397143972439734397443975439764397743978439794398043981439824398343984439854398643987439884398943990439914399243993439944399543996439974399843999440004400144002440034400444005440064400744008440094401044011440124401344014440154401644017440184401944020440214402244023440244402544026440274402844029440304403144032440334403444035440364403744038440394404044041440424404344044440454404644047440484404944050440514405244053440544405544056440574405844059440604406144062440634406444065440664406744068440694407044071440724407344074440754407644077440784407944080440814408244083440844408544086440874408844089440904409144092440934409444095440964409744098440994410044101441024410344104441054410644107441084410944110441114411244113441144411544116441174411844119441204412144122441234412444125441264412744128441294413044131441324413344134441354413644137441384413944140441414414244143441444414544146441474414844149441504415144152441534415444155441564415744158441594416044161441624416344164441654416644167441684416944170441714417244173441744417544176441774417844179441804418144182441834418444185441864418744188441894419044191441924419344194441954419644197441984419944200442014420244203442044420544206442074420844209442104421144212442134421444215442164421744218442194422044221442224422344224442254422644227442284422944230442314423244233442344423544236442374423844239442404424144242442434424444245442464424744248442494425044251442524425344254442554425644257442584425944260442614426244263442644426544266442674426844269442704427144272442734427444275442764427744278442794428044281442824428344284442854428644287442884428944290442914429244293442944429544296442974429844299443004430144302443034430444305443064430744308443094431044311443124431344314443154431644317443184431944320443214432244323443244432544326443274432844329443304433144332443334433444335443364433744338443394434044341443424434344344443454434644347443484434944350443514435244353443544435544356443574435844359443604436144362443634436444365443664436744368443694437044371443724437344374443754437644377443784437944380443814438244383443844438544386443874438844389443904439144392443934439444395443964439744398443994440044401444024440344404444054440644407444084440944410444114441244413444144441544416444174441844419444204442144422444234442444425444264442744428444294443044431444324443344434444354443644437444384443944440444414444244443444444444544446444474444844449444504445144452444534445444455444564445744458444594446044461444624446344464444654446644467444684446944470444714447244473444744447544476444774447844479444804448144482444834448444485444864448744488444894449044491444924449344494444954449644497444984449944500445014450244503445044450544506445074450844509445104451144512445134451444515445164451744518445194452044521445224452344524445254452644527445284452944530445314453244533445344453544536445374453844539445404454144542445434454444545445464454744548445494455044551445524455344554445554455644557445584455944560445614456244563445644456544566445674456844569445704457144572445734457444575445764457744578445794458044581445824458344584445854458644587445884458944590445914459244593445944459544596445974459844599446004460144602446034460444605446064460744608446094461044611446124461344614446154461644617446184461944620446214462244623446244462544626446274462844629446304463144632446334463444635446364463744638446394464044641446424464344644446454464644647446484464944650446514465244653446544465544656446574465844659446604466144662446634466444665446664466744668446694467044671446724467344674446754467644677446784467944680446814468244683446844468544686446874468844689446904469144692446934469444695446964469744698446994470044701447024470344704447054470644707447084470944710447114471244713447144471544716447174471844719447204472144722447234472444725447264472744728447294473044731447324473344734447354473644737447384473944740447414474244743447444474544746447474474844749447504475144752447534475444755447564475744758447594476044761447624476344764447654476644767447684476944770447714477244773447744477544776447774477844779447804478144782447834478444785447864478744788447894479044791447924479344794447954479644797447984479944800448014480244803448044480544806448074480844809448104481144812448134481444815448164481744818448194482044821448224482344824448254482644827448284482944830448314483244833448344483544836448374483844839448404484144842448434484444845448464484744848448494485044851448524485344854448554485644857448584485944860448614486244863448644486544866448674486844869448704487144872448734487444875448764487744878448794488044881448824488344884448854488644887448884488944890448914489244893448944489544896448974489844899449004490144902449034490444905449064490744908449094491044911449124491344914449154491644917449184491944920449214492244923449244492544926449274492844929449304493144932449334493444935449364493744938449394494044941449424494344944449454494644947449484494944950449514495244953449544495544956449574495844959449604496144962449634496444965449664496744968449694497044971449724497344974449754497644977449784497944980449814498244983449844498544986449874498844989449904499144992449934499444995449964499744998449994500045001450024500345004450054500645007450084500945010450114501245013450144501545016450174501845019450204502145022450234502445025450264502745028450294503045031450324503345034450354503645037450384503945040450414504245043450444504545046450474504845049450504505145052450534505445055450564505745058450594506045061450624506345064450654506645067450684506945070450714507245073450744507545076450774507845079450804508145082450834508445085450864508745088450894509045091450924509345094450954509645097450984509945100451014510245103451044510545106451074510845109451104511145112451134511445115451164511745118451194512045121451224512345124451254512645127451284512945130451314513245133451344513545136451374513845139451404514145142451434514445145451464514745148451494515045151451524515345154451554515645157451584515945160451614516245163451644516545166451674516845169451704517145172451734517445175451764517745178451794518045181451824518345184451854518645187451884518945190451914519245193451944519545196451974519845199452004520145202452034520445205452064520745208452094521045211452124521345214452154521645217452184521945220452214522245223452244522545226452274522845229452304523145232452334523445235452364523745238452394524045241452424524345244452454524645247452484524945250452514525245253452544525545256452574525845259452604526145262452634526445265452664526745268452694527045271452724527345274452754527645277452784527945280452814528245283452844528545286452874528845289452904529145292452934529445295452964529745298452994530045301453024530345304453054530645307453084530945310453114531245313453144531545316453174531845319453204532145322453234532445325453264532745328453294533045331453324533345334453354533645337453384533945340453414534245343453444534545346453474534845349453504535145352453534535445355453564535745358453594536045361453624536345364453654536645367453684536945370453714537245373453744537545376453774537845379453804538145382453834538445385453864538745388453894539045391453924539345394453954539645397453984539945400454014540245403454044540545406454074540845409454104541145412454134541445415454164541745418454194542045421454224542345424454254542645427454284542945430454314543245433454344543545436454374543845439454404544145442454434544445445454464544745448454494545045451454524545345454454554545645457454584545945460454614546245463454644546545466454674546845469454704547145472454734547445475454764547745478454794548045481454824548345484454854548645487454884548945490454914549245493454944549545496454974549845499455004550145502455034550445505455064550745508455094551045511455124551345514455154551645517455184551945520455214552245523455244552545526455274552845529455304553145532455334553445535455364553745538455394554045541455424554345544455454554645547455484554945550455514555245553455544555545556455574555845559455604556145562455634556445565455664556745568455694557045571455724557345574455754557645577455784557945580455814558245583455844558545586455874558845589455904559145592455934559445595455964559745598455994560045601456024560345604456054560645607456084560945610456114561245613456144561545616456174561845619456204562145622456234562445625456264562745628456294563045631456324563345634456354563645637456384563945640456414564245643456444564545646456474564845649456504565145652456534565445655456564565745658456594566045661456624566345664456654566645667456684566945670456714567245673456744567545676456774567845679456804568145682456834568445685456864568745688456894569045691456924569345694456954569645697456984569945700457014570245703457044570545706457074570845709457104571145712457134571445715457164571745718457194572045721457224572345724457254572645727457284572945730457314573245733457344573545736457374573845739457404574145742457434574445745457464574745748457494575045751457524575345754457554575645757457584575945760457614576245763457644576545766457674576845769457704577145772457734577445775457764577745778457794578045781457824578345784457854578645787457884578945790457914579245793457944579545796457974579845799458004580145802458034580445805458064580745808458094581045811458124581345814458154581645817458184581945820458214582245823458244582545826458274582845829458304583145832458334583445835458364583745838458394584045841458424584345844458454584645847458484584945850458514585245853458544585545856458574585845859458604586145862458634586445865458664586745868458694587045871458724587345874458754587645877458784587945880458814588245883458844588545886458874588845889458904589145892458934589445895458964589745898458994590045901459024590345904459054590645907459084590945910459114591245913459144591545916459174591845919459204592145922459234592445925459264592745928459294593045931459324593345934459354593645937459384593945940459414594245943459444594545946459474594845949459504595145952459534595445955459564595745958459594596045961459624596345964459654596645967459684596945970459714597245973459744597545976459774597845979459804598145982459834598445985459864598745988459894599045991459924599345994459954599645997459984599946000460014600246003460044600546006460074600846009460104601146012460134601446015460164601746018460194602046021460224602346024460254602646027460284602946030460314603246033460344603546036460374603846039460404604146042460434604446045460464604746048460494605046051460524605346054460554605646057460584605946060460614606246063460644606546066460674606846069460704607146072460734607446075460764607746078460794608046081460824608346084460854608646087460884608946090460914609246093460944609546096460974609846099461004610146102461034610446105461064610746108461094611046111461124611346114461154611646117461184611946120461214612246123461244612546126461274612846129461304613146132461334613446135461364613746138461394614046141461424614346144461454614646147461484614946150461514615246153461544615546156461574615846159461604616146162461634616446165461664616746168461694617046171461724617346174461754617646177461784617946180461814618246183461844618546186461874618846189461904619146192461934619446195461964619746198461994620046201462024620346204462054620646207462084620946210462114621246213462144621546216462174621846219462204622146222462234622446225462264622746228462294623046231462324623346234462354623646237462384623946240462414624246243462444624546246462474624846249462504625146252462534625446255462564625746258462594626046261462624626346264462654626646267462684626946270462714627246273462744627546276462774627846279462804628146282462834628446285462864628746288462894629046291462924629346294462954629646297462984629946300463014630246303463044630546306463074630846309463104631146312463134631446315463164631746318463194632046321463224632346324463254632646327463284632946330463314633246333463344633546336463374633846339463404634146342463434634446345463464634746348463494635046351463524635346354463554635646357463584635946360463614636246363463644636546366463674636846369463704637146372463734637446375463764637746378463794638046381463824638346384463854638646387463884638946390463914639246393463944639546396463974639846399464004640146402464034640446405464064640746408464094641046411464124641346414464154641646417464184641946420464214642246423464244642546426464274642846429464304643146432464334643446435464364643746438464394644046441464424644346444464454644646447464484644946450464514645246453464544645546456464574645846459464604646146462464634646446465464664646746468464694647046471464724647346474464754647646477464784647946480464814648246483464844648546486464874648846489464904649146492464934649446495464964649746498464994650046501465024650346504465054650646507465084650946510465114651246513465144651546516465174651846519465204652146522465234652446525465264652746528465294653046531465324653346534465354653646537465384653946540465414654246543465444654546546465474654846549465504655146552465534655446555465564655746558465594656046561465624656346564465654656646567465684656946570465714657246573465744657546576465774657846579465804658146582465834658446585465864658746588465894659046591465924659346594465954659646597465984659946600466014660246603466044660546606466074660846609466104661146612466134661446615466164661746618466194662046621466224662346624466254662646627466284662946630466314663246633466344663546636466374663846639466404664146642466434664446645466464664746648466494665046651466524665346654466554665646657466584665946660466614666246663466644666546666466674666846669466704667146672466734667446675466764667746678466794668046681466824668346684466854668646687466884668946690466914669246693466944669546696466974669846699467004670146702467034670446705467064670746708467094671046711467124671346714467154671646717467184671946720467214672246723467244672546726467274672846729467304673146732467334673446735467364673746738467394674046741467424674346744467454674646747467484674946750467514675246753467544675546756467574675846759467604676146762467634676446765467664676746768467694677046771467724677346774467754677646777467784677946780467814678246783467844678546786467874678846789467904679146792467934679446795467964679746798467994680046801468024680346804468054680646807468084680946810468114681246813468144681546816468174681846819468204682146822468234682446825468264682746828468294683046831468324683346834468354683646837468384683946840468414684246843468444684546846468474684846849468504685146852468534685446855468564685746858468594686046861468624686346864468654686646867468684686946870468714687246873468744687546876468774687846879468804688146882468834688446885468864688746888468894689046891468924689346894468954689646897468984689946900469014690246903469044690546906469074690846909469104691146912469134691446915469164691746918469194692046921469224692346924469254692646927469284692946930469314693246933469344693546936469374693846939469404694146942469434694446945469464694746948469494695046951469524695346954469554695646957469584695946960469614696246963469644696546966469674696846969469704697146972469734697446975469764697746978469794698046981469824698346984469854698646987469884698946990469914699246993469944699546996469974699846999470004700147002470034700447005470064700747008470094701047011470124701347014470154701647017470184701947020470214702247023470244702547026470274702847029470304703147032470334703447035470364703747038470394704047041470424704347044470454704647047470484704947050470514705247053470544705547056470574705847059470604706147062470634706447065470664706747068470694707047071470724707347074470754707647077470784707947080470814708247083470844708547086470874708847089470904709147092470934709447095470964709747098470994710047101471024710347104471054710647107471084710947110471114711247113471144711547116471174711847119471204712147122471234712447125471264712747128471294713047131471324713347134471354713647137471384713947140471414714247143471444714547146471474714847149471504715147152471534715447155471564715747158471594716047161471624716347164471654716647167471684716947170471714717247173471744717547176471774717847179471804718147182471834718447185471864718747188471894719047191471924719347194471954719647197471984719947200472014720247203472044720547206472074720847209472104721147212472134721447215472164721747218472194722047221472224722347224472254722647227472284722947230472314723247233472344723547236472374723847239472404724147242472434724447245472464724747248472494725047251472524725347254472554725647257472584725947260472614726247263472644726547266472674726847269472704727147272472734727447275472764727747278472794728047281472824728347284472854728647287472884728947290472914729247293472944729547296472974729847299473004730147302473034730447305473064730747308473094731047311473124731347314473154731647317473184731947320473214732247323473244732547326473274732847329473304733147332473334733447335473364733747338473394734047341473424734347344473454734647347473484734947350473514735247353473544735547356473574735847359473604736147362473634736447365473664736747368473694737047371473724737347374473754737647377473784737947380473814738247383473844738547386473874738847389473904739147392473934739447395473964739747398473994740047401474024740347404474054740647407474084740947410474114741247413474144741547416474174741847419474204742147422474234742447425474264742747428474294743047431474324743347434474354743647437474384743947440474414744247443474444744547446474474744847449474504745147452474534745447455474564745747458474594746047461474624746347464474654746647467474684746947470474714747247473474744747547476474774747847479474804748147482474834748447485474864748747488474894749047491474924749347494474954749647497474984749947500475014750247503475044750547506475074750847509475104751147512475134751447515475164751747518475194752047521475224752347524475254752647527475284752947530475314753247533475344753547536475374753847539475404754147542475434754447545475464754747548475494755047551475524755347554475554755647557475584755947560475614756247563475644756547566475674756847569475704757147572475734757447575475764757747578475794758047581475824758347584475854758647587475884758947590475914759247593475944759547596475974759847599476004760147602476034760447605476064760747608476094761047611476124761347614476154761647617476184761947620476214762247623476244762547626476274762847629476304763147632476334763447635476364763747638476394764047641476424764347644476454764647647476484764947650476514765247653476544765547656476574765847659476604766147662476634766447665476664766747668476694767047671476724767347674476754767647677476784767947680476814768247683476844768547686476874768847689476904769147692476934769447695476964769747698476994770047701477024770347704477054770647707477084770947710477114771247713477144771547716477174771847719477204772147722477234772447725477264772747728477294773047731477324773347734477354773647737477384773947740477414774247743477444774547746477474774847749477504775147752477534775447755477564775747758477594776047761477624776347764477654776647767477684776947770477714777247773477744777547776477774777847779477804778147782477834778447785477864778747788477894779047791477924779347794477954779647797477984779947800478014780247803478044780547806478074780847809478104781147812478134781447815478164781747818478194782047821478224782347824478254782647827478284782947830478314783247833478344783547836478374783847839478404784147842478434784447845478464784747848478494785047851478524785347854478554785647857478584785947860478614786247863478644786547866478674786847869478704787147872478734787447875478764787747878478794788047881478824788347884478854788647887478884788947890478914789247893478944789547896478974789847899479004790147902479034790447905479064790747908479094791047911479124791347914479154791647917479184791947920479214792247923479244792547926479274792847929479304793147932479334793447935479364793747938479394794047941479424794347944479454794647947479484794947950479514795247953479544795547956479574795847959479604796147962479634796447965479664796747968479694797047971479724797347974479754797647977479784797947980479814798247983479844798547986479874798847989479904799147992479934799447995479964799747998479994800048001480024800348004480054800648007480084800948010480114801248013480144801548016480174801848019480204802148022480234802448025480264802748028480294803048031480324803348034480354803648037480384803948040480414804248043480444804548046480474804848049480504805148052480534805448055480564805748058480594806048061480624806348064480654806648067480684806948070480714807248073480744807548076480774807848079480804808148082480834808448085480864808748088480894809048091480924809348094480954809648097480984809948100481014810248103481044810548106481074810848109481104811148112481134811448115481164811748118481194812048121481224812348124481254812648127481284812948130481314813248133481344813548136481374813848139481404814148142481434814448145481464814748148481494815048151481524815348154481554815648157481584815948160481614816248163481644816548166481674816848169481704817148172481734817448175481764817748178481794818048181481824818348184481854818648187481884818948190481914819248193481944819548196481974819848199482004820148202482034820448205482064820748208482094821048211482124821348214482154821648217482184821948220482214822248223482244822548226482274822848229482304823148232482334823448235482364823748238482394824048241482424824348244482454824648247482484824948250482514825248253482544825548256482574825848259482604826148262482634826448265482664826748268482694827048271482724827348274482754827648277482784827948280482814828248283482844828548286482874828848289482904829148292482934829448295482964829748298482994830048301483024830348304483054830648307483084830948310483114831248313483144831548316483174831848319483204832148322483234832448325483264832748328483294833048331483324833348334483354833648337483384833948340483414834248343483444834548346483474834848349483504835148352483534835448355483564835748358483594836048361483624836348364483654836648367483684836948370483714837248373483744837548376483774837848379483804838148382483834838448385483864838748388483894839048391483924839348394483954839648397483984839948400484014840248403484044840548406484074840848409484104841148412484134841448415484164841748418484194842048421484224842348424484254842648427484284842948430484314843248433484344843548436484374843848439484404844148442484434844448445484464844748448484494845048451484524845348454484554845648457484584845948460484614846248463484644846548466484674846848469484704847148472484734847448475484764847748478484794848048481484824848348484484854848648487484884848948490484914849248493484944849548496484974849848499485004850148502485034850448505485064850748508485094851048511485124851348514485154851648517485184851948520485214852248523485244852548526485274852848529485304853148532485334853448535485364853748538485394854048541485424854348544485454854648547485484854948550485514855248553485544855548556485574855848559485604856148562485634856448565485664856748568485694857048571485724857348574485754857648577485784857948580485814858248583485844858548586485874858848589485904859148592485934859448595485964859748598485994860048601486024860348604486054860648607486084860948610486114861248613486144861548616486174861848619486204862148622486234862448625486264862748628486294863048631486324863348634486354863648637486384863948640486414864248643486444864548646486474864848649486504865148652486534865448655486564865748658486594866048661486624866348664486654866648667486684866948670486714867248673486744867548676486774867848679486804868148682486834868448685486864868748688486894869048691486924869348694486954869648697486984869948700487014870248703487044870548706487074870848709487104871148712487134871448715487164871748718487194872048721487224872348724487254872648727487284872948730487314873248733487344873548736487374873848739487404874148742487434874448745487464874748748487494875048751487524875348754487554875648757487584875948760487614876248763487644876548766487674876848769487704877148772487734877448775487764877748778487794878048781487824878348784487854878648787487884878948790487914879248793487944879548796487974879848799488004880148802488034880448805488064880748808488094881048811488124881348814488154881648817488184881948820488214882248823488244882548826488274882848829488304883148832488334883448835488364883748838488394884048841488424884348844488454884648847488484884948850488514885248853488544885548856488574885848859488604886148862488634886448865488664886748868488694887048871488724887348874488754887648877488784887948880488814888248883488844888548886488874888848889488904889148892488934889448895488964889748898488994890048901489024890348904489054890648907489084890948910489114891248913489144891548916489174891848919489204892148922489234892448925489264892748928489294893048931489324893348934489354893648937489384893948940489414894248943489444894548946489474894848949489504895148952489534895448955489564895748958489594896048961489624896348964489654896648967489684896948970489714897248973489744897548976489774897848979489804898148982489834898448985489864898748988489894899048991489924899348994489954899648997489984899949000490014900249003490044900549006490074900849009490104901149012490134901449015490164901749018490194902049021490224902349024490254902649027490284902949030490314903249033490344903549036490374903849039490404904149042490434904449045490464904749048490494905049051490524905349054490554905649057490584905949060490614906249063490644906549066490674906849069490704907149072490734907449075490764907749078490794908049081490824908349084490854908649087490884908949090490914909249093490944909549096490974909849099491004910149102491034910449105491064910749108491094911049111491124911349114491154911649117491184911949120491214912249123491244912549126491274912849129491304913149132491334913449135491364913749138491394914049141491424914349144491454914649147491484914949150491514915249153491544915549156491574915849159491604916149162491634916449165491664916749168491694917049171491724917349174491754917649177491784917949180491814918249183491844918549186491874918849189491904919149192491934919449195491964919749198491994920049201492024920349204492054920649207492084920949210492114921249213492144921549216492174921849219492204922149222492234922449225492264922749228492294923049231492324923349234492354923649237492384923949240492414924249243492444924549246492474924849249492504925149252492534925449255492564925749258492594926049261492624926349264492654926649267492684926949270492714927249273492744927549276492774927849279492804928149282492834928449285492864928749288492894929049291492924929349294492954929649297492984929949300493014930249303493044930549306493074930849309493104931149312493134931449315493164931749318493194932049321493224932349324493254932649327493284932949330493314933249333493344933549336493374933849339493404934149342493434934449345493464934749348493494935049351493524935349354493554935649357493584935949360493614936249363493644936549366493674936849369493704937149372493734937449375493764937749378493794938049381493824938349384493854938649387493884938949390493914939249393493944939549396493974939849399494004940149402494034940449405494064940749408494094941049411494124941349414494154941649417494184941949420494214942249423494244942549426494274942849429494304943149432494334943449435494364943749438494394944049441494424944349444494454944649447494484944949450494514945249453494544945549456494574945849459494604946149462494634946449465494664946749468494694947049471494724947349474494754947649477494784947949480494814948249483494844948549486494874948849489494904949149492494934949449495494964949749498494994950049501495024950349504495054950649507495084950949510495114951249513495144951549516495174951849519495204952149522495234952449525495264952749528495294953049531495324953349534495354953649537495384953949540495414954249543495444954549546495474954849549495504955149552495534955449555495564955749558495594956049561495624956349564495654956649567495684956949570495714957249573495744957549576495774957849579495804958149582495834958449585495864958749588495894959049591495924959349594495954959649597495984959949600496014960249603496044960549606496074960849609496104961149612496134961449615496164961749618496194962049621496224962349624496254962649627496284962949630496314963249633496344963549636496374963849639496404964149642496434964449645496464964749648496494965049651496524965349654496554965649657496584965949660496614966249663496644966549666496674966849669496704967149672496734967449675496764967749678496794968049681496824968349684496854968649687496884968949690496914969249693496944969549696496974969849699497004970149702497034970449705497064970749708497094971049711497124971349714497154971649717497184971949720497214972249723497244972549726497274972849729497304973149732497334973449735497364973749738497394974049741497424974349744497454974649747497484974949750497514975249753497544975549756497574975849759497604976149762497634976449765497664976749768497694977049771497724977349774497754977649777497784977949780497814978249783497844978549786497874978849789497904979149792497934979449795497964979749798497994980049801498024980349804498054980649807498084980949810498114981249813498144981549816498174981849819498204982149822498234982449825498264982749828498294983049831498324983349834498354983649837498384983949840498414984249843498444984549846498474984849849498504985149852498534985449855498564985749858498594986049861498624986349864498654986649867498684986949870498714987249873498744987549876498774987849879498804988149882498834988449885498864988749888498894989049891498924989349894498954989649897498984989949900499014990249903499044990549906499074990849909499104991149912499134991449915499164991749918499194992049921499224992349924499254992649927499284992949930499314993249933499344993549936499374993849939499404994149942499434994449945499464994749948499494995049951499524995349954499554995649957499584995949960499614996249963499644996549966499674996849969499704997149972499734997449975499764997749978499794998049981499824998349984499854998649987499884998949990499914999249993499944999549996499974999849999500005000150002500035000450005500065000750008500095001050011500125001350014500155001650017500185001950020500215002250023500245002550026500275002850029500305003150032500335003450035500365003750038500395004050041500425004350044500455004650047500485004950050500515005250053500545005550056500575005850059500605006150062500635006450065500665006750068500695007050071500725007350074500755007650077500785007950080500815008250083500845008550086500875008850089500905009150092500935009450095500965009750098500995010050101501025010350104501055010650107501085010950110501115011250113501145011550116501175011850119501205012150122501235012450125501265012750128501295013050131501325013350134501355013650137501385013950140501415014250143501445014550146501475014850149501505015150152501535015450155501565015750158501595016050161501625016350164501655016650167501685016950170501715017250173501745017550176501775017850179501805018150182501835018450185501865018750188501895019050191501925019350194501955019650197501985019950200502015020250203502045020550206502075020850209502105021150212502135021450215502165021750218502195022050221502225022350224502255022650227502285022950230502315023250233502345023550236502375023850239502405024150242502435024450245502465024750248502495025050251502525025350254502555025650257502585025950260502615026250263502645026550266502675026850269502705027150272502735027450275502765027750278502795028050281502825028350284502855028650287502885028950290502915029250293502945029550296502975029850299503005030150302503035030450305503065030750308503095031050311503125031350314503155031650317503185031950320503215032250323503245032550326503275032850329503305033150332503335033450335503365033750338503395034050341503425034350344503455034650347503485034950350503515035250353503545035550356503575035850359503605036150362503635036450365503665036750368503695037050371503725037350374503755037650377503785037950380503815038250383503845038550386503875038850389503905039150392503935039450395503965039750398503995040050401504025040350404504055040650407504085040950410504115041250413504145041550416504175041850419504205042150422504235042450425504265042750428504295043050431504325043350434504355043650437504385043950440504415044250443504445044550446504475044850449504505045150452504535045450455504565045750458504595046050461504625046350464504655046650467504685046950470504715047250473504745047550476504775047850479504805048150482504835048450485504865048750488504895049050491504925049350494504955049650497504985049950500505015050250503505045050550506505075050850509505105051150512505135051450515505165051750518505195052050521505225052350524505255052650527505285052950530505315053250533505345053550536505375053850539505405054150542505435054450545505465054750548505495055050551505525055350554505555055650557505585055950560505615056250563505645056550566505675056850569505705057150572505735057450575505765057750578505795058050581505825058350584505855058650587505885058950590505915059250593505945059550596505975059850599506005060150602506035060450605506065060750608506095061050611506125061350614506155061650617506185061950620506215062250623506245062550626506275062850629506305063150632506335063450635506365063750638506395064050641506425064350644506455064650647506485064950650506515065250653506545065550656506575065850659506605066150662506635066450665506665066750668506695067050671506725067350674506755067650677506785067950680506815068250683506845068550686506875068850689506905069150692506935069450695506965069750698506995070050701507025070350704507055070650707507085070950710507115071250713507145071550716507175071850719507205072150722507235072450725507265072750728507295073050731507325073350734507355073650737507385073950740507415074250743507445074550746507475074850749507505075150752507535075450755507565075750758507595076050761507625076350764507655076650767507685076950770507715077250773507745077550776507775077850779507805078150782507835078450785507865078750788507895079050791507925079350794507955079650797507985079950800508015080250803508045080550806508075080850809508105081150812508135081450815508165081750818508195082050821508225082350824508255082650827508285082950830508315083250833508345083550836508375083850839508405084150842508435084450845508465084750848508495085050851508525085350854508555085650857508585085950860508615086250863508645086550866508675086850869508705087150872508735087450875508765087750878508795088050881508825088350884508855088650887508885088950890508915089250893508945089550896508975089850899509005090150902509035090450905509065090750908509095091050911509125091350914509155091650917509185091950920509215092250923509245092550926509275092850929509305093150932509335093450935509365093750938509395094050941509425094350944509455094650947509485094950950509515095250953509545095550956509575095850959509605096150962509635096450965509665096750968509695097050971509725097350974509755097650977509785097950980509815098250983509845098550986509875098850989509905099150992509935099450995509965099750998509995100051001510025100351004510055100651007510085100951010510115101251013510145101551016510175101851019510205102151022510235102451025510265102751028510295103051031510325103351034510355103651037510385103951040510415104251043510445104551046510475104851049510505105151052510535105451055510565105751058510595106051061510625106351064510655106651067510685106951070510715107251073510745107551076510775107851079510805108151082510835108451085510865108751088510895109051091510925109351094510955109651097510985109951100511015110251103511045110551106511075110851109511105111151112511135111451115511165111751118511195112051121511225112351124511255112651127511285112951130511315113251133511345113551136511375113851139511405114151142511435114451145511465114751148511495115051151511525115351154511555115651157511585115951160511615116251163511645116551166511675116851169511705117151172511735117451175511765117751178511795118051181511825118351184511855118651187511885118951190511915119251193511945119551196511975119851199512005120151202512035120451205512065120751208512095121051211512125121351214512155121651217512185121951220512215122251223512245122551226512275122851229512305123151232512335123451235512365123751238512395124051241512425124351244512455124651247512485124951250512515125251253512545125551256512575125851259512605126151262512635126451265512665126751268512695127051271512725127351274512755127651277512785127951280512815128251283512845128551286512875128851289512905129151292512935129451295512965129751298512995130051301513025130351304513055130651307513085130951310513115131251313513145131551316513175131851319513205132151322513235132451325513265132751328513295133051331513325133351334513355133651337513385133951340513415134251343513445134551346513475134851349513505135151352513535135451355513565135751358513595136051361513625136351364513655136651367513685136951370513715137251373513745137551376513775137851379513805138151382513835138451385513865138751388513895139051391513925139351394513955139651397513985139951400514015140251403514045140551406514075140851409514105141151412514135141451415514165141751418514195142051421514225142351424514255142651427514285142951430514315143251433514345143551436514375143851439514405144151442514435144451445514465144751448514495145051451514525145351454514555145651457514585145951460514615146251463514645146551466514675146851469514705147151472514735147451475514765147751478514795148051481514825148351484514855148651487514885148951490514915149251493514945149551496514975149851499515005150151502515035150451505515065150751508515095151051511515125151351514515155151651517515185151951520515215152251523515245152551526515275152851529515305153151532515335153451535515365153751538515395154051541515425154351544515455154651547515485154951550515515155251553515545155551556515575155851559515605156151562515635156451565515665156751568515695157051571515725157351574515755157651577515785157951580515815158251583515845158551586515875158851589515905159151592515935159451595515965159751598515995160051601516025160351604516055160651607516085160951610516115161251613516145161551616516175161851619516205162151622516235162451625516265162751628516295163051631516325163351634516355163651637516385163951640516415164251643516445164551646516475164851649516505165151652516535165451655516565165751658516595166051661516625166351664516655166651667516685166951670516715167251673516745167551676516775167851679516805168151682516835168451685516865168751688516895169051691516925169351694516955169651697516985169951700517015170251703517045170551706517075170851709517105171151712517135171451715517165171751718517195172051721517225172351724517255172651727517285172951730517315173251733517345173551736517375173851739517405174151742517435174451745517465174751748517495175051751517525175351754517555175651757517585175951760517615176251763517645176551766517675176851769517705177151772517735177451775517765177751778517795178051781517825178351784517855178651787517885178951790517915179251793517945179551796517975179851799518005180151802518035180451805518065180751808518095181051811518125181351814518155181651817518185181951820518215182251823518245182551826518275182851829518305183151832518335183451835518365183751838518395184051841518425184351844518455184651847518485184951850518515185251853518545185551856518575185851859518605186151862518635186451865518665186751868518695187051871518725187351874518755187651877518785187951880518815188251883518845188551886518875188851889518905189151892518935189451895518965189751898518995190051901519025190351904519055190651907519085190951910519115191251913519145191551916519175191851919519205192151922519235192451925519265192751928519295193051931519325193351934519355193651937519385193951940519415194251943519445194551946519475194851949519505195151952519535195451955519565195751958519595196051961519625196351964519655196651967519685196951970519715197251973519745197551976519775197851979519805198151982519835198451985519865198751988519895199051991519925199351994519955199651997519985199952000520015200252003520045200552006520075200852009520105201152012520135201452015520165201752018520195202052021520225202352024520255202652027520285202952030520315203252033520345203552036520375203852039520405204152042520435204452045520465204752048520495205052051520525205352054520555205652057520585205952060520615206252063520645206552066520675206852069520705207152072520735207452075520765207752078520795208052081520825208352084520855208652087520885208952090520915209252093520945209552096520975209852099521005210152102521035210452105521065210752108521095211052111521125211352114521155211652117521185211952120521215212252123521245212552126521275212852129521305213152132521335213452135521365213752138521395214052141521425214352144521455214652147521485214952150521515215252153521545215552156521575215852159521605216152162521635216452165521665216752168521695217052171521725217352174521755217652177521785217952180521815218252183521845218552186521875218852189521905219152192521935219452195521965219752198521995220052201522025220352204522055220652207522085220952210522115221252213522145221552216522175221852219522205222152222522235222452225522265222752228522295223052231522325223352234522355223652237522385223952240522415224252243522445224552246522475224852249522505225152252522535225452255522565225752258522595226052261522625226352264522655226652267522685226952270522715227252273522745227552276522775227852279522805228152282522835228452285522865228752288522895229052291522925229352294522955229652297522985229952300523015230252303523045230552306523075230852309523105231152312523135231452315523165231752318523195232052321523225232352324523255232652327523285232952330523315233252333523345233552336523375233852339523405234152342523435234452345523465234752348523495235052351523525235352354523555235652357523585235952360523615236252363523645236552366523675236852369523705237152372523735237452375523765237752378523795238052381523825238352384523855238652387523885238952390523915239252393523945239552396523975239852399524005240152402524035240452405524065240752408524095241052411524125241352414524155241652417524185241952420524215242252423524245242552426524275242852429524305243152432524335243452435524365243752438524395244052441524425244352444524455244652447524485244952450524515245252453524545245552456524575245852459524605246152462524635246452465524665246752468524695247052471524725247352474524755247652477524785247952480524815248252483524845248552486524875248852489524905249152492524935249452495524965249752498524995250052501525025250352504525055250652507525085250952510525115251252513525145251552516525175251852519525205252152522525235252452525525265252752528525295253052531525325253352534525355253652537525385253952540525415254252543525445254552546525475254852549525505255152552525535255452555525565255752558525595256052561525625256352564525655256652567525685256952570525715257252573525745257552576525775257852579525805258152582525835258452585525865258752588525895259052591525925259352594525955259652597525985259952600526015260252603526045260552606526075260852609526105261152612526135261452615526165261752618526195262052621526225262352624526255262652627526285262952630526315263252633526345263552636526375263852639526405264152642526435264452645526465264752648526495265052651526525265352654526555265652657526585265952660526615266252663526645266552666526675266852669526705267152672526735267452675526765267752678526795268052681526825268352684526855268652687526885268952690526915269252693526945269552696526975269852699527005270152702527035270452705527065270752708527095271052711527125271352714527155271652717527185271952720527215272252723527245272552726527275272852729527305273152732527335273452735527365273752738527395274052741527425274352744527455274652747527485274952750527515275252753527545275552756527575275852759527605276152762527635276452765527665276752768527695277052771527725277352774527755277652777527785277952780527815278252783527845278552786527875278852789527905279152792527935279452795527965279752798527995280052801528025280352804528055280652807528085280952810528115281252813528145281552816528175281852819528205282152822528235282452825528265282752828528295283052831528325283352834528355283652837528385283952840528415284252843528445284552846528475284852849528505285152852528535285452855528565285752858528595286052861528625286352864528655286652867528685286952870528715287252873528745287552876528775287852879528805288152882528835288452885528865288752888528895289052891528925289352894528955289652897528985289952900529015290252903529045290552906529075290852909529105291152912529135291452915529165291752918529195292052921529225292352924529255292652927529285292952930529315293252933529345293552936529375293852939529405294152942529435294452945529465294752948529495295052951529525295352954529555295652957529585295952960529615296252963529645296552966529675296852969529705297152972529735297452975529765297752978529795298052981529825298352984529855298652987529885298952990529915299252993529945299552996529975299852999530005300153002530035300453005530065300753008530095301053011530125301353014530155301653017530185301953020530215302253023530245302553026530275302853029530305303153032530335303453035530365303753038530395304053041530425304353044530455304653047530485304953050530515305253053530545305553056530575305853059530605306153062530635306453065530665306753068530695307053071530725307353074530755307653077530785307953080530815308253083530845308553086530875308853089530905309153092530935309453095530965309753098530995310053101531025310353104531055310653107531085310953110531115311253113531145311553116531175311853119531205312153122531235312453125531265312753128531295313053131531325313353134531355313653137531385313953140531415314253143531445314553146531475314853149531505315153152531535315453155531565315753158531595316053161531625316353164531655316653167531685316953170531715317253173531745317553176531775317853179531805318153182531835318453185531865318753188531895319053191531925319353194531955319653197531985319953200532015320253203532045320553206532075320853209532105321153212532135321453215532165321753218532195322053221532225322353224532255322653227532285322953230532315323253233532345323553236532375323853239532405324153242532435324453245532465324753248532495325053251532525325353254532555325653257532585325953260532615326253263532645326553266532675326853269532705327153272532735327453275532765327753278532795328053281532825328353284532855328653287532885328953290532915329253293532945329553296532975329853299533005330153302533035330453305533065330753308533095331053311533125331353314533155331653317533185331953320533215332253323533245332553326533275332853329533305333153332533335333453335533365333753338533395334053341533425334353344533455334653347533485334953350533515335253353533545335553356533575335853359533605336153362533635336453365533665336753368533695337053371533725337353374533755337653377533785337953380533815338253383533845338553386533875338853389533905339153392533935339453395533965339753398533995340053401534025340353404534055340653407534085340953410534115341253413534145341553416534175341853419534205342153422534235342453425534265342753428534295343053431534325343353434534355343653437534385343953440534415344253443534445344553446534475344853449534505345153452534535345453455534565345753458534595346053461534625346353464534655346653467534685346953470534715347253473534745347553476534775347853479534805348153482534835348453485534865348753488534895349053491534925349353494534955349653497534985349953500535015350253503535045350553506535075350853509535105351153512535135351453515535165351753518535195352053521535225352353524535255352653527535285352953530535315353253533535345353553536535375353853539535405354153542535435354453545535465354753548535495355053551535525355353554535555355653557535585355953560535615356253563535645356553566535675356853569535705357153572535735357453575535765357753578535795358053581535825358353584535855358653587535885358953590535915359253593535945359553596535975359853599536005360153602536035360453605536065360753608536095361053611536125361353614536155361653617536185361953620536215362253623536245362553626536275362853629536305363153632536335363453635536365363753638536395364053641536425364353644536455364653647536485364953650536515365253653536545365553656536575365853659536605366153662536635366453665536665366753668536695367053671536725367353674536755367653677536785367953680536815368253683536845368553686536875368853689536905369153692536935369453695536965369753698536995370053701537025370353704537055370653707537085370953710537115371253713537145371553716537175371853719537205372153722537235372453725537265372753728537295373053731537325373353734537355373653737537385373953740537415374253743537445374553746537475374853749537505375153752537535375453755537565375753758537595376053761537625376353764537655376653767537685376953770537715377253773537745377553776537775377853779537805378153782537835378453785537865378753788537895379053791537925379353794537955379653797537985379953800538015380253803538045380553806538075380853809538105381153812538135381453815538165381753818538195382053821538225382353824538255382653827538285382953830538315383253833538345383553836538375383853839538405384153842538435384453845538465384753848538495385053851538525385353854538555385653857538585385953860538615386253863538645386553866538675386853869538705387153872538735387453875538765387753878538795388053881538825388353884538855388653887538885388953890538915389253893538945389553896538975389853899539005390153902539035390453905539065390753908539095391053911539125391353914539155391653917539185391953920539215392253923539245392553926539275392853929539305393153932539335393453935539365393753938539395394053941539425394353944539455394653947539485394953950539515395253953539545395553956539575395853959539605396153962539635396453965539665396753968539695397053971539725397353974539755397653977539785397953980539815398253983539845398553986539875398853989539905399153992539935399453995539965399753998539995400054001540025400354004540055400654007540085400954010540115401254013540145401554016540175401854019540205402154022540235402454025540265402754028540295403054031540325403354034540355403654037540385403954040540415404254043540445404554046540475404854049540505405154052540535405454055540565405754058540595406054061540625406354064540655406654067540685406954070540715407254073540745407554076540775407854079540805408154082540835408454085540865408754088540895409054091540925409354094540955409654097540985409954100541015410254103541045410554106541075410854109541105411154112541135411454115541165411754118541195412054121541225412354124541255412654127541285412954130541315413254133541345413554136541375413854139541405414154142541435414454145541465414754148541495415054151541525415354154541555415654157541585415954160541615416254163541645416554166541675416854169541705417154172541735417454175541765417754178541795418054181541825418354184541855418654187541885418954190541915419254193541945419554196541975419854199542005420154202542035420454205542065420754208542095421054211542125421354214542155421654217542185421954220542215422254223542245422554226542275422854229542305423154232542335423454235542365423754238542395424054241542425424354244542455424654247542485424954250542515425254253542545425554256542575425854259542605426154262542635426454265542665426754268542695427054271542725427354274542755427654277542785427954280542815428254283542845428554286542875428854289542905429154292542935429454295542965429754298542995430054301543025430354304543055430654307543085430954310543115431254313543145431554316543175431854319543205432154322543235432454325543265432754328543295433054331543325433354334543355433654337543385433954340543415434254343543445434554346543475434854349543505435154352543535435454355543565435754358543595436054361543625436354364543655436654367543685436954370543715437254373543745437554376543775437854379543805438154382543835438454385543865438754388543895439054391543925439354394543955439654397543985439954400544015440254403544045440554406544075440854409544105441154412544135441454415544165441754418544195442054421544225442354424544255442654427544285442954430544315443254433544345443554436544375443854439544405444154442544435444454445544465444754448544495445054451544525445354454544555445654457544585445954460544615446254463544645446554466544675446854469544705447154472544735447454475544765447754478544795448054481544825448354484544855448654487544885448954490544915449254493544945449554496544975449854499545005450154502545035450454505545065450754508545095451054511545125451354514545155451654517545185451954520545215452254523545245452554526545275452854529545305453154532545335453454535545365453754538545395454054541545425454354544545455454654547545485454954550545515455254553545545455554556545575455854559545605456154562545635456454565545665456754568545695457054571545725457354574545755457654577545785457954580545815458254583545845458554586545875458854589545905459154592545935459454595545965459754598545995460054601546025460354604546055460654607546085460954610546115461254613546145461554616546175461854619546205462154622546235462454625546265462754628546295463054631546325463354634546355463654637546385463954640546415464254643546445464554646546475464854649546505465154652546535465454655546565465754658546595466054661546625466354664546655466654667546685466954670546715467254673546745467554676546775467854679546805468154682546835468454685546865468754688546895469054691546925469354694546955469654697546985469954700547015470254703547045470554706547075470854709547105471154712547135471454715547165471754718547195472054721547225472354724547255472654727547285472954730547315473254733547345473554736547375473854739547405474154742547435474454745547465474754748547495475054751547525475354754547555475654757547585475954760547615476254763547645476554766547675476854769547705477154772547735477454775547765477754778547795478054781547825478354784547855478654787547885478954790547915479254793547945479554796547975479854799548005480154802548035480454805548065480754808548095481054811548125481354814548155481654817548185481954820548215482254823548245482554826548275482854829548305483154832548335483454835548365483754838548395484054841548425484354844548455484654847548485484954850548515485254853548545485554856548575485854859548605486154862548635486454865548665486754868548695487054871548725487354874548755487654877548785487954880548815488254883548845488554886548875488854889548905489154892548935489454895548965489754898548995490054901549025490354904549055490654907549085490954910549115491254913549145491554916549175491854919549205492154922549235492454925549265492754928549295493054931549325493354934549355493654937549385493954940549415494254943549445494554946549475494854949549505495154952549535495454955549565495754958549595496054961549625496354964549655496654967549685496954970549715497254973549745497554976549775497854979549805498154982549835498454985549865498754988549895499054991549925499354994549955499654997549985499955000550015500255003550045500555006550075500855009550105501155012550135501455015550165501755018550195502055021550225502355024550255502655027550285502955030550315503255033550345503555036550375503855039550405504155042550435504455045550465504755048550495505055051550525505355054550555505655057550585505955060550615506255063550645506555066550675506855069550705507155072550735507455075550765507755078550795508055081550825508355084550855508655087550885508955090550915509255093550945509555096550975509855099551005510155102551035510455105551065510755108551095511055111551125511355114551155511655117551185511955120551215512255123551245512555126551275512855129551305513155132551335513455135551365513755138551395514055141551425514355144551455514655147551485514955150551515515255153551545515555156551575515855159551605516155162551635516455165551665516755168551695517055171551725517355174551755517655177551785517955180551815518255183551845518555186551875518855189551905519155192551935519455195551965519755198551995520055201552025520355204552055520655207552085520955210552115521255213552145521555216552175521855219552205522155222552235522455225552265522755228552295523055231552325523355234552355523655237552385523955240552415524255243552445524555246552475524855249552505525155252552535525455255552565525755258552595526055261552625526355264552655526655267552685526955270552715527255273552745527555276552775527855279552805528155282552835528455285552865528755288552895529055291552925529355294552955529655297552985529955300553015530255303553045530555306553075530855309553105531155312553135531455315553165531755318553195532055321553225532355324553255532655327553285532955330553315533255333553345533555336553375533855339553405534155342553435534455345553465534755348553495535055351553525535355354553555535655357553585535955360553615536255363553645536555366553675536855369553705537155372553735537455375553765537755378553795538055381553825538355384553855538655387553885538955390553915539255393553945539555396553975539855399554005540155402554035540455405554065540755408554095541055411554125541355414554155541655417554185541955420554215542255423554245542555426554275542855429554305543155432554335543455435554365543755438554395544055441554425544355444554455544655447554485544955450554515545255453554545545555456554575545855459554605546155462554635546455465554665546755468554695547055471554725547355474554755547655477554785547955480554815548255483554845548555486554875548855489554905549155492554935549455495554965549755498554995550055501555025550355504555055550655507555085550955510555115551255513555145551555516555175551855519555205552155522555235552455525555265552755528555295553055531555325553355534555355553655537555385553955540555415554255543555445554555546555475554855549555505555155552555535555455555555565555755558555595556055561555625556355564555655556655567555685556955570555715557255573555745557555576555775557855579555805558155582555835558455585555865558755588555895559055591555925559355594555955559655597555985559955600556015560255603556045560555606556075560855609556105561155612556135561455615556165561755618556195562055621556225562355624556255562655627556285562955630556315563255633556345563555636556375563855639556405564155642556435564455645556465564755648556495565055651556525565355654556555565655657556585565955660556615566255663556645566555666556675566855669556705567155672556735567455675556765567755678556795568055681556825568355684556855568655687556885568955690556915569255693556945569555696556975569855699557005570155702557035570455705557065570755708557095571055711557125571355714557155571655717557185571955720557215572255723557245572555726557275572855729557305573155732557335573455735557365573755738557395574055741557425574355744557455574655747557485574955750557515575255753557545575555756557575575855759557605576155762557635576455765557665576755768557695577055771557725577355774557755577655777557785577955780557815578255783557845578555786557875578855789557905579155792557935579455795557965579755798557995580055801558025580355804558055580655807558085580955810558115581255813558145581555816558175581855819558205582155822558235582455825558265582755828558295583055831558325583355834558355583655837558385583955840558415584255843558445584555846558475584855849558505585155852558535585455855558565585755858558595586055861558625586355864558655586655867558685586955870558715587255873558745587555876558775587855879558805588155882558835588455885558865588755888558895589055891558925589355894558955589655897558985589955900559015590255903559045590555906559075590855909559105591155912559135591455915559165591755918559195592055921559225592355924559255592655927559285592955930559315593255933559345593555936559375593855939559405594155942559435594455945559465594755948559495595055951559525595355954559555595655957559585595955960559615596255963559645596555966559675596855969559705597155972559735597455975559765597755978559795598055981559825598355984559855598655987559885598955990559915599255993559945599555996559975599855999560005600156002560035600456005560065600756008560095601056011560125601356014560155601656017560185601956020560215602256023560245602556026560275602856029560305603156032560335603456035560365603756038560395604056041560425604356044560455604656047560485604956050560515605256053560545605556056560575605856059560605606156062560635606456065560665606756068560695607056071560725607356074560755607656077560785607956080560815608256083560845608556086560875608856089560905609156092560935609456095560965609756098560995610056101561025610356104561055610656107561085610956110561115611256113561145611556116561175611856119561205612156122561235612456125561265612756128561295613056131561325613356134561355613656137561385613956140561415614256143561445614556146561475614856149561505615156152561535615456155561565615756158561595616056161561625616356164561655616656167561685616956170561715617256173561745617556176561775617856179561805618156182561835618456185561865618756188561895619056191561925619356194561955619656197561985619956200562015620256203562045620556206562075620856209562105621156212562135621456215562165621756218562195622056221562225622356224562255622656227562285622956230562315623256233562345623556236562375623856239562405624156242562435624456245562465624756248562495625056251562525625356254562555625656257562585625956260562615626256263562645626556266562675626856269562705627156272562735627456275562765627756278562795628056281562825628356284562855628656287562885628956290562915629256293562945629556296562975629856299563005630156302563035630456305563065630756308563095631056311563125631356314563155631656317563185631956320563215632256323563245632556326563275632856329563305633156332563335633456335563365633756338563395634056341563425634356344563455634656347563485634956350563515635256353563545635556356563575635856359563605636156362563635636456365563665636756368563695637056371563725637356374563755637656377563785637956380563815638256383563845638556386563875638856389563905639156392563935639456395563965639756398563995640056401564025640356404564055640656407564085640956410564115641256413564145641556416564175641856419564205642156422564235642456425564265642756428564295643056431564325643356434564355643656437564385643956440564415644256443564445644556446564475644856449564505645156452564535645456455564565645756458564595646056461564625646356464564655646656467564685646956470564715647256473564745647556476564775647856479564805648156482564835648456485564865648756488564895649056491564925649356494564955649656497564985649956500565015650256503565045650556506565075650856509565105651156512565135651456515565165651756518565195652056521565225652356524565255652656527565285652956530565315653256533565345653556536565375653856539565405654156542565435654456545565465654756548565495655056551565525655356554565555655656557565585655956560565615656256563565645656556566565675656856569565705657156572565735657456575565765657756578565795658056581565825658356584565855658656587565885658956590565915659256593565945659556596565975659856599566005660156602566035660456605566065660756608566095661056611566125661356614566155661656617566185661956620566215662256623566245662556626566275662856629566305663156632566335663456635566365663756638566395664056641566425664356644566455664656647566485664956650566515665256653566545665556656566575665856659566605666156662566635666456665566665666756668566695667056671566725667356674566755667656677566785667956680566815668256683566845668556686566875668856689566905669156692566935669456695566965669756698566995670056701567025670356704567055670656707567085670956710567115671256713567145671556716567175671856719567205672156722567235672456725567265672756728567295673056731567325673356734567355673656737567385673956740567415674256743567445674556746567475674856749567505675156752567535675456755567565675756758567595676056761567625676356764567655676656767567685676956770567715677256773567745677556776567775677856779567805678156782567835678456785567865678756788567895679056791567925679356794567955679656797567985679956800568015680256803568045680556806568075680856809568105681156812568135681456815568165681756818568195682056821568225682356824568255682656827568285682956830568315683256833568345683556836568375683856839568405684156842568435684456845568465684756848568495685056851568525685356854568555685656857568585685956860568615686256863568645686556866568675686856869568705687156872568735687456875568765687756878568795688056881568825688356884568855688656887568885688956890568915689256893568945689556896568975689856899569005690156902569035690456905569065690756908569095691056911569125691356914569155691656917569185691956920569215692256923569245692556926569275692856929569305693156932569335693456935569365693756938569395694056941569425694356944569455694656947569485694956950569515695256953569545695556956569575695856959569605696156962569635696456965569665696756968569695697056971569725697356974569755697656977569785697956980569815698256983569845698556986569875698856989569905699156992569935699456995569965699756998569995700057001570025700357004570055700657007570085700957010570115701257013570145701557016570175701857019570205702157022570235702457025570265702757028570295703057031570325703357034570355703657037570385703957040570415704257043570445704557046570475704857049570505705157052570535705457055570565705757058570595706057061570625706357064570655706657067570685706957070570715707257073570745707557076570775707857079570805708157082570835708457085570865708757088570895709057091570925709357094570955709657097570985709957100571015710257103571045710557106571075710857109571105711157112571135711457115571165711757118571195712057121571225712357124571255712657127571285712957130571315713257133571345713557136571375713857139571405714157142571435714457145571465714757148571495715057151571525715357154571555715657157571585715957160571615716257163571645716557166571675716857169571705717157172571735717457175571765717757178571795718057181571825718357184571855718657187571885718957190571915719257193571945719557196571975719857199572005720157202572035720457205572065720757208572095721057211572125721357214572155721657217572185721957220572215722257223572245722557226572275722857229572305723157232572335723457235572365723757238572395724057241572425724357244572455724657247572485724957250572515725257253572545725557256572575725857259572605726157262572635726457265572665726757268572695727057271572725727357274572755727657277572785727957280572815728257283572845728557286572875728857289572905729157292572935729457295572965729757298572995730057301573025730357304573055730657307573085730957310573115731257313573145731557316573175731857319573205732157322573235732457325573265732757328573295733057331573325733357334573355733657337573385733957340573415734257343573445734557346573475734857349573505735157352573535735457355573565735757358573595736057361573625736357364573655736657367573685736957370573715737257373573745737557376573775737857379573805738157382573835738457385573865738757388573895739057391573925739357394573955739657397573985739957400574015740257403574045740557406574075740857409574105741157412574135741457415574165741757418574195742057421574225742357424574255742657427574285742957430574315743257433574345743557436574375743857439574405744157442574435744457445574465744757448574495745057451574525745357454574555745657457574585745957460574615746257463574645746557466574675746857469574705747157472574735747457475574765747757478574795748057481574825748357484574855748657487574885748957490574915749257493574945749557496574975749857499575005750157502575035750457505575065750757508575095751057511575125751357514575155751657517575185751957520575215752257523575245752557526575275752857529575305753157532575335753457535575365753757538575395754057541575425754357544575455754657547575485754957550575515755257553575545755557556575575755857559575605756157562575635756457565575665756757568575695757057571575725757357574575755757657577575785757957580575815758257583575845758557586575875758857589575905759157592575935759457595575965759757598575995760057601576025760357604576055760657607576085760957610576115761257613576145761557616576175761857619576205762157622576235762457625576265762757628576295763057631576325763357634576355763657637576385763957640576415764257643576445764557646576475764857649576505765157652576535765457655576565765757658576595766057661576625766357664576655766657667576685766957670576715767257673576745767557676576775767857679576805768157682576835768457685576865768757688576895769057691576925769357694576955769657697576985769957700577015770257703577045770557706577075770857709577105771157712577135771457715577165771757718577195772057721577225772357724577255772657727577285772957730577315773257733577345773557736577375773857739577405774157742577435774457745577465774757748577495775057751577525775357754577555775657757577585775957760577615776257763577645776557766577675776857769577705777157772577735777457775577765777757778577795778057781577825778357784577855778657787577885778957790577915779257793577945779557796577975779857799578005780157802578035780457805578065780757808578095781057811578125781357814578155781657817578185781957820578215782257823578245782557826578275782857829578305783157832578335783457835578365783757838578395784057841578425784357844578455784657847578485784957850578515785257853578545785557856578575785857859578605786157862578635786457865578665786757868578695787057871578725787357874578755787657877578785787957880578815788257883578845788557886578875788857889578905789157892578935789457895578965789757898578995790057901579025790357904579055790657907579085790957910579115791257913579145791557916579175791857919579205792157922579235792457925579265792757928579295793057931579325793357934579355793657937579385793957940579415794257943579445794557946579475794857949579505795157952579535795457955579565795757958579595796057961579625796357964579655796657967579685796957970579715797257973579745797557976579775797857979579805798157982579835798457985579865798757988579895799057991579925799357994579955799657997579985799958000580015800258003580045800558006580075800858009580105801158012580135801458015580165801758018580195802058021580225802358024580255802658027580285802958030580315803258033580345803558036580375803858039580405804158042580435804458045580465804758048580495805058051580525805358054580555805658057580585805958060580615806258063580645806558066580675806858069580705807158072580735807458075580765807758078580795808058081580825808358084580855808658087580885808958090580915809258093580945809558096580975809858099581005810158102581035810458105581065810758108581095811058111581125811358114581155811658117581185811958120581215812258123581245812558126581275812858129581305813158132581335813458135581365813758138581395814058141581425814358144581455814658147581485814958150581515815258153581545815558156581575815858159581605816158162581635816458165581665816758168581695817058171581725817358174581755817658177581785817958180581815818258183581845818558186581875818858189581905819158192581935819458195581965819758198581995820058201582025820358204582055820658207582085820958210582115821258213582145821558216582175821858219582205822158222582235822458225582265822758228582295823058231582325823358234582355823658237582385823958240582415824258243582445824558246582475824858249582505825158252582535825458255582565825758258582595826058261582625826358264582655826658267582685826958270582715827258273582745827558276582775827858279582805828158282582835828458285582865828758288582895829058291582925829358294582955829658297582985829958300583015830258303583045830558306583075830858309583105831158312583135831458315583165831758318583195832058321583225832358324583255832658327583285832958330583315833258333583345833558336583375833858339583405834158342583435834458345583465834758348583495835058351583525835358354583555835658357583585835958360583615836258363583645836558366583675836858369583705837158372583735837458375583765837758378583795838058381583825838358384583855838658387583885838958390583915839258393583945839558396583975839858399584005840158402584035840458405584065840758408584095841058411584125841358414584155841658417584185841958420584215842258423584245842558426584275842858429584305843158432584335843458435584365843758438584395844058441584425844358444584455844658447584485844958450584515845258453584545845558456584575845858459584605846158462584635846458465584665846758468584695847058471584725847358474584755847658477584785847958480584815848258483584845848558486584875848858489584905849158492584935849458495584965849758498584995850058501585025850358504585055850658507585085850958510585115851258513585145851558516585175851858519585205852158522585235852458525585265852758528585295853058531585325853358534585355853658537585385853958540585415854258543585445854558546585475854858549585505855158552585535855458555585565855758558585595856058561585625856358564585655856658567585685856958570585715857258573585745857558576585775857858579585805858158582585835858458585585865858758588585895859058591585925859358594585955859658597585985859958600586015860258603586045860558606586075860858609586105861158612586135861458615586165861758618586195862058621586225862358624586255862658627586285862958630586315863258633586345863558636586375863858639586405864158642586435864458645586465864758648586495865058651586525865358654586555865658657586585865958660586615866258663586645866558666586675866858669586705867158672586735867458675586765867758678586795868058681586825868358684586855868658687586885868958690586915869258693586945869558696586975869858699587005870158702587035870458705587065870758708587095871058711587125871358714587155871658717587185871958720587215872258723587245872558726587275872858729587305873158732587335873458735587365873758738587395874058741587425874358744587455874658747587485874958750587515875258753587545875558756587575875858759587605876158762587635876458765587665876758768587695877058771587725877358774587755877658777587785877958780587815878258783587845878558786587875878858789587905879158792587935879458795587965879758798587995880058801588025880358804588055880658807588085880958810588115881258813588145881558816588175881858819588205882158822588235882458825588265882758828588295883058831588325883358834588355883658837588385883958840588415884258843588445884558846588475884858849588505885158852588535885458855588565885758858588595886058861588625886358864588655886658867588685886958870588715887258873588745887558876588775887858879588805888158882588835888458885588865888758888588895889058891588925889358894588955889658897588985889958900589015890258903589045890558906589075890858909589105891158912589135891458915589165891758918589195892058921589225892358924589255892658927589285892958930589315893258933589345893558936589375893858939589405894158942589435894458945589465894758948589495895058951589525895358954589555895658957589585895958960589615896258963589645896558966589675896858969589705897158972589735897458975589765897758978589795898058981589825898358984589855898658987589885898958990589915899258993589945899558996589975899858999590005900159002590035900459005590065900759008590095901059011590125901359014590155901659017590185901959020590215902259023590245902559026590275902859029590305903159032590335903459035590365903759038590395904059041590425904359044590455904659047590485904959050590515905259053590545905559056590575905859059590605906159062590635906459065590665906759068590695907059071590725907359074590755907659077590785907959080590815908259083590845908559086590875908859089590905909159092590935909459095590965909759098590995910059101591025910359104591055910659107591085910959110591115911259113591145911559116591175911859119591205912159122591235912459125591265912759128591295913059131591325913359134591355913659137591385913959140591415914259143591445914559146591475914859149591505915159152591535915459155591565915759158591595916059161591625916359164591655916659167591685916959170591715917259173591745917559176591775917859179591805918159182591835918459185591865918759188591895919059191591925919359194591955919659197591985919959200592015920259203592045920559206592075920859209592105921159212592135921459215592165921759218592195922059221592225922359224592255922659227592285922959230592315923259233592345923559236592375923859239592405924159242592435924459245592465924759248592495925059251592525925359254592555925659257592585925959260592615926259263592645926559266592675926859269592705927159272592735927459275592765927759278592795928059281592825928359284592855928659287592885928959290592915929259293592945929559296592975929859299593005930159302593035930459305593065930759308593095931059311593125931359314593155931659317593185931959320593215932259323593245932559326593275932859329593305933159332593335933459335593365933759338593395934059341593425934359344593455934659347593485934959350593515935259353593545935559356593575935859359593605936159362593635936459365593665936759368593695937059371593725937359374593755937659377593785937959380593815938259383593845938559386593875938859389593905939159392593935939459395593965939759398593995940059401594025940359404594055940659407594085940959410594115941259413594145941559416594175941859419594205942159422594235942459425594265942759428594295943059431594325943359434594355943659437594385943959440594415944259443594445944559446594475944859449594505945159452594535945459455594565945759458594595946059461594625946359464594655946659467594685946959470594715947259473594745947559476594775947859479594805948159482594835948459485594865948759488594895949059491594925949359494594955949659497594985949959500595015950259503595045950559506595075950859509595105951159512595135951459515595165951759518595195952059521595225952359524595255952659527595285952959530595315953259533595345953559536595375953859539595405954159542595435954459545595465954759548595495955059551595525955359554595555955659557595585955959560595615956259563595645956559566595675956859569595705957159572595735957459575595765957759578595795958059581595825958359584595855958659587595885958959590595915959259593595945959559596595975959859599596005960159602596035960459605596065960759608596095961059611596125961359614596155961659617596185961959620596215962259623596245962559626596275962859629596305963159632596335963459635596365963759638596395964059641596425964359644596455964659647596485964959650596515965259653596545965559656596575965859659596605966159662596635966459665596665966759668596695967059671596725967359674596755967659677596785967959680596815968259683596845968559686596875968859689596905969159692596935969459695596965969759698596995970059701597025970359704597055970659707597085970959710597115971259713597145971559716597175971859719597205972159722597235972459725597265972759728597295973059731597325973359734597355973659737597385973959740597415974259743597445974559746597475974859749597505975159752597535975459755597565975759758597595976059761597625976359764597655976659767597685976959770597715977259773597745977559776597775977859779597805978159782597835978459785597865978759788597895979059791597925979359794597955979659797597985979959800598015980259803598045980559806598075980859809598105981159812598135981459815598165981759818598195982059821598225982359824598255982659827598285982959830598315983259833598345983559836598375983859839598405984159842598435984459845598465984759848598495985059851598525985359854598555985659857598585985959860598615986259863598645986559866598675986859869598705987159872598735987459875598765987759878598795988059881598825988359884598855988659887598885988959890598915989259893598945989559896598975989859899599005990159902599035990459905599065990759908599095991059911599125991359914599155991659917599185991959920599215992259923599245992559926599275992859929599305993159932599335993459935599365993759938599395994059941599425994359944599455994659947599485994959950599515995259953599545995559956599575995859959599605996159962599635996459965599665996759968599695997059971599725997359974599755997659977599785997959980599815998259983599845998559986599875998859989599905999159992599935999459995599965999759998599996000060001600026000360004600056000660007600086000960010600116001260013600146001560016600176001860019600206002160022600236002460025600266002760028600296003060031600326003360034600356003660037600386003960040600416004260043600446004560046600476004860049600506005160052600536005460055600566005760058600596006060061600626006360064600656006660067600686006960070600716007260073600746007560076600776007860079600806008160082600836008460085600866008760088600896009060091600926009360094600956009660097600986009960100601016010260103601046010560106601076010860109601106011160112601136011460115601166011760118601196012060121601226012360124601256012660127601286012960130601316013260133601346013560136601376013860139601406014160142601436014460145601466014760148601496015060151601526015360154601556015660157601586015960160601616016260163601646016560166601676016860169601706017160172601736017460175601766017760178601796018060181601826018360184601856018660187601886018960190601916019260193601946019560196601976019860199602006020160202602036020460205602066020760208602096021060211602126021360214602156021660217602186021960220602216022260223602246022560226602276022860229602306023160232602336023460235602366023760238602396024060241602426024360244602456024660247602486024960250602516025260253602546025560256602576025860259602606026160262602636026460265602666026760268602696027060271602726027360274602756027660277602786027960280602816028260283602846028560286602876028860289602906029160292602936029460295602966029760298602996030060301603026030360304603056030660307603086030960310603116031260313603146031560316603176031860319603206032160322603236032460325603266032760328603296033060331603326033360334603356033660337603386033960340603416034260343603446034560346603476034860349603506035160352603536035460355603566035760358603596036060361603626036360364603656036660367603686036960370603716037260373603746037560376603776037860379603806038160382603836038460385603866038760388603896039060391603926039360394603956039660397603986039960400604016040260403604046040560406604076040860409604106041160412604136041460415604166041760418604196042060421604226042360424604256042660427604286042960430604316043260433604346043560436604376043860439604406044160442604436044460445604466044760448604496045060451604526045360454604556045660457604586045960460604616046260463604646046560466604676046860469604706047160472604736047460475604766047760478604796048060481604826048360484604856048660487604886048960490604916049260493604946049560496604976049860499605006050160502605036050460505605066050760508605096051060511605126051360514605156051660517605186051960520605216052260523605246052560526605276052860529605306053160532605336053460535605366053760538605396054060541605426054360544605456054660547605486054960550605516055260553605546055560556605576055860559605606056160562605636056460565605666056760568605696057060571605726057360574605756057660577605786057960580605816058260583605846058560586605876058860589605906059160592605936059460595605966059760598605996060060601606026060360604606056060660607606086060960610606116061260613606146061560616606176061860619606206062160622606236062460625606266062760628606296063060631606326063360634606356063660637606386063960640606416064260643606446064560646606476064860649606506065160652606536065460655606566065760658606596066060661606626066360664606656066660667606686066960670606716067260673606746067560676606776067860679606806068160682606836068460685606866068760688606896069060691606926069360694606956069660697606986069960700607016070260703607046070560706607076070860709607106071160712607136071460715607166071760718607196072060721607226072360724607256072660727607286072960730607316073260733607346073560736607376073860739607406074160742607436074460745607466074760748607496075060751607526075360754607556075660757607586075960760607616076260763607646076560766607676076860769607706077160772607736077460775607766077760778607796078060781607826078360784607856078660787607886078960790607916079260793607946079560796607976079860799608006080160802608036080460805608066080760808608096081060811608126081360814608156081660817608186081960820608216082260823608246082560826608276082860829608306083160832608336083460835608366083760838608396084060841608426084360844608456084660847608486084960850608516085260853608546085560856608576085860859608606086160862608636086460865608666086760868608696087060871608726087360874608756087660877608786087960880608816088260883608846088560886608876088860889608906089160892608936089460895608966089760898608996090060901609026090360904609056090660907609086090960910609116091260913609146091560916609176091860919609206092160922609236092460925609266092760928609296093060931609326093360934609356093660937609386093960940609416094260943609446094560946609476094860949609506095160952609536095460955609566095760958609596096060961609626096360964609656096660967609686096960970609716097260973609746097560976609776097860979609806098160982609836098460985609866098760988609896099060991609926099360994609956099660997609986099961000610016100261003610046100561006610076100861009610106101161012610136101461015610166101761018610196102061021610226102361024610256102661027610286102961030610316103261033610346103561036610376103861039610406104161042610436104461045610466104761048610496105061051610526105361054610556105661057610586105961060610616106261063610646106561066610676106861069610706107161072610736107461075610766107761078610796108061081610826108361084610856108661087610886108961090610916109261093610946109561096610976109861099611006110161102611036110461105611066110761108611096111061111611126111361114611156111661117611186111961120611216112261123611246112561126611276112861129611306113161132611336113461135611366113761138611396114061141611426114361144611456114661147611486114961150611516115261153611546115561156611576115861159611606116161162611636116461165611666116761168611696117061171611726117361174611756117661177611786117961180611816118261183611846118561186611876118861189611906119161192611936119461195611966119761198611996120061201612026120361204612056120661207612086120961210612116121261213612146121561216612176121861219612206122161222612236122461225612266122761228612296123061231612326123361234612356123661237612386123961240612416124261243612446124561246612476124861249612506125161252612536125461255612566125761258612596126061261612626126361264612656126661267612686126961270612716127261273612746127561276612776127861279612806128161282612836128461285612866128761288612896129061291612926129361294612956129661297612986129961300613016130261303613046130561306613076130861309613106131161312613136131461315613166131761318613196132061321613226132361324613256132661327613286132961330613316133261333613346133561336613376133861339613406134161342613436134461345613466134761348613496135061351613526135361354613556135661357613586135961360613616136261363613646136561366613676136861369613706137161372613736137461375613766137761378613796138061381613826138361384613856138661387613886138961390613916139261393613946139561396613976139861399614006140161402614036140461405614066140761408614096141061411614126141361414614156141661417614186141961420614216142261423614246142561426614276142861429614306143161432614336143461435614366143761438614396144061441614426144361444614456144661447614486144961450614516145261453614546145561456614576145861459614606146161462614636146461465614666146761468614696147061471614726147361474614756147661477614786147961480614816148261483614846148561486614876148861489614906149161492614936149461495614966149761498614996150061501615026150361504615056150661507615086150961510615116151261513615146151561516615176151861519615206152161522615236152461525615266152761528615296153061531615326153361534615356153661537615386153961540615416154261543615446154561546615476154861549615506155161552615536155461555615566155761558615596156061561615626156361564615656156661567615686156961570615716157261573615746157561576615776157861579615806158161582615836158461585615866158761588615896159061591615926159361594615956159661597615986159961600616016160261603616046160561606616076160861609616106161161612616136161461615616166161761618616196162061621616226162361624616256162661627616286162961630616316163261633616346163561636616376163861639616406164161642616436164461645616466164761648616496165061651616526165361654616556165661657616586165961660616616166261663616646166561666616676166861669616706167161672616736167461675616766167761678616796168061681616826168361684616856168661687616886168961690616916169261693616946169561696616976169861699617006170161702617036170461705617066170761708617096171061711617126171361714617156171661717617186171961720617216172261723617246172561726617276172861729617306173161732617336173461735617366173761738617396174061741617426174361744617456174661747617486174961750617516175261753617546175561756617576175861759617606176161762617636176461765617666176761768617696177061771617726177361774617756177661777617786177961780617816178261783617846178561786617876178861789617906179161792617936179461795617966179761798617996180061801618026180361804618056180661807618086180961810618116181261813618146181561816618176181861819618206182161822618236182461825618266182761828618296183061831618326183361834618356183661837618386183961840618416184261843618446184561846618476184861849618506185161852618536185461855618566185761858618596186061861618626186361864618656186661867618686186961870618716187261873618746187561876618776187861879618806188161882618836188461885618866188761888618896189061891618926189361894618956189661897618986189961900619016190261903619046190561906619076190861909619106191161912619136191461915619166191761918619196192061921619226192361924619256192661927619286192961930619316193261933619346193561936619376193861939619406194161942619436194461945619466194761948619496195061951619526195361954619556195661957619586195961960619616196261963619646196561966619676196861969619706197161972619736197461975619766197761978619796198061981619826198361984619856198661987619886198961990619916199261993619946199561996619976199861999620006200162002620036200462005620066200762008620096201062011620126201362014620156201662017620186201962020620216202262023620246202562026620276202862029620306203162032620336203462035620366203762038620396204062041620426204362044620456204662047620486204962050620516205262053620546205562056620576205862059620606206162062620636206462065620666206762068620696207062071620726207362074620756207662077620786207962080620816208262083620846208562086620876208862089620906209162092620936209462095620966209762098620996210062101621026210362104621056210662107621086210962110621116211262113621146211562116621176211862119621206212162122621236212462125621266212762128621296213062131621326213362134621356213662137621386213962140621416214262143621446214562146621476214862149621506215162152621536215462155621566215762158621596216062161621626216362164621656216662167621686216962170621716217262173621746217562176621776217862179621806218162182621836218462185621866218762188621896219062191621926219362194621956219662197621986219962200622016220262203622046220562206622076220862209622106221162212622136221462215622166221762218622196222062221622226222362224622256222662227622286222962230622316223262233622346223562236622376223862239622406224162242622436224462245622466224762248622496225062251622526225362254622556225662257622586225962260622616226262263622646226562266622676226862269622706227162272622736227462275622766227762278622796228062281622826228362284622856228662287622886228962290622916229262293622946229562296622976229862299623006230162302623036230462305623066230762308623096231062311623126231362314623156231662317623186231962320623216232262323623246232562326623276232862329623306233162332623336233462335623366233762338623396234062341623426234362344623456234662347623486234962350623516235262353623546235562356623576235862359623606236162362623636236462365623666236762368623696237062371623726237362374623756237662377623786237962380623816238262383623846238562386623876238862389623906239162392623936239462395623966239762398623996240062401624026240362404624056240662407624086240962410624116241262413624146241562416624176241862419624206242162422624236242462425624266242762428624296243062431624326243362434624356243662437624386243962440624416244262443624446244562446624476244862449624506245162452624536245462455624566245762458624596246062461624626246362464624656246662467624686246962470624716247262473624746247562476624776247862479624806248162482624836248462485624866248762488624896249062491624926249362494624956249662497624986249962500625016250262503625046250562506625076250862509625106251162512625136251462515625166251762518625196252062521625226252362524625256252662527625286252962530625316253262533625346253562536625376253862539625406254162542625436254462545625466254762548625496255062551625526255362554625556255662557625586255962560625616256262563625646256562566625676256862569625706257162572625736257462575625766257762578625796258062581625826258362584625856258662587625886258962590625916259262593625946259562596625976259862599626006260162602626036260462605626066260762608626096261062611626126261362614626156261662617626186261962620626216262262623626246262562626626276262862629626306263162632626336263462635626366263762638626396264062641626426264362644626456264662647626486264962650626516265262653626546265562656626576265862659626606266162662626636266462665626666266762668626696267062671626726267362674626756267662677626786267962680626816268262683626846268562686626876268862689626906269162692626936269462695626966269762698626996270062701627026270362704627056270662707627086270962710627116271262713627146271562716627176271862719627206272162722627236272462725627266272762728627296273062731627326273362734627356273662737627386273962740627416274262743627446274562746627476274862749627506275162752627536275462755627566275762758627596276062761627626276362764627656276662767627686276962770627716277262773627746277562776627776277862779627806278162782627836278462785627866278762788627896279062791627926279362794627956279662797627986279962800628016280262803628046280562806628076280862809628106281162812628136281462815628166281762818628196282062821628226282362824628256282662827628286282962830628316283262833628346283562836628376283862839628406284162842628436284462845628466284762848628496285062851628526285362854628556285662857628586285962860628616286262863628646286562866628676286862869628706287162872628736287462875628766287762878628796288062881628826288362884628856288662887628886288962890628916289262893628946289562896628976289862899629006290162902629036290462905629066290762908629096291062911629126291362914629156291662917629186291962920629216292262923629246292562926629276292862929629306293162932629336293462935629366293762938629396294062941629426294362944629456294662947629486294962950629516295262953629546295562956629576295862959629606296162962629636296462965629666296762968629696297062971629726297362974629756297662977629786297962980629816298262983629846298562986629876298862989629906299162992629936299462995629966299762998629996300063001630026300363004630056300663007630086300963010630116301263013630146301563016630176301863019630206302163022630236302463025630266302763028630296303063031630326303363034630356303663037630386303963040630416304263043630446304563046630476304863049630506305163052630536305463055630566305763058630596306063061630626306363064630656306663067630686306963070630716307263073630746307563076630776307863079630806308163082630836308463085630866308763088630896309063091630926309363094630956309663097630986309963100631016310263103631046310563106631076310863109631106311163112631136311463115631166311763118631196312063121631226312363124631256312663127631286312963130631316313263133631346313563136631376313863139631406314163142631436314463145631466314763148631496315063151631526315363154631556315663157631586315963160631616316263163631646316563166631676316863169631706317163172631736317463175631766317763178631796318063181631826318363184631856318663187631886318963190631916319263193631946319563196631976319863199632006320163202632036320463205632066320763208632096321063211632126321363214632156321663217632186321963220632216322263223632246322563226632276322863229632306323163232632336323463235632366323763238632396324063241632426324363244632456324663247632486324963250632516325263253632546325563256632576325863259632606326163262632636326463265632666326763268632696327063271632726327363274632756327663277632786327963280632816328263283632846328563286632876328863289632906329163292632936329463295632966329763298632996330063301633026330363304633056330663307633086330963310633116331263313633146331563316633176331863319633206332163322633236332463325633266332763328633296333063331633326333363334633356333663337633386333963340633416334263343633446334563346633476334863349633506335163352633536335463355633566335763358633596336063361633626336363364633656336663367633686336963370633716337263373633746337563376633776337863379633806338163382633836338463385633866338763388633896339063391633926339363394633956339663397633986339963400634016340263403634046340563406634076340863409634106341163412634136341463415634166341763418634196342063421634226342363424634256342663427634286342963430634316343263433634346343563436634376343863439634406344163442634436344463445634466344763448634496345063451634526345363454634556345663457634586345963460634616346263463634646346563466634676346863469634706347163472634736347463475634766347763478634796348063481634826348363484634856348663487634886348963490634916349263493634946349563496634976349863499635006350163502635036350463505635066350763508635096351063511635126351363514635156351663517635186351963520635216352263523635246352563526635276352863529635306353163532635336353463535635366353763538635396354063541635426354363544635456354663547635486354963550635516355263553635546355563556635576355863559635606356163562635636356463565635666356763568635696357063571635726357363574635756357663577635786357963580635816358263583635846358563586635876358863589635906359163592635936359463595635966359763598635996360063601636026360363604636056360663607636086360963610636116361263613636146361563616636176361863619636206362163622636236362463625636266362763628636296363063631636326363363634636356363663637636386363963640636416364263643636446364563646636476364863649636506365163652636536365463655636566365763658636596366063661636626366363664636656366663667636686366963670636716367263673636746367563676636776367863679636806368163682636836368463685636866368763688636896369063691636926369363694636956369663697636986369963700637016370263703637046370563706637076370863709637106371163712637136371463715637166371763718637196372063721637226372363724637256372663727637286372963730637316373263733637346373563736637376373863739637406374163742637436374463745637466374763748637496375063751637526375363754637556375663757637586375963760637616376263763637646376563766637676376863769637706377163772637736377463775637766377763778637796378063781637826378363784637856378663787637886378963790637916379263793637946379563796637976379863799638006380163802638036380463805638066380763808638096381063811638126381363814638156381663817638186381963820638216382263823638246382563826638276382863829638306383163832638336383463835638366383763838638396384063841638426384363844638456384663847638486384963850638516385263853638546385563856638576385863859638606386163862638636386463865638666386763868638696387063871638726387363874638756387663877638786387963880638816388263883638846388563886638876388863889638906389163892638936389463895638966389763898638996390063901639026390363904639056390663907639086390963910639116391263913639146391563916639176391863919639206392163922639236392463925639266392763928639296393063931639326393363934639356393663937639386393963940639416394263943639446394563946639476394863949639506395163952639536395463955639566395763958639596396063961639626396363964639656396663967639686396963970639716397263973639746397563976639776397863979639806398163982639836398463985639866398763988639896399063991639926399363994639956399663997639986399964000640016400264003640046400564006640076400864009640106401164012640136401464015640166401764018640196402064021640226402364024640256402664027640286402964030640316403264033640346403564036640376403864039640406404164042640436404464045640466404764048640496405064051640526405364054640556405664057640586405964060640616406264063640646406564066640676406864069640706407164072640736407464075640766407764078640796408064081640826408364084640856408664087640886408964090640916409264093640946409564096640976409864099641006410164102641036410464105641066410764108641096411064111641126411364114641156411664117641186411964120641216412264123641246412564126641276412864129641306413164132641336413464135641366413764138641396414064141641426414364144641456414664147641486414964150641516415264153641546415564156641576415864159641606416164162641636416464165641666416764168641696417064171641726417364174641756417664177641786417964180641816418264183641846418564186641876418864189641906419164192641936419464195641966419764198641996420064201642026420364204642056420664207642086420964210642116421264213642146421564216642176421864219642206422164222642236422464225642266422764228642296423064231642326423364234642356423664237642386423964240642416424264243642446424564246642476424864249642506425164252642536425464255642566425764258642596426064261642626426364264642656426664267642686426964270642716427264273642746427564276642776427864279642806428164282642836428464285642866428764288642896429064291642926429364294642956429664297642986429964300643016430264303643046430564306643076430864309643106431164312643136431464315643166431764318643196432064321643226432364324643256432664327643286432964330643316433264333643346433564336643376433864339643406434164342643436434464345643466434764348643496435064351643526435364354643556435664357643586435964360643616436264363643646436564366643676436864369643706437164372643736437464375643766437764378643796438064381643826438364384643856438664387643886438964390643916439264393643946439564396643976439864399644006440164402644036440464405644066440764408644096441064411644126441364414644156441664417644186441964420644216442264423644246442564426644276442864429644306443164432644336443464435644366443764438644396444064441644426444364444644456444664447644486444964450644516445264453644546445564456644576445864459644606446164462644636446464465644666446764468644696447064471644726447364474644756447664477644786447964480644816448264483644846448564486644876448864489644906449164492644936449464495644966449764498644996450064501645026450364504645056450664507645086450964510645116451264513645146451564516645176451864519645206452164522645236452464525645266452764528645296453064531645326453364534645356453664537645386453964540645416454264543645446454564546645476454864549645506455164552645536455464555645566455764558645596456064561645626456364564645656456664567645686456964570645716457264573645746457564576645776457864579645806458164582645836458464585645866458764588645896459064591645926459364594645956459664597645986459964600646016460264603646046460564606646076460864609646106461164612646136461464615646166461764618646196462064621646226462364624646256462664627646286462964630646316463264633646346463564636646376463864639646406464164642646436464464645646466464764648646496465064651646526465364654646556465664657646586465964660646616466264663646646466564666646676466864669646706467164672646736467464675646766467764678646796468064681646826468364684646856468664687646886468964690646916469264693646946469564696646976469864699647006470164702647036470464705647066470764708647096471064711647126471364714647156471664717647186471964720647216472264723647246472564726647276472864729647306473164732647336473464735647366473764738647396474064741647426474364744647456474664747647486474964750647516475264753647546475564756647576475864759647606476164762647636476464765647666476764768647696477064771647726477364774647756477664777647786477964780647816478264783647846478564786647876478864789647906479164792647936479464795647966479764798647996480064801648026480364804648056480664807648086480964810648116481264813648146481564816648176481864819648206482164822648236482464825648266482764828648296483064831648326483364834648356483664837648386483964840648416484264843648446484564846648476484864849648506485164852648536485464855648566485764858648596486064861648626486364864648656486664867648686486964870648716487264873648746487564876648776487864879648806488164882648836488464885648866488764888648896489064891648926489364894648956489664897648986489964900649016490264903649046490564906649076490864909649106491164912649136491464915649166491764918649196492064921649226492364924649256492664927649286492964930649316493264933649346493564936649376493864939649406494164942649436494464945649466494764948649496495064951649526495364954649556495664957649586495964960649616496264963649646496564966649676496864969649706497164972649736497464975649766497764978649796498064981649826498364984649856498664987649886498964990649916499264993649946499564996649976499864999650006500165002650036500465005650066500765008650096501065011650126501365014650156501665017650186501965020650216502265023650246502565026650276502865029650306503165032650336503465035650366503765038650396504065041650426504365044650456504665047650486504965050650516505265053650546505565056650576505865059650606506165062650636506465065650666506765068650696507065071650726507365074650756507665077650786507965080650816508265083650846508565086650876508865089650906509165092650936509465095650966509765098650996510065101651026510365104651056510665107651086510965110651116511265113651146511565116651176511865119651206512165122651236512465125651266512765128651296513065131651326513365134651356513665137651386513965140651416514265143651446514565146651476514865149651506515165152651536515465155651566515765158651596516065161651626516365164651656516665167651686516965170651716517265173651746517565176651776517865179651806518165182651836518465185651866518765188651896519065191651926519365194651956519665197651986519965200652016520265203652046520565206652076520865209652106521165212652136521465215652166521765218652196522065221652226522365224652256522665227652286522965230652316523265233652346523565236652376523865239652406524165242652436524465245652466524765248652496525065251652526525365254652556525665257652586525965260652616526265263652646526565266652676526865269652706527165272652736527465275652766527765278652796528065281652826528365284652856528665287652886528965290652916529265293652946529565296652976529865299653006530165302653036530465305653066530765308653096531065311653126531365314653156531665317653186531965320653216532265323653246532565326653276532865329653306533165332653336533465335653366533765338653396534065341653426534365344653456534665347653486534965350653516535265353653546535565356653576535865359653606536165362653636536465365653666536765368653696537065371653726537365374653756537665377653786537965380653816538265383653846538565386653876538865389653906539165392653936539465395653966539765398653996540065401654026540365404654056540665407654086540965410654116541265413654146541565416654176541865419654206542165422654236542465425654266542765428654296543065431654326543365434654356543665437654386543965440654416544265443654446544565446654476544865449654506545165452654536545465455654566545765458654596546065461654626546365464654656546665467654686546965470654716547265473654746547565476654776547865479654806548165482654836548465485654866548765488654896549065491654926549365494654956549665497654986549965500655016550265503655046550565506655076550865509655106551165512655136551465515655166551765518655196552065521655226552365524655256552665527655286552965530655316553265533655346553565536655376553865539655406554165542655436554465545655466554765548655496555065551655526555365554655556555665557655586555965560655616556265563655646556565566655676556865569655706557165572655736557465575655766557765578655796558065581655826558365584655856558665587655886558965590655916559265593655946559565596655976559865599656006560165602656036560465605656066560765608656096561065611656126561365614656156561665617656186561965620656216562265623656246562565626656276562865629656306563165632656336563465635656366563765638656396564065641656426564365644656456564665647656486564965650656516565265653656546565565656656576565865659656606566165662656636566465665656666566765668656696567065671656726567365674656756567665677656786567965680656816568265683656846568565686656876568865689656906569165692656936569465695656966569765698656996570065701657026570365704657056570665707657086570965710657116571265713657146571565716657176571865719657206572165722657236572465725657266572765728657296573065731657326573365734657356573665737657386573965740657416574265743657446574565746657476574865749657506575165752657536575465755657566575765758657596576065761657626576365764657656576665767657686576965770657716577265773657746577565776657776577865779657806578165782657836578465785657866578765788657896579065791657926579365794657956579665797657986579965800658016580265803658046580565806658076580865809658106581165812658136581465815658166581765818658196582065821658226582365824658256582665827658286582965830658316583265833658346583565836658376583865839658406584165842658436584465845658466584765848658496585065851658526585365854658556585665857658586585965860658616586265863658646586565866658676586865869658706587165872658736587465875658766587765878658796588065881658826588365884658856588665887658886588965890658916589265893658946589565896658976589865899659006590165902659036590465905659066590765908659096591065911659126591365914659156591665917659186591965920659216592265923659246592565926659276592865929659306593165932659336593465935659366593765938659396594065941659426594365944659456594665947659486594965950659516595265953659546595565956659576595865959659606596165962659636596465965659666596765968659696597065971659726597365974659756597665977659786597965980659816598265983659846598565986659876598865989659906599165992659936599465995659966599765998659996600066001660026600366004660056600666007660086600966010660116601266013660146601566016660176601866019660206602166022660236602466025660266602766028660296603066031660326603366034660356603666037660386603966040660416604266043660446604566046660476604866049660506605166052660536605466055660566605766058660596606066061660626606366064660656606666067660686606966070660716607266073660746607566076660776607866079660806608166082660836608466085660866608766088660896609066091660926609366094660956609666097660986609966100661016610266103661046610566106661076610866109661106611166112661136611466115661166611766118661196612066121661226612366124661256612666127661286612966130661316613266133661346613566136661376613866139661406614166142661436614466145661466614766148661496615066151661526615366154661556615666157661586615966160661616616266163661646616566166661676616866169661706617166172661736617466175661766617766178661796618066181661826618366184661856618666187661886618966190661916619266193661946619566196661976619866199662006620166202662036620466205662066620766208662096621066211662126621366214662156621666217662186621966220662216622266223662246622566226662276622866229662306623166232662336623466235662366623766238662396624066241662426624366244662456624666247662486624966250662516625266253662546625566256662576625866259662606626166262662636626466265662666626766268662696627066271662726627366274662756627666277662786627966280662816628266283662846628566286662876628866289662906629166292662936629466295662966629766298662996630066301663026630366304663056630666307663086630966310663116631266313663146631566316663176631866319663206632166322663236632466325663266632766328663296633066331663326633366334663356633666337663386633966340663416634266343663446634566346663476634866349663506635166352663536635466355663566635766358663596636066361663626636366364663656636666367663686636966370663716637266373663746637566376663776637866379663806638166382663836638466385663866638766388663896639066391663926639366394663956639666397663986639966400664016640266403664046640566406664076640866409664106641166412664136641466415664166641766418664196642066421664226642366424664256642666427664286642966430664316643266433664346643566436664376643866439664406644166442664436644466445664466644766448664496645066451664526645366454664556645666457664586645966460664616646266463664646646566466664676646866469664706647166472664736647466475664766647766478664796648066481664826648366484664856648666487664886648966490664916649266493664946649566496664976649866499665006650166502665036650466505665066650766508665096651066511665126651366514665156651666517665186651966520665216652266523665246652566526665276652866529665306653166532665336653466535665366653766538665396654066541665426654366544665456654666547665486654966550665516655266553665546655566556665576655866559665606656166562665636656466565665666656766568665696657066571665726657366574665756657666577665786657966580665816658266583665846658566586665876658866589665906659166592665936659466595665966659766598665996660066601666026660366604666056660666607666086660966610666116661266613666146661566616666176661866619666206662166622666236662466625666266662766628666296663066631666326663366634666356663666637666386663966640666416664266643666446664566646666476664866649666506665166652666536665466655666566665766658666596666066661666626666366664666656666666667666686666966670666716667266673666746667566676666776667866679666806668166682666836668466685666866668766688666896669066691666926669366694666956669666697666986669966700667016670266703667046670566706667076670866709667106671166712667136671466715667166671766718667196672066721667226672366724667256672666727667286672966730667316673266733667346673566736667376673866739667406674166742667436674466745667466674766748667496675066751667526675366754667556675666757667586675966760667616676266763667646676566766667676676866769667706677166772667736677466775667766677766778667796678066781667826678366784667856678666787667886678966790667916679266793667946679566796667976679866799668006680166802668036680466805668066680766808668096681066811668126681366814668156681666817668186681966820668216682266823668246682566826668276682866829668306683166832668336683466835668366683766838668396684066841668426684366844668456684666847668486684966850668516685266853668546685566856668576685866859668606686166862668636686466865668666686766868668696687066871668726687366874668756687666877668786687966880668816688266883668846688566886668876688866889668906689166892668936689466895668966689766898668996690066901669026690366904669056690666907669086690966910669116691266913669146691566916669176691866919669206692166922669236692466925669266692766928669296693066931669326693366934669356693666937669386693966940669416694266943669446694566946669476694866949669506695166952669536695466955669566695766958669596696066961669626696366964669656696666967669686696966970669716697266973669746697566976669776697866979669806698166982669836698466985669866698766988669896699066991669926699366994669956699666997669986699967000670016700267003670046700567006670076700867009670106701167012670136701467015670166701767018670196702067021670226702367024670256702667027670286702967030670316703267033670346703567036670376703867039670406704167042670436704467045670466704767048670496705067051670526705367054670556705667057670586705967060670616706267063670646706567066670676706867069670706707167072670736707467075670766707767078670796708067081670826708367084670856708667087670886708967090670916709267093670946709567096670976709867099671006710167102671036710467105671066710767108671096711067111671126711367114671156711667117671186711967120671216712267123671246712567126671276712867129671306713167132671336713467135671366713767138671396714067141671426714367144671456714667147671486714967150671516715267153671546715567156671576715867159671606716167162671636716467165671666716767168671696717067171671726717367174671756717667177671786717967180671816718267183671846718567186671876718867189671906719167192671936719467195671966719767198671996720067201672026720367204672056720667207672086720967210672116721267213672146721567216672176721867219672206722167222672236722467225672266722767228672296723067231672326723367234672356723667237672386723967240672416724267243672446724567246672476724867249672506725167252672536725467255672566725767258672596726067261672626726367264672656726667267672686726967270672716727267273672746727567276672776727867279672806728167282672836728467285672866728767288672896729067291672926729367294672956729667297672986729967300673016730267303673046730567306673076730867309673106731167312673136731467315673166731767318673196732067321673226732367324673256732667327673286732967330673316733267333673346733567336673376733867339673406734167342673436734467345673466734767348673496735067351673526735367354673556735667357673586735967360673616736267363673646736567366673676736867369673706737167372673736737467375673766737767378673796738067381673826738367384673856738667387673886738967390673916739267393673946739567396673976739867399674006740167402674036740467405674066740767408674096741067411674126741367414674156741667417674186741967420674216742267423674246742567426674276742867429674306743167432674336743467435674366743767438674396744067441674426744367444674456744667447674486744967450674516745267453674546745567456674576745867459674606746167462674636746467465674666746767468674696747067471674726747367474674756747667477674786747967480674816748267483674846748567486674876748867489674906749167492674936749467495674966749767498674996750067501675026750367504675056750667507675086750967510675116751267513675146751567516675176751867519675206752167522675236752467525675266752767528675296753067531675326753367534675356753667537675386753967540675416754267543675446754567546675476754867549675506755167552675536755467555675566755767558675596756067561675626756367564675656756667567675686756967570675716757267573675746757567576675776757867579675806758167582675836758467585675866758767588675896759067591675926759367594675956759667597675986759967600676016760267603676046760567606676076760867609676106761167612676136761467615676166761767618676196762067621676226762367624676256762667627676286762967630676316763267633676346763567636676376763867639676406764167642676436764467645676466764767648676496765067651676526765367654676556765667657676586765967660676616766267663676646766567666676676766867669676706767167672676736767467675676766767767678676796768067681676826768367684676856768667687676886768967690676916769267693676946769567696676976769867699677006770167702677036770467705677066770767708677096771067711677126771367714677156771667717677186771967720677216772267723677246772567726677276772867729677306773167732677336773467735677366773767738677396774067741677426774367744677456774667747677486774967750677516775267753677546775567756677576775867759677606776167762677636776467765677666776767768677696777067771677726777367774677756777667777677786777967780677816778267783677846778567786677876778867789677906779167792677936779467795677966779767798677996780067801678026780367804678056780667807678086780967810678116781267813678146781567816678176781867819678206782167822678236782467825678266782767828678296783067831678326783367834678356783667837678386783967840678416784267843678446784567846678476784867849678506785167852678536785467855678566785767858678596786067861678626786367864678656786667867678686786967870678716787267873678746787567876678776787867879678806788167882678836788467885678866788767888678896789067891678926789367894678956789667897678986789967900679016790267903679046790567906679076790867909679106791167912679136791467915679166791767918679196792067921679226792367924679256792667927679286792967930679316793267933679346793567936679376793867939679406794167942679436794467945679466794767948679496795067951679526795367954679556795667957679586795967960679616796267963679646796567966679676796867969679706797167972679736797467975679766797767978679796798067981679826798367984679856798667987679886798967990679916799267993679946799567996679976799867999680006800168002680036800468005680066800768008680096801068011680126801368014680156801668017680186801968020680216802268023680246802568026680276802868029680306803168032680336803468035680366803768038680396804068041680426804368044680456804668047680486804968050680516805268053680546805568056680576805868059680606806168062680636806468065680666806768068680696807068071680726807368074680756807668077680786807968080680816808268083680846808568086680876808868089680906809168092680936809468095680966809768098680996810068101681026810368104681056810668107681086810968110681116811268113681146811568116681176811868119681206812168122681236812468125681266812768128681296813068131681326813368134681356813668137681386813968140681416814268143681446814568146681476814868149681506815168152681536815468155681566815768158681596816068161681626816368164681656816668167681686816968170681716817268173681746817568176681776817868179681806818168182681836818468185681866818768188681896819068191681926819368194681956819668197681986819968200682016820268203682046820568206682076820868209682106821168212682136821468215682166821768218682196822068221682226822368224682256822668227682286822968230682316823268233682346823568236682376823868239682406824168242682436824468245682466824768248682496825068251682526825368254682556825668257682586825968260682616826268263682646826568266682676826868269682706827168272682736827468275682766827768278682796828068281682826828368284682856828668287682886828968290682916829268293682946829568296682976829868299683006830168302683036830468305683066830768308683096831068311683126831368314683156831668317683186831968320683216832268323683246832568326683276832868329683306833168332683336833468335683366833768338683396834068341683426834368344683456834668347683486834968350683516835268353683546835568356683576835868359683606836168362683636836468365683666836768368683696837068371683726837368374683756837668377683786837968380683816838268383683846838568386683876838868389683906839168392683936839468395683966839768398683996840068401684026840368404684056840668407684086840968410684116841268413684146841568416684176841868419684206842168422684236842468425684266842768428684296843068431684326843368434684356843668437684386843968440684416844268443684446844568446684476844868449684506845168452684536845468455684566845768458684596846068461684626846368464684656846668467684686846968470684716847268473684746847568476684776847868479684806848168482684836848468485684866848768488684896849068491684926849368494684956849668497684986849968500685016850268503685046850568506685076850868509685106851168512685136851468515685166851768518685196852068521685226852368524685256852668527685286852968530685316853268533685346853568536685376853868539685406854168542685436854468545685466854768548685496855068551685526855368554685556855668557685586855968560685616856268563685646856568566685676856868569685706857168572685736857468575685766857768578685796858068581685826858368584685856858668587685886858968590685916859268593685946859568596685976859868599686006860168602686036860468605686066860768608686096861068611686126861368614686156861668617686186861968620686216862268623686246862568626686276862868629686306863168632686336863468635686366863768638686396864068641686426864368644686456864668647686486864968650686516865268653686546865568656686576865868659686606866168662686636866468665686666866768668686696867068671686726867368674686756867668677686786867968680686816868268683686846868568686686876868868689686906869168692686936869468695686966869768698686996870068701687026870368704687056870668707687086870968710687116871268713687146871568716687176871868719687206872168722687236872468725687266872768728687296873068731687326873368734687356873668737687386873968740687416874268743687446874568746687476874868749687506875168752687536875468755687566875768758687596876068761687626876368764687656876668767687686876968770687716877268773687746877568776687776877868779687806878168782687836878468785687866878768788687896879068791687926879368794687956879668797687986879968800688016880268803688046880568806688076880868809688106881168812688136881468815688166881768818688196882068821688226882368824688256882668827688286882968830688316883268833688346883568836688376883868839688406884168842688436884468845688466884768848688496885068851688526885368854688556885668857688586885968860688616886268863688646886568866688676886868869688706887168872688736887468875688766887768878688796888068881688826888368884688856888668887688886888968890688916889268893688946889568896688976889868899689006890168902689036890468905689066890768908689096891068911689126891368914689156891668917689186891968920689216892268923689246892568926689276892868929689306893168932689336893468935689366893768938689396894068941689426894368944689456894668947689486894968950689516895268953689546895568956689576895868959689606896168962689636896468965689666896768968689696897068971689726897368974689756897668977689786897968980689816898268983689846898568986689876898868989689906899168992689936899468995689966899768998689996900069001690026900369004690056900669007690086900969010690116901269013690146901569016690176901869019690206902169022690236902469025690266902769028690296903069031690326903369034690356903669037690386903969040690416904269043690446904569046690476904869049690506905169052690536905469055690566905769058690596906069061690626906369064690656906669067690686906969070690716907269073690746907569076690776907869079690806908169082690836908469085690866908769088690896909069091690926909369094690956909669097690986909969100691016910269103691046910569106691076910869109691106911169112691136911469115691166911769118691196912069121691226912369124691256912669127691286912969130691316913269133691346913569136691376913869139691406914169142691436914469145691466914769148691496915069151691526915369154691556915669157691586915969160691616916269163691646916569166691676916869169691706917169172691736917469175691766917769178691796918069181691826918369184691856918669187691886918969190691916919269193691946919569196691976919869199692006920169202692036920469205692066920769208692096921069211692126921369214692156921669217692186921969220692216922269223692246922569226692276922869229692306923169232692336923469235692366923769238692396924069241692426924369244692456924669247692486924969250692516925269253692546925569256692576925869259692606926169262692636926469265692666926769268692696927069271692726927369274692756927669277692786927969280692816928269283692846928569286692876928869289692906929169292692936929469295692966929769298692996930069301693026930369304693056930669307693086930969310693116931269313693146931569316693176931869319693206932169322693236932469325693266932769328693296933069331693326933369334693356933669337693386933969340693416934269343693446934569346693476934869349693506935169352693536935469355693566935769358693596936069361693626936369364693656936669367693686936969370693716937269373693746937569376693776937869379693806938169382693836938469385693866938769388693896939069391693926939369394693956939669397693986939969400694016940269403694046940569406694076940869409694106941169412694136941469415694166941769418694196942069421694226942369424694256942669427694286942969430694316943269433694346943569436694376943869439694406944169442694436944469445694466944769448694496945069451694526945369454694556945669457694586945969460694616946269463694646946569466694676946869469694706947169472694736947469475694766947769478694796948069481694826948369484694856948669487694886948969490694916949269493694946949569496694976949869499695006950169502695036950469505695066950769508695096951069511695126951369514695156951669517695186951969520695216952269523695246952569526695276952869529695306953169532695336953469535695366953769538695396954069541695426954369544695456954669547695486954969550695516955269553695546955569556695576955869559695606956169562695636956469565695666956769568695696957069571695726957369574695756957669577695786957969580695816958269583695846958569586695876958869589695906959169592695936959469595695966959769598695996960069601696026960369604696056960669607696086960969610696116961269613696146961569616696176961869619696206962169622696236962469625696266962769628696296963069631696326963369634696356963669637696386963969640696416964269643696446964569646696476964869649696506965169652696536965469655696566965769658696596966069661696626966369664696656966669667696686966969670696716967269673696746967569676696776967869679696806968169682696836968469685696866968769688696896969069691696926969369694696956969669697696986969969700697016970269703697046970569706697076970869709697106971169712697136971469715697166971769718697196972069721697226972369724697256972669727697286972969730697316973269733697346973569736697376973869739697406974169742697436974469745697466974769748697496975069751697526975369754697556975669757697586975969760697616976269763697646976569766697676976869769697706977169772697736977469775697766977769778697796978069781697826978369784697856978669787697886978969790697916979269793697946979569796697976979869799698006980169802698036980469805698066980769808698096981069811698126981369814698156981669817698186981969820698216982269823698246982569826698276982869829698306983169832698336983469835698366983769838698396984069841698426984369844698456984669847698486984969850698516985269853698546985569856698576985869859698606986169862698636986469865698666986769868698696987069871698726987369874698756987669877698786987969880698816988269883698846988569886698876988869889698906989169892698936989469895698966989769898698996990069901699026990369904699056990669907699086990969910699116991269913699146991569916699176991869919699206992169922699236992469925699266992769928699296993069931699326993369934699356993669937699386993969940699416994269943699446994569946699476994869949699506995169952699536995469955699566995769958699596996069961699626996369964699656996669967699686996969970699716997269973699746997569976699776997869979699806998169982699836998469985699866998769988699896999069991699926999369994699956999669997699986999970000700017000270003700047000570006700077000870009700107001170012700137001470015700167001770018700197002070021700227002370024700257002670027700287002970030700317003270033700347003570036700377003870039700407004170042700437004470045700467004770048700497005070051700527005370054700557005670057700587005970060700617006270063700647006570066700677006870069700707007170072700737007470075700767007770078700797008070081700827008370084700857008670087700887008970090700917009270093700947009570096700977009870099701007010170102701037010470105701067010770108701097011070111701127011370114701157011670117701187011970120701217012270123701247012570126701277012870129701307013170132701337013470135701367013770138701397014070141701427014370144701457014670147701487014970150701517015270153701547015570156701577015870159701607016170162701637016470165701667016770168701697017070171701727017370174701757017670177701787017970180701817018270183701847018570186701877018870189701907019170192701937019470195701967019770198701997020070201702027020370204702057020670207702087020970210702117021270213702147021570216702177021870219702207022170222702237022470225702267022770228702297023070231702327023370234702357023670237702387023970240702417024270243702447024570246702477024870249702507025170252702537025470255702567025770258702597026070261702627026370264702657026670267702687026970270702717027270273702747027570276702777027870279702807028170282702837028470285702867028770288702897029070291702927029370294702957029670297702987029970300703017030270303703047030570306703077030870309703107031170312703137031470315703167031770318703197032070321703227032370324703257032670327703287032970330703317033270333703347033570336703377033870339703407034170342703437034470345703467034770348703497035070351703527035370354703557035670357703587035970360703617036270363703647036570366703677036870369703707037170372703737037470375703767037770378703797038070381703827038370384703857038670387703887038970390703917039270393703947039570396703977039870399704007040170402704037040470405704067040770408704097041070411704127041370414704157041670417704187041970420704217042270423704247042570426704277042870429704307043170432704337043470435704367043770438704397044070441704427044370444704457044670447704487044970450704517045270453704547045570456704577045870459704607046170462704637046470465704667046770468704697047070471704727047370474704757047670477704787047970480704817048270483704847048570486704877048870489704907049170492704937049470495704967049770498704997050070501705027050370504705057050670507705087050970510705117051270513705147051570516705177051870519705207052170522705237052470525705267052770528705297053070531705327053370534705357053670537705387053970540705417054270543705447054570546705477054870549705507055170552705537055470555705567055770558705597056070561705627056370564705657056670567705687056970570705717057270573705747057570576705777057870579705807058170582705837058470585705867058770588705897059070591705927059370594705957059670597705987059970600706017060270603706047060570606706077060870609706107061170612706137061470615706167061770618706197062070621706227062370624706257062670627706287062970630706317063270633706347063570636706377063870639706407064170642706437064470645706467064770648706497065070651706527065370654706557065670657706587065970660706617066270663706647066570666706677066870669706707067170672706737067470675706767067770678706797068070681706827068370684706857068670687706887068970690706917069270693706947069570696706977069870699707007070170702707037070470705707067070770708707097071070711707127071370714707157071670717707187071970720707217072270723707247072570726707277072870729707307073170732707337073470735707367073770738707397074070741707427074370744707457074670747707487074970750707517075270753707547075570756707577075870759707607076170762707637076470765707667076770768707697077070771707727077370774707757077670777707787077970780707817078270783707847078570786707877078870789707907079170792707937079470795707967079770798707997080070801708027080370804708057080670807708087080970810708117081270813708147081570816708177081870819708207082170822708237082470825708267082770828708297083070831708327083370834708357083670837708387083970840708417084270843708447084570846708477084870849708507085170852708537085470855708567085770858708597086070861708627086370864708657086670867708687086970870708717087270873708747087570876708777087870879708807088170882708837088470885708867088770888708897089070891708927089370894708957089670897708987089970900709017090270903709047090570906709077090870909709107091170912709137091470915709167091770918709197092070921709227092370924709257092670927709287092970930709317093270933709347093570936709377093870939709407094170942709437094470945709467094770948709497095070951709527095370954709557095670957709587095970960709617096270963709647096570966709677096870969709707097170972709737097470975709767097770978709797098070981709827098370984709857098670987709887098970990709917099270993709947099570996709977099870999710007100171002710037100471005710067100771008710097101071011710127101371014710157101671017710187101971020710217102271023710247102571026710277102871029710307103171032710337103471035710367103771038710397104071041710427104371044710457104671047710487104971050710517105271053710547105571056710577105871059710607106171062710637106471065710667106771068710697107071071710727107371074710757107671077710787107971080710817108271083710847108571086710877108871089710907109171092710937109471095710967109771098710997110071101711027110371104711057110671107711087110971110711117111271113711147111571116711177111871119711207112171122711237112471125711267112771128711297113071131711327113371134711357113671137711387113971140711417114271143711447114571146711477114871149711507115171152711537115471155711567115771158711597116071161711627116371164711657116671167711687116971170711717117271173711747117571176711777117871179711807118171182711837118471185711867118771188711897119071191711927119371194711957119671197711987119971200712017120271203712047120571206712077120871209712107121171212712137121471215712167121771218712197122071221712227122371224712257122671227712287122971230712317123271233712347123571236712377123871239712407124171242712437124471245712467124771248712497125071251712527125371254712557125671257712587125971260712617126271263712647126571266712677126871269712707127171272712737127471275712767127771278712797128071281712827128371284712857128671287712887128971290712917129271293712947129571296712977129871299713007130171302713037130471305713067130771308713097131071311713127131371314713157131671317713187131971320713217132271323713247132571326713277132871329713307133171332713337133471335713367133771338713397134071341713427134371344713457134671347713487134971350713517135271353713547135571356713577135871359713607136171362713637136471365713667136771368713697137071371713727137371374713757137671377713787137971380713817138271383713847138571386713877138871389713907139171392713937139471395713967139771398713997140071401714027140371404714057140671407714087140971410714117141271413714147141571416714177141871419714207142171422714237142471425714267142771428714297143071431714327143371434714357143671437714387143971440714417144271443714447144571446714477144871449714507145171452714537145471455714567145771458714597146071461714627146371464714657146671467714687146971470714717147271473714747147571476714777147871479714807148171482714837148471485714867148771488714897149071491714927149371494714957149671497714987149971500715017150271503715047150571506715077150871509715107151171512715137151471515715167151771518715197152071521715227152371524715257152671527715287152971530715317153271533715347153571536715377153871539715407154171542715437154471545715467154771548715497155071551715527155371554715557155671557715587155971560715617156271563715647156571566715677156871569715707157171572715737157471575715767157771578715797158071581715827158371584715857158671587715887158971590715917159271593715947159571596715977159871599716007160171602716037160471605716067160771608716097161071611716127161371614716157161671617716187161971620716217162271623716247162571626716277162871629716307163171632716337163471635716367163771638716397164071641716427164371644716457164671647716487164971650716517165271653716547165571656716577165871659716607166171662716637166471665716667166771668716697167071671716727167371674716757167671677716787167971680716817168271683716847168571686716877168871689716907169171692716937169471695716967169771698716997170071701717027170371704717057170671707717087170971710717117171271713717147171571716717177171871719717207172171722717237172471725717267172771728717297173071731717327173371734717357173671737717387173971740717417174271743717447174571746717477174871749717507175171752717537175471755717567175771758717597176071761717627176371764717657176671767717687176971770717717177271773717747177571776717777177871779717807178171782717837178471785717867178771788717897179071791717927179371794717957179671797717987179971800718017180271803718047180571806718077180871809718107181171812718137181471815718167181771818718197182071821718227182371824718257182671827718287182971830718317183271833718347183571836718377183871839718407184171842718437184471845718467184771848718497185071851718527185371854718557185671857718587185971860718617186271863718647186571866718677186871869718707187171872718737187471875718767187771878718797188071881718827188371884718857188671887718887188971890718917189271893718947189571896718977189871899719007190171902719037190471905719067190771908719097191071911719127191371914719157191671917719187191971920719217192271923719247192571926719277192871929719307193171932719337193471935719367193771938719397194071941719427194371944719457194671947719487194971950719517195271953719547195571956719577195871959719607196171962719637196471965719667196771968719697197071971719727197371974719757197671977719787197971980719817198271983719847198571986719877198871989719907199171992719937199471995719967199771998719997200072001720027200372004720057200672007720087200972010720117201272013720147201572016720177201872019720207202172022720237202472025720267202772028720297203072031720327203372034720357203672037720387203972040720417204272043720447204572046720477204872049720507205172052720537205472055720567205772058720597206072061720627206372064720657206672067720687206972070720717207272073720747207572076720777207872079720807208172082720837208472085720867208772088720897209072091720927209372094720957209672097720987209972100721017210272103721047210572106721077210872109721107211172112721137211472115721167211772118721197212072121721227212372124721257212672127721287212972130721317213272133721347213572136721377213872139721407214172142721437214472145721467214772148721497215072151721527215372154721557215672157721587215972160721617216272163721647216572166721677216872169721707217172172721737217472175721767217772178721797218072181721827218372184721857218672187721887218972190721917219272193721947219572196721977219872199722007220172202722037220472205722067220772208722097221072211722127221372214722157221672217722187221972220722217222272223722247222572226722277222872229722307223172232722337223472235722367223772238722397224072241722427224372244722457224672247722487224972250722517225272253722547225572256722577225872259722607226172262722637226472265722667226772268722697227072271722727227372274722757227672277722787227972280722817228272283722847228572286722877228872289722907229172292722937229472295722967229772298722997230072301723027230372304723057230672307723087230972310723117231272313723147231572316723177231872319723207232172322723237232472325723267232772328723297233072331723327233372334723357233672337723387233972340723417234272343723447234572346723477234872349723507235172352723537235472355723567235772358723597236072361723627236372364723657236672367723687236972370723717237272373723747237572376723777237872379723807238172382723837238472385723867238772388723897239072391723927239372394723957239672397723987239972400724017240272403724047240572406724077240872409724107241172412724137241472415724167241772418724197242072421724227242372424724257242672427724287242972430724317243272433724347243572436724377243872439724407244172442724437244472445724467244772448724497245072451724527245372454724557245672457724587245972460724617246272463724647246572466724677246872469724707247172472724737247472475724767247772478724797248072481724827248372484724857248672487724887248972490724917249272493724947249572496724977249872499725007250172502725037250472505725067250772508725097251072511725127251372514725157251672517725187251972520725217252272523725247252572526725277252872529725307253172532725337253472535725367253772538725397254072541725427254372544725457254672547725487254972550725517255272553725547255572556725577255872559725607256172562725637256472565725667256772568725697257072571725727257372574725757257672577725787257972580725817258272583725847258572586725877258872589725907259172592725937259472595725967259772598725997260072601726027260372604726057260672607726087260972610726117261272613726147261572616726177261872619726207262172622726237262472625726267262772628726297263072631726327263372634726357263672637726387263972640726417264272643726447264572646726477264872649726507265172652726537265472655726567265772658726597266072661726627266372664726657266672667726687266972670726717267272673726747267572676726777267872679726807268172682726837268472685726867268772688726897269072691726927269372694726957269672697726987269972700727017270272703727047270572706727077270872709727107271172712727137271472715727167271772718727197272072721727227272372724727257272672727727287272972730727317273272733727347273572736727377273872739727407274172742727437274472745727467274772748727497275072751727527275372754727557275672757727587275972760727617276272763727647276572766727677276872769727707277172772727737277472775727767277772778727797278072781727827278372784727857278672787727887278972790727917279272793727947279572796727977279872799728007280172802728037280472805728067280772808728097281072811728127281372814728157281672817728187281972820728217282272823728247282572826728277282872829728307283172832728337283472835728367283772838728397284072841728427284372844728457284672847728487284972850728517285272853728547285572856728577285872859728607286172862728637286472865728667286772868728697287072871728727287372874728757287672877728787287972880728817288272883728847288572886728877288872889728907289172892728937289472895728967289772898728997290072901729027290372904729057290672907729087290972910729117291272913729147291572916729177291872919729207292172922729237292472925729267292772928729297293072931729327293372934729357293672937729387293972940729417294272943729447294572946729477294872949729507295172952729537295472955729567295772958729597296072961729627296372964729657296672967729687296972970729717297272973729747297572976729777297872979729807298172982729837298472985729867298772988729897299072991729927299372994729957299672997729987299973000730017300273003730047300573006730077300873009730107301173012730137301473015730167301773018730197302073021730227302373024730257302673027730287302973030730317303273033730347303573036730377303873039730407304173042730437304473045730467304773048730497305073051730527305373054730557305673057730587305973060730617306273063730647306573066730677306873069730707307173072730737307473075730767307773078730797308073081730827308373084730857308673087730887308973090730917309273093730947309573096730977309873099731007310173102731037310473105731067310773108731097311073111731127311373114731157311673117731187311973120731217312273123731247312573126731277312873129731307313173132731337313473135731367313773138731397314073141731427314373144731457314673147731487314973150731517315273153731547315573156731577315873159731607316173162731637316473165731667316773168731697317073171731727317373174731757317673177731787317973180731817318273183731847318573186731877318873189731907319173192731937319473195731967319773198731997320073201732027320373204732057320673207732087320973210732117321273213732147321573216732177321873219732207322173222732237322473225732267322773228732297323073231732327323373234732357323673237732387323973240732417324273243732447324573246732477324873249732507325173252732537325473255732567325773258732597326073261732627326373264732657326673267732687326973270732717327273273732747327573276732777327873279732807328173282732837328473285732867328773288732897329073291732927329373294732957329673297732987329973300733017330273303733047330573306733077330873309733107331173312733137331473315733167331773318733197332073321733227332373324733257332673327733287332973330733317333273333733347333573336733377333873339733407334173342733437334473345733467334773348733497335073351733527335373354733557335673357733587335973360733617336273363733647336573366733677336873369733707337173372733737337473375733767337773378733797338073381733827338373384733857338673387733887338973390733917339273393733947339573396733977339873399734007340173402734037340473405734067340773408734097341073411734127341373414734157341673417734187341973420734217342273423734247342573426734277342873429734307343173432734337343473435734367343773438734397344073441734427344373444734457344673447734487344973450734517345273453734547345573456734577345873459734607346173462734637346473465734667346773468734697347073471734727347373474734757347673477734787347973480734817348273483734847348573486734877348873489734907349173492734937349473495734967349773498734997350073501735027350373504735057350673507735087350973510735117351273513735147351573516735177351873519735207352173522735237352473525735267352773528735297353073531735327353373534735357353673537735387353973540735417354273543735447354573546735477354873549735507355173552735537355473555735567355773558735597356073561735627356373564735657356673567735687356973570735717357273573735747357573576735777357873579735807358173582735837358473585735867358773588735897359073591735927359373594735957359673597735987359973600736017360273603736047360573606736077360873609736107361173612736137361473615736167361773618736197362073621736227362373624736257362673627736287362973630736317363273633736347363573636736377363873639736407364173642736437364473645736467364773648736497365073651736527365373654736557365673657736587365973660736617366273663736647366573666736677366873669736707367173672736737367473675736767367773678736797368073681736827368373684736857368673687736887368973690736917369273693736947369573696736977369873699737007370173702737037370473705737067370773708737097371073711737127371373714737157371673717737187371973720737217372273723737247372573726737277372873729737307373173732737337373473735737367373773738737397374073741737427374373744737457374673747737487374973750737517375273753737547375573756737577375873759737607376173762737637376473765737667376773768737697377073771737727377373774737757377673777737787377973780737817378273783737847378573786737877378873789737907379173792737937379473795737967379773798737997380073801738027380373804738057380673807738087380973810738117381273813738147381573816738177381873819738207382173822738237382473825738267382773828738297383073831738327383373834738357383673837738387383973840738417384273843738447384573846738477384873849738507385173852738537385473855738567385773858738597386073861738627386373864738657386673867738687386973870738717387273873738747387573876738777387873879738807388173882738837388473885738867388773888738897389073891738927389373894738957389673897738987389973900739017390273903739047390573906739077390873909739107391173912739137391473915739167391773918739197392073921739227392373924739257392673927739287392973930739317393273933739347393573936739377393873939739407394173942739437394473945739467394773948739497395073951739527395373954739557395673957739587395973960739617396273963739647396573966739677396873969739707397173972739737397473975739767397773978739797398073981739827398373984739857398673987739887398973990739917399273993739947399573996739977399873999740007400174002740037400474005740067400774008740097401074011740127401374014740157401674017740187401974020740217402274023740247402574026740277402874029740307403174032740337403474035740367403774038740397404074041740427404374044740457404674047740487404974050740517405274053740547405574056740577405874059740607406174062740637406474065740667406774068740697407074071740727407374074740757407674077740787407974080740817408274083740847408574086740877408874089740907409174092740937409474095740967409774098740997410074101741027410374104741057410674107741087410974110741117411274113741147411574116741177411874119741207412174122741237412474125741267412774128741297413074131741327413374134741357413674137741387413974140741417414274143741447414574146741477414874149741507415174152741537415474155741567415774158741597416074161741627416374164741657416674167741687416974170741717417274173741747417574176741777417874179741807418174182741837418474185741867418774188741897419074191741927419374194741957419674197741987419974200742017420274203742047420574206742077420874209742107421174212742137421474215742167421774218742197422074221742227422374224742257422674227742287422974230742317423274233742347423574236742377423874239742407424174242742437424474245742467424774248742497425074251742527425374254742557425674257742587425974260742617426274263742647426574266742677426874269742707427174272742737427474275742767427774278742797428074281742827428374284742857428674287742887428974290742917429274293742947429574296742977429874299743007430174302743037430474305743067430774308743097431074311743127431374314743157431674317743187431974320743217432274323743247432574326743277432874329743307433174332743337433474335743367433774338743397434074341743427434374344743457434674347
  1. #!/usr/bin/env php
  2. <?php
  3. if (__FILE__ == realpath($GLOBALS['_SERVER']['SCRIPT_NAME'])) {
  4. $phar = realpath($GLOBALS['_SERVER']['SCRIPT_NAME']);
  5. $execute = true;
  6. } else {
  7. $files = get_included_files();
  8. $phar = $files[0];
  9. $execute = false;
  10. }
  11. define('__PHPUNIT_PHAR__', str_replace(DIRECTORY_SEPARATOR, '/', $phar));
  12. define('__PHPUNIT_PHAR_ROOT__', 'phar://phpunit-4.7.0.phar');
  13. Phar::mapPhar('phpunit-4.7.0.phar');
  14. require 'phar://phpunit-4.7.0.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Exception/ExceptionInterface.php';
  15. require 'phar://phpunit-4.7.0.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Exception/InvalidArgumentException.php';
  16. require 'phar://phpunit-4.7.0.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Exception/UnexpectedValueException.php';
  17. require 'phar://phpunit-4.7.0.phar' . '/doctrine-instantiator/Doctrine/Instantiator/InstantiatorInterface.php';
  18. require 'phar://phpunit-4.7.0.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Instantiator.php';
  19. require 'phar://phpunit-4.7.0.phar' . '/php-file-iterator/Iterator.php';
  20. require 'phar://phpunit-4.7.0.phar' . '/php-file-iterator/Facade.php';
  21. require 'phar://phpunit-4.7.0.phar' . '/php-file-iterator/Factory.php';
  22. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage.php';
  23. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Driver.php';
  24. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Driver/HHVM.php';
  25. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Driver/Xdebug.php';
  26. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Exception.php';
  27. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Exception/UnintentionallyCoveredCode.php';
  28. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Filter.php';
  29. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/Clover.php';
  30. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/Crap4j.php';
  31. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/Factory.php';
  32. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/HTML.php';
  33. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/HTML/Renderer.php';
  34. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/Dashboard.php';
  35. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/Directory.php';
  36. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/File.php';
  37. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/Node.php';
  38. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/Node/Directory.php';
  39. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/Node/File.php';
  40. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/Node/Iterator.php';
  41. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/PHP.php';
  42. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/Text.php';
  43. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML.php';
  44. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML/Node.php';
  45. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML/Directory.php';
  46. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML/File.php';
  47. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML/File/Coverage.php';
  48. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML/File/Method.php';
  49. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML/File/Report.php';
  50. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML/File/Unit.php';
  51. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML/Project.php';
  52. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML/Tests.php';
  53. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Report/XML/Totals.php';
  54. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Util.php';
  55. require 'phar://phpunit-4.7.0.phar' . '/php-code-coverage/CodeCoverage/Util/InvalidArgumentHelper.php';
  56. require 'phar://phpunit-4.7.0.phar' . '/php-invoker/Invoker.php';
  57. require 'phar://phpunit-4.7.0.phar' . '/php-invoker/Invoker/TimeoutException.php';
  58. require 'phar://phpunit-4.7.0.phar' . '/php-timer/Timer.php';
  59. require 'phar://phpunit-4.7.0.phar' . '/php-token-stream/Token.php';
  60. require 'phar://phpunit-4.7.0.phar' . '/php-token-stream/Token/Stream.php';
  61. require 'phar://phpunit-4.7.0.phar' . '/php-token-stream/Token/Stream/CachingFactory.php';
  62. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock.php';
  63. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Context.php';
  64. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Description.php';
  65. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Location.php';
  66. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Serializer.php';
  67. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag.php';
  68. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/AuthorTag.php';
  69. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SeeTag.php';
  70. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/CoversTag.php';
  71. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/VersionTag.php';
  72. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTag.php';
  73. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SourceTag.php';
  74. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ExampleTag.php';
  75. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/LinkTag.php';
  76. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ReturnTag.php';
  77. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/MethodTag.php';
  78. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ParamTag.php';
  79. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyTag.php';
  80. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyReadTag.php';
  81. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyWriteTag.php';
  82. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SinceTag.php';
  83. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTag.php';
  84. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/UsesTag.php';
  85. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/VarTag.php';
  86. require 'phar://phpunit-4.7.0.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Type/Collection.php';
  87. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Exception.php';
  88. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/ITester.php';
  89. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/AbstractTester.php';
  90. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/SelfDescribing.php';
  91. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint.php';
  92. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Constraint/DataSetIsEqual.php';
  93. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Constraint/TableIsEqual.php';
  94. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Constraint/TableRowCount.php';
  95. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/IDataSet.php';
  96. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/AbstractDataSet.php';
  97. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/ITable.php';
  98. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/AbstractTable.php';
  99. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/ITableMetaData.php';
  100. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/AbstractTableMetaData.php';
  101. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.php';
  102. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/ArrayDataSet.php';
  103. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/CompositeDataSet.php';
  104. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/CsvDataSet.php';
  105. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/DataSetFilter.php';
  106. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/DefaultDataSet.php';
  107. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/DefaultTable.php';
  108. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/ITableIterator.php';
  109. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/DefaultTableIterator.php';
  110. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/DefaultTableMetaData.php';
  111. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/FlatXmlDataSet.php';
  112. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/IPersistable.php';
  113. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/ISpec.php';
  114. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/IYamlParser.php';
  115. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.php';
  116. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Abstract.php';
  117. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Factory.php';
  118. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/FlatXml.php';
  119. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.php';
  120. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Xml.php';
  121. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Yaml.php';
  122. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/QueryDataSet.php';
  123. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/QueryTable.php';
  124. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/ReplacementDataSet.php';
  125. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/ReplacementTable.php';
  126. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/ReplacementTableIterator.php';
  127. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Csv.php';
  128. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/IDatabaseListConsumer.php';
  129. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Specs/DbQuery.php';
  130. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Specs/DbTable.php';
  131. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Specs/IFactory.php';
  132. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Factory.php';
  133. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Specs/FlatXml.php';
  134. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Xml.php';
  135. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Yaml.php';
  136. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/SymfonyYamlParser.php';
  137. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/TableFilter.php';
  138. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/TableMetaDataFilter.php';
  139. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/XmlDataSet.php';
  140. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DataSet/YamlDataSet.php';
  141. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/DataSet.php';
  142. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/IDatabaseConnection.php';
  143. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php';
  144. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/FilteredDataSet.php';
  145. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/IMetaData.php';
  146. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/MetaData.php';
  147. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/MetaData/Dblib.php';
  148. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/MetaData/Firebird.php';
  149. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/MetaData/InformationSchema.php';
  150. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/MetaData/MySQL.php';
  151. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/MetaData/Oci.php';
  152. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/MetaData/PgSQL.php';
  153. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/MetaData/Sqlite.php';
  154. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/MetaData/SqlSrv.php';
  155. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/ResultSetTable.php';
  156. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/Table.php';
  157. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/TableIterator.php';
  158. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DB/TableMetaData.php';
  159. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/DefaultTester.php';
  160. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Exception.php';
  161. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/IDatabaseOperation.php';
  162. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/Composite.php';
  163. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/RowBased.php';
  164. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/Delete.php';
  165. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/DeleteAll.php';
  166. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/Exception.php';
  167. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/Factory.php';
  168. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/Insert.php';
  169. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/Null.php';
  170. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/Replace.php';
  171. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/Truncate.php';
  172. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/Operation/Update.php';
  173. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Test.php';
  174. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Assert.php';
  175. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/TestCase.php';
  176. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/TestCase.php';
  177. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/Command.php';
  178. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/Context.php';
  179. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/IMediumPrinter.php';
  180. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/IMedium.php';
  181. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/IMode.php';
  182. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/IModeFactory.php';
  183. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/InvalidModeException.php';
  184. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/Mediums/Text.php';
  185. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/ModeFactory.php';
  186. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/Modes/ExportDataSet.php';
  187. require 'phar://phpunit-4.7.0.phar' . '/dbunit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php';
  188. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/TestSuite.php';
  189. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Extensions/GroupTestSuite.php';
  190. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Extensions/PhptTestCase.php';
  191. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Extensions/PhptTestSuite.php';
  192. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Extensions/TestDecorator.php';
  193. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Extensions/RepeatedTest.php';
  194. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase.php';
  195. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Command.php';
  196. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/CommandsHolder.php';
  197. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Driver.php';
  198. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Element/Accessor.php';
  199. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Element.php';
  200. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Element/Select.php';
  201. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Attribute.php';
  202. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Click.php';
  203. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Css.php';
  204. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Equals.php';
  205. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.php';
  206. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericPost.php';
  207. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Keys.php';
  208. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Value.php';
  209. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCriteria.php';
  210. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Exception.php';
  211. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Keys.php';
  212. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/KeysHolder.php';
  213. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/NoSeleniumException.php';
  214. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Response.php';
  215. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/TestListener.php';
  216. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ScreenshotListener.php';
  217. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Session.php';
  218. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie.php';
  219. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie/Builder.php';
  220. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Storage.php';
  221. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Timeouts.php';
  222. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php';
  223. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Active.php';
  224. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AlertText.php';
  225. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Click.php';
  226. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php';
  227. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/File.php';
  228. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Frame.php';
  229. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.php';
  230. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.php';
  231. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Location.php';
  232. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Log.php';
  233. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/MoveTo.php';
  234. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Orientation.php';
  235. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Url.php';
  236. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Window.php';
  237. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy.php';
  238. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php';
  239. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Shared.php';
  240. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/StateCommand.php';
  241. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/URL.php';
  242. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/WaitUntil.php';
  243. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/WebDriverException.php';
  244. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Window.php';
  245. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/SeleniumBrowserSuite.php';
  246. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/SeleniumCommon/ExitHandler.php';
  247. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/SeleniumCommon/RemoteCoverage.php';
  248. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/SeleniumTestCase.php';
  249. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/SeleniumTestCase/Driver.php';
  250. require 'phar://phpunit-4.7.0.phar' . '/phpunit-selenium/Extensions/SeleniumTestSuite.php';
  251. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Extensions/TicketListener.php';
  252. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Exception.php';
  253. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/AssertionFailedError.php';
  254. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/BaseTestListener.php';
  255. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/CodeCoverageException.php';
  256. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/And.php';
  257. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/ArrayHasKey.php';
  258. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/ArraySubset.php';
  259. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/Composite.php';
  260. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/Attribute.php';
  261. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/Callback.php';
  262. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/ClassHasAttribute.php';
  263. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/ClassHasStaticAttribute.php';
  264. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/Count.php';
  265. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/Exception.php';
  266. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/ExceptionCode.php';
  267. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/ExceptionMessage.php';
  268. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/ExceptionMessageRegExp.php';
  269. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/FileExists.php';
  270. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/GreaterThan.php';
  271. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/IsAnything.php';
  272. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/IsEmpty.php';
  273. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/IsEqual.php';
  274. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/IsFalse.php';
  275. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/IsIdentical.php';
  276. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/IsInstanceOf.php';
  277. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/IsJson.php';
  278. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/IsNull.php';
  279. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/IsTrue.php';
  280. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/IsType.php';
  281. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/JsonMatches.php';
  282. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.php';
  283. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/LessThan.php';
  284. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/Not.php';
  285. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/ObjectHasAttribute.php';
  286. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/Or.php';
  287. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/PCREMatch.php';
  288. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/SameSize.php';
  289. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/StringContains.php';
  290. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/StringEndsWith.php';
  291. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/StringMatches.php';
  292. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/StringStartsWith.php';
  293. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/TraversableContains.php';
  294. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/TraversableContainsOnly.php';
  295. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Constraint/Xor.php';
  296. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Error.php';
  297. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Error/Deprecated.php';
  298. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Error/Notice.php';
  299. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Error/Warning.php';
  300. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/ExceptionWrapper.php';
  301. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/ExpectationFailedException.php';
  302. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/IncompleteTest.php';
  303. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/IncompleteTestCase.php';
  304. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/IncompleteTestError.php';
  305. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/SkippedTest.php';
  306. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/InvalidCoversTargetError.php';
  307. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/InvalidCoversTargetException.php';
  308. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Exception/Exception.php';
  309. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Exception/BadMethodCallException.php';
  310. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Identity.php';
  311. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Stub.php';
  312. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Match.php';
  313. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.php';
  314. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.php';
  315. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.php';
  316. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Namespace.php';
  317. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Generator.php';
  318. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Invocation.php';
  319. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Invocation/Static.php';
  320. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Invocation/Object.php';
  321. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.php';
  322. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Verifiable.php';
  323. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Invokable.php';
  324. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/InvocationMocker.php';
  325. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.php';
  326. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher.php';
  327. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.php';
  328. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.php';
  329. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.php';
  330. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.php';
  331. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/ConsecutiveParameters.php';
  332. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.php';
  333. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastCount.php';
  334. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.php';
  335. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtMostCount.php';
  336. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.php';
  337. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.php';
  338. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.php';
  339. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/MockBuilder.php';
  340. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/MockObject.php';
  341. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Exception/RuntimeException.php';
  342. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub.php';
  343. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.php';
  344. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/Exception.php';
  345. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/Return.php';
  346. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.php';
  347. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.php';
  348. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.php';
  349. require 'phar://phpunit-4.7.0.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.php';
  350. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/OutputError.php';
  351. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/RiskyTest.php';
  352. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/RiskyTestError.php';
  353. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/SkippedTestCase.php';
  354. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/SkippedTestError.php';
  355. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/SkippedTestSuiteError.php';
  356. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/SyntheticError.php';
  357. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/TestFailure.php';
  358. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/TestResult.php';
  359. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/TestSuite/DataProvider.php';
  360. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/UnintentionallyCoveredCodeError.php';
  361. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Framework/Warning.php';
  362. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Runner/BaseTestRunner.php';
  363. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Runner/Exception.php';
  364. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Runner/Filter/Factory.php';
  365. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Runner/Filter/Group.php';
  366. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Runner/Filter/Group/Exclude.php';
  367. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Runner/Filter/Group/Include.php';
  368. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Runner/Filter/Test.php';
  369. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Runner/TestSuiteLoader.php';
  370. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Runner/StandardTestSuiteLoader.php';
  371. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Runner/Version.php';
  372. require 'phar://phpunit-4.7.0.phar' . '/phpunit/TextUI/Command.php';
  373. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Printer.php';
  374. require 'phar://phpunit-4.7.0.phar' . '/phpunit/TextUI/ResultPrinter.php';
  375. require 'phar://phpunit-4.7.0.phar' . '/phpunit/TextUI/TestRunner.php';
  376. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Blacklist.php';
  377. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Configuration.php';
  378. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/ErrorHandler.php';
  379. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Fileloader.php';
  380. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Filesystem.php';
  381. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Filter.php';
  382. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Getopt.php';
  383. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/GlobalState.php';
  384. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/InvalidArgumentHelper.php';
  385. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Log/JSON.php';
  386. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Log/JUnit.php';
  387. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Log/TAP.php';
  388. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/PHP.php';
  389. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/PHP/Default.php';
  390. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/PHP/Windows.php';
  391. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Regex.php';
  392. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/String.php';
  393. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Test.php';
  394. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/TestDox/NamePrettifier.php';
  395. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/TestDox/ResultPrinter.php';
  396. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/TestDox/ResultPrinter/HTML.php';
  397. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/TestDox/ResultPrinter/Text.php';
  398. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/TestSuiteIterator.php';
  399. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/Type.php';
  400. require 'phar://phpunit-4.7.0.phar' . '/phpunit/Util/XML.php';
  401. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument.php';
  402. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/ArgumentsWildcard.php';
  403. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/TokenInterface.php';
  404. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/AnyValuesToken.php';
  405. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/AnyValueToken.php';
  406. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ArrayCountToken.php';
  407. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ArrayEntryToken.php';
  408. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ArrayEveryEntryToken.php';
  409. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/CallbackToken.php';
  410. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ExactValueToken.php';
  411. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/IdenticalValueToken.php';
  412. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/LogicalAndToken.php';
  413. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/LogicalNotToken.php';
  414. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ObjectStateToken.php';
  415. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/StringContainsToken.php';
  416. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/TypeToken.php';
  417. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Call/Call.php';
  418. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Call/CallCenter.php';
  419. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/Comparator.php';
  420. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Comparator/ClosureComparator.php';
  421. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/Factory.php';
  422. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Comparator/Factory.php';
  423. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/Doubler.php';
  424. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/CachedDoubler.php';
  425. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php';
  426. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php';
  427. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php';
  428. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/KeywordPatch.php';
  429. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/MagicCallPatch.php';
  430. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php';
  431. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php';
  432. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php';
  433. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/TraversablePatch.php';
  434. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/DoubleInterface.php';
  435. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ClassCodeGenerator.php';
  436. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ClassCreator.php';
  437. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ClassMirror.php';
  438. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/Node/ArgumentNode.php';
  439. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/Node/ClassNode.php';
  440. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/Node/MethodNode.php';
  441. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ReflectionInterface.php';
  442. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/LazyDouble.php';
  443. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Doubler/NameGenerator.php';
  444. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Exception.php';
  445. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Prophecy/ProphecyException.php';
  446. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Prophecy/ObjectProphecyException.php';
  447. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Call/UnexpectedCallException.php';
  448. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/DoublerException.php';
  449. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ClassCreatorException.php';
  450. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ClassMirrorException.php';
  451. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/DoubleException.php';
  452. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ClassNotFoundException.php';
  453. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/InterfaceNotFoundException.php';
  454. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/MethodNotFoundException.php';
  455. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ReturnByReferenceException.php';
  456. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/InvalidArgumentException.php';
  457. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/PredictionException.php';
  458. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/AggregateException.php';
  459. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/FailedPredictionException.php';
  460. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Prophecy/MethodProphecyException.php';
  461. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/NoCallsException.php';
  462. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsException.php';
  463. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php';
  464. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prediction/PredictionInterface.php';
  465. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prediction/CallbackPrediction.php';
  466. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prediction/CallPrediction.php';
  467. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prediction/CallTimesPrediction.php';
  468. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prediction/NoCallsPrediction.php';
  469. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Promise/PromiseInterface.php';
  470. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Promise/CallbackPromise.php';
  471. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Promise/ReturnArgumentPromise.php';
  472. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Promise/ReturnPromise.php';
  473. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Promise/ThrowPromise.php';
  474. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prophecy/MethodProphecy.php';
  475. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prophecy/ProphecyInterface.php';
  476. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prophecy/ObjectProphecy.php';
  477. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prophecy/ProphecySubjectInterface.php';
  478. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prophecy/RevealerInterface.php';
  479. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prophecy/Revealer.php';
  480. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Prophet.php';
  481. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Util/ExportUtil.php';
  482. require 'phar://phpunit-4.7.0.phar' . '/phpspec-prophecy/Prophecy/Util/StringUtil.php';
  483. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/ArrayComparator.php';
  484. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/ComparisonFailure.php';
  485. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/ObjectComparator.php';
  486. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/DateTimeComparator.php';
  487. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/DOMNodeComparator.php';
  488. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/ScalarComparator.php';
  489. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/NumericComparator.php';
  490. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/DoubleComparator.php';
  491. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/ExceptionComparator.php';
  492. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/MockObjectComparator.php';
  493. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/ResourceComparator.php';
  494. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/SplObjectStorageComparator.php';
  495. require 'phar://phpunit-4.7.0.phar' . '/sebastian-comparator/TypeComparator.php';
  496. require 'phar://phpunit-4.7.0.phar' . '/sebastian-diff/Chunk.php';
  497. require 'phar://phpunit-4.7.0.phar' . '/sebastian-diff/Diff.php';
  498. require 'phar://phpunit-4.7.0.phar' . '/sebastian-diff/Differ.php';
  499. require 'phar://phpunit-4.7.0.phar' . '/sebastian-diff/LCS/LongestCommonSubsequence.php';
  500. require 'phar://phpunit-4.7.0.phar' . '/sebastian-diff/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php';
  501. require 'phar://phpunit-4.7.0.phar' . '/sebastian-diff/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php';
  502. require 'phar://phpunit-4.7.0.phar' . '/sebastian-diff/Line.php';
  503. require 'phar://phpunit-4.7.0.phar' . '/sebastian-diff/Parser.php';
  504. require 'phar://phpunit-4.7.0.phar' . '/sebastian-environment/Console.php';
  505. require 'phar://phpunit-4.7.0.phar' . '/sebastian-environment/Runtime.php';
  506. require 'phar://phpunit-4.7.0.phar' . '/sebastian-exporter/Exporter.php';
  507. require 'phar://phpunit-4.7.0.phar' . '/sebastian-global-state/Blacklist.php';
  508. require 'phar://phpunit-4.7.0.phar' . '/sebastian-global-state/Exception.php';
  509. require 'phar://phpunit-4.7.0.phar' . '/sebastian-global-state/Restorer.php';
  510. require 'phar://phpunit-4.7.0.phar' . '/sebastian-global-state/RuntimeException.php';
  511. require 'phar://phpunit-4.7.0.phar' . '/sebastian-global-state/Snapshot.php';
  512. require 'phar://phpunit-4.7.0.phar' . '/sebastian-recursion-context/Context.php';
  513. require 'phar://phpunit-4.7.0.phar' . '/sebastian-recursion-context/Exception.php';
  514. require 'phar://phpunit-4.7.0.phar' . '/sebastian-recursion-context/InvalidArgumentException.php';
  515. require 'phar://phpunit-4.7.0.phar' . '/sebastian-version/Version.php';
  516. require 'phar://phpunit-4.7.0.phar' . '/symfony/yaml/Dumper.php';
  517. require 'phar://phpunit-4.7.0.phar' . '/symfony/yaml/Escaper.php';
  518. require 'phar://phpunit-4.7.0.phar' . '/symfony/yaml/Exception/ExceptionInterface.php';
  519. require 'phar://phpunit-4.7.0.phar' . '/symfony/yaml/Exception/RuntimeException.php';
  520. require 'phar://phpunit-4.7.0.phar' . '/symfony/yaml/Exception/DumpException.php';
  521. require 'phar://phpunit-4.7.0.phar' . '/symfony/yaml/Exception/ParseException.php';
  522. require 'phar://phpunit-4.7.0.phar' . '/symfony/yaml/Inline.php';
  523. require 'phar://phpunit-4.7.0.phar' . '/symfony/yaml/Parser.php';
  524. require 'phar://phpunit-4.7.0.phar' . '/symfony/yaml/Unescaper.php';
  525. require 'phar://phpunit-4.7.0.phar' . '/symfony/yaml/Yaml.php';
  526. require 'phar://phpunit-4.7.0.phar' . '/php-text-template/Template.php';
  527. if ($execute) {
  528. if (isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == '--manifest') {
  529. print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/manifest.txt');
  530. exit;
  531. }
  532. PHPUnit_TextUI_Command::main();
  533. }
  534. __HALT_COMPILER(); ?>
  535. E³��9���������phpunit-4.7.0.phar����$���sebastian-global-state/Exception.phpþ��"qUþ�� ª„´¶������#���sebastian-global-state/Snapshot.php',��"qU',��5+å ¶���������sebastian-global-state/LICENSE
  536. ��"qU
  537. ��êâ¶������#���sebastian-global-state/Restorer.phpž��"qUž��­}FÔ¶������$���sebastian-global-state/Blacklist.php#��"qU#��Òf1“¶������+���sebastian-global-state/RuntimeException.php0 ��"qU0 ���Èyv¶���������php-text-template/LICENSE ��"qU ��²d¸è¶���������php-text-template/Template.phpð��"qUð��í;$¶���������sebastian-diff/LICENSE��"qU��vEvö������/���sebastian-diff/LCS/LongestCommonSubsequence.phpº��"qUº��»Ø›¶������L���sebastian-diff/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.phpô
  538. ��"qUô
  539. ��ƒÓg8¶������J���sebastian-diff/LCS/TimeEfficientLongestCommonSubsequenceImplementation.phpá��"qUá��Š½¸r¶���������sebastian-diff/Line.phpé��"qUé��ü¼éζ���������sebastian-diff/Differ.php��"qU��ºŒ<6¶���������sebastian-diff/Parser.phps ��"qUs ��vÚ ^¶���������sebastian-diff/Diff.php��"qU��²ª¶���������sebastian-diff/Chunk.php��"qU��9LKé¶���������php-timer/Timer.php6��"qU6��#X6ñ¶���������php-timer/LICENSE��"qU���ÔN>¶���������sebastian-comparator/LICENSE ��"qU ��”:¶������#���sebastian-comparator/Comparator.php ��"qU ��o:7¶������3���sebastian-comparator/SplObjectStorageComparator.php6 ��"qU6 ��íÃÓɶ������'���sebastian-comparator/TypeComparator.php@ ��"qU@ ��ÍFòñ¶������)���sebastian-comparator/ObjectComparator.php.��"qU.��˯?ð¶������+���sebastian-comparator/ResourceComparator.phpŠ��"qUŠ��aõµV¶������(���sebastian-comparator/ArrayComparator.phpv��"qUv�� ÀíÕ¶������+���sebastian-comparator/DateTimeComparator.php™ ��"qU™ ��JzM¶������,���sebastian-comparator/ExceptionComparator.php��"qU��ƒîÔ¶������*���sebastian-comparator/DOMNodeComparator.php,��"qU,��ûû�W¶������)���sebastian-comparator/ScalarComparator.phpÏ��"qUÏ��"’18¶������-���sebastian-comparator/MockObjectComparator.phpé��"qUé��ÂÌSö¶������*���sebastian-comparator/NumericComparator.phpF ��"qUF ��»š`¶������ ���sebastian-comparator/Factory.php‰ ��"qU‰ ��@‹Ø¶������)���sebastian-comparator/DoubleComparator.phpÐ��"qUÐ��š¼ž×¶������*���sebastian-comparator/ComparisonFailure.phpÅ ��"qUÅ ��ƒÓºª¶���������phpspec-prophecy/LICENSE}��"qU}��òÅ6¶������8���phpspec-prophecy/Prophecy/Prophecy/RevealerInterface.phpH��"qUH��‡gZ¶¶������?���phpspec-prophecy/Prophecy/Prophecy/ProphecySubjectInterface.phpß��"qUß��i²¶������/���phpspec-prophecy/Prophecy/Prophecy/Revealer.php���"qU���jÉɸ¶������8���phpspec-prophecy/Prophecy/Prophecy/ProphecyInterface.php,��"qU,��¡W¶������5���phpspec-prophecy/Prophecy/Prophecy/ObjectProphecy.phpk��"qUk��k„ʶ������5���phpspec-prophecy/Prophecy/Prophecy/MethodProphecy.php(��"qU(��ç�ÔŶ������:���phpspec-prophecy/Prophecy/Comparator/ClosureComparator.phpK��"qUK��)RQã¶������0���phpspec-prophecy/Prophecy/Comparator/Factory.php¡��"qU¡��Aê϶������&���phpspec-prophecy/Prophecy/Argument.php^��"qU^��l”¶������%���phpspec-prophecy/Prophecy/Prophet.php��"qU��çvqŽ¶������1���phpspec-prophecy/Prophecy/Exception/Exception.php+��"qU+��¸µ‘¶������H���phpspec-prophecy/Prophecy/Exception/Prophecy/ObjectProphecyException.php��"qU��†:‚F¶������B���phpspec-prophecy/Prophecy/Exception/Prophecy/ProphecyException.php™��"qU™��Üê$϶������H���phpspec-prophecy/Prophecy/Exception/Prophecy/MethodProphecyException.php)��"qU)��Fù¢4¶������J���phpspec-prophecy/Prophecy/Exception/Doubler/InterfaceNotFoundException.phpà��"qUà��õ¡…ý¶������D���phpspec-prophecy/Prophecy/Exception/Doubler/ClassMirrorException.phpª��"qUª��Û‰?¶������?���phpspec-prophecy/Prophecy/Exception/Doubler/DoubleException.php©��"qU©��zéFƒ¶������@���phpspec-prophecy/Prophecy/Exception/Doubler/DoublerException.php—��"qU—��ÃZ^¶������G���phpspec-prophecy/Prophecy/Exception/Doubler/MethodNotFoundException.phpÖ��"qUÖ��iÞhó¶������J���phpspec-prophecy/Prophecy/Exception/Doubler/ReturnByReferenceException.php���"qU���ýª¶������E���phpspec-prophecy/Prophecy/Exception/Doubler/ClassCreatorException.phpµ��"qUµ��77/%¶������F���phpspec-prophecy/Prophecy/Exception/Doubler/ClassNotFoundException.phpÅ��"qUÅ��h+������K���phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsException.php,��"qU,����õa¶������F���phpspec-prophecy/Prophecy/Exception/Prediction/PredictionException.php���"qU���2T¢Ñ¶������L���phpspec-prophecy/Prophecy/Exception/Prediction/FailedPredictionException.phpJ��"qUJ��~ÐãD¶������C���phpspec-prophecy/Prophecy/Exception/Prediction/NoCallsException.phpÚ��"qUÚ��Ál<�¶������E���phpspec-prophecy/Prophecy/Exception/Prediction/AggregateException.php»��"qU»��?D<ζ������P���phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php��"qU��æ ƶ������D���phpspec-prophecy/Prophecy/Exception/Call/UnexpectedCallException.phpÖ��"qUÖ��£Áó¸¶������@���phpspec-prophecy/Prophecy/Exception/InvalidArgumentException.php•��"qU•��¨gì¶������3���phpspec-prophecy/Prophecy/Doubler/CachedDoubler.phpƒ��"qUƒ��̇gè¶������5���phpspec-prophecy/Prophecy/Doubler/DoubleInterface.phpâ��"qUâ��8d�j¶������-���phpspec-prophecy/Prophecy/Doubler/Doubler.php���"qU���8]Õ^¶������B���phpspec-prophecy/Prophecy/Doubler/Generator/ClassCodeGenerator.phpU
  540. ��"qUU
  541. ��J9½y¶������<���phpspec-prophecy/Prophecy/Doubler/Generator/ClassCreator.phpÔ��"qUÔ��ä?Br¶������C���phpspec-prophecy/Prophecy/Doubler/Generator/ReflectionInterface.phpò��"qUò��çûªå¶������;���phpspec-prophecy/Prophecy/Doubler/Generator/ClassMirror.phpŒ��"qUŒ��p%f¶������A���phpspec-prophecy/Prophecy/Doubler/Generator/Node/ArgumentNode.phpš��"qUš��^ž¶������?���phpspec-prophecy/Prophecy/Doubler/Generator/Node/MethodNode.phpÛ
  542. ��"qUÛ
  543. ��ÿ¸Ó¶������>���phpspec-prophecy/Prophecy/Doubler/Generator/Node/ClassNode.phpP
  544. ��"qUP
  545. ��M°-Š¶������0���phpspec-prophecy/Prophecy/Doubler/LazyDouble.phpF ��"qUF ��¼ël¦¶������=���phpspec-prophecy/Prophecy/Doubler/ClassPatch/KeywordPatch.php½ ��"qU½ ��û/@ȶ������E���phpspec-prophecy/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.phpô
  546. ��"qUô
  547. ��Ân–i¶������?���phpspec-prophecy/Prophecy/Doubler/ClassPatch/MagicCallPatch.phpâ��"qUâ��Áyú¶������A���phpspec-prophecy/Prophecy/Doubler/ClassPatch/TraversablePatch.php ��"qU ��§€jN¶������A���phpspec-prophecy/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php���"qU���!h^¶������H���phpspec-prophecy/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php’��"qU’��:0`ò¶������C���phpspec-prophecy/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.phpÑ��"qUÑ��x“Â^¶������P���phpspec-prophecy/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.phpp��"qUp��x¤¿ˆ¶������D���phpspec-prophecy/Prophecy/Doubler/ClassPatch/ClassPatchInterface.phpl��"qUl��)Š5:¶������3���phpspec-prophecy/Prophecy/Doubler/NameGenerator.phpŠ��"qUŠ��õÑ7¶������<���phpspec-prophecy/Prophecy/Prediction/CallTimesPrediction.php“ ��"qU“ ��XŠü¶������:���phpspec-prophecy/Prophecy/Prediction/NoCallsPrediction.phpå��"qUå��L9%¶������<���phpspec-prophecy/Prophecy/Prediction/PredictionInterface.phpŸ��"qUŸ��`IE¶������;���phpspec-prophecy/Prophecy/Prediction/CallbackPrediction.php“��"qU“��Vb{ζ������7���phpspec-prophecy/Prophecy/Prediction/CallPrediction.phpQ ��"qUQ ��Iæ“é¶������'���phpspec-prophecy/Prophecy/Call/Call.phpÓ ��"qUÓ ��{:å%¶������-���phpspec-prophecy/Prophecy/Call/CallCenter.phpm��"qUm��š[µ9¶������2���phpspec-prophecy/Prophecy/Promise/ThrowPromise.php9
  548. ��"qU9
  549. ��˜½cu¶������;���phpspec-prophecy/Prophecy/Promise/ReturnArgumentPromise.php��"qU��¨ô%A¶������3���phpspec-prophecy/Prophecy/Promise/ReturnPromise.php��"qU��çØ�ä¶������5���phpspec-prophecy/Prophecy/Promise/CallbackPromise.php���"qU���[žÜ¶������6���phpspec-prophecy/Prophecy/Promise/PromiseInterface.phpK��"qUK��¾¬…ë¶������8���phpspec-prophecy/Prophecy/Argument/ArgumentsWildcard.php4 ��"qU4 ��A;K2¶������:���phpspec-prophecy/Prophecy/Argument/Token/AnyValueToken.php«��"qU«��F�h¶������A���phpspec-prophecy/Prophecy/Argument/Token/ArrayEveryEntryToken.php’��"qU’��pbø�¶������<���phpspec-prophecy/Prophecy/Argument/Token/LogicalAndToken.phpø��"qUø�� Nãv¶������;���phpspec-prophecy/Prophecy/Argument/Token/TokenInterface.php���"qU���Ù°Š¼¶������<���phpspec-prophecy/Prophecy/Argument/Token/ArrayEntryToken.php”��"qU”��ÞJú:¶������<���phpspec-prophecy/Prophecy/Argument/Token/ArrayCountToken.phpá��"qUá��‚4®Ì¶������;���phpspec-prophecy/Prophecy/Argument/Token/AnyValuesToken.phpÚ��"qUÚ��ÖbN/¶������@���phpspec-prophecy/Prophecy/Argument/Token/StringContainsToken.phpü��"qUü��‰ÑÊ>¶������<���phpspec-prophecy/Prophecy/Argument/Token/ExactValueToken.php¡ ��"qU¡ ���…3�¶������=���phpspec-prophecy/Prophecy/Argument/Token/ObjectStateToken.php9
  550. ��"qU9
  551. ��_ÛJg¶������:���phpspec-prophecy/Prophecy/Argument/Token/CallbackToken.php,��"qU,��cRÊ̶������@���phpspec-prophecy/Prophecy/Argument/Token/IdenticalValueToken.phpæ��"qUæ���¯Êý¶������<���phpspec-prophecy/Prophecy/Argument/Token/LogicalNotToken.php��"qU��ܼr¶������6���phpspec-prophecy/Prophecy/Argument/Token/TypeToken.php¥��"qU¥��®næ\¶������-���phpspec-prophecy/Prophecy/Util/ExportUtil.php„��"qU„��ѪzH¶������-���phpspec-prophecy/Prophecy/Util/StringUtil.phpì ��"qUì ��%ø¶���������sebastian-exporter/LICENSE��"qU��Aªe)¶���������sebastian-exporter/Exporter.php*#��"qU*#��žÓl׶���������php-file-iterator/LICENSE ��"qU ��¶És‰¶���������php-file-iterator/Iterator.php²��"qU²��¬É¶���������php-file-iterator/Facade.phpô ��"qUô ��Q–훶���������php-file-iterator/Factory.php¸
  552. ��"qU¸
  553. ��dÂŽ¶������ ���manifest.txt_��"qU_��\½“¶������)���sebastian-recursion-context/Exception.phpˆ��"qUˆ��>å™3¶������#���sebastian-recursion-context/LICENSE��"qU��Éðζ������'���sebastian-recursion-context/Context.php°��"qU°��ø¿Nê¶������8���sebastian-recursion-context/InvalidArgumentException.phpÐ��"qUÐ��Ê ¨ú¶������0���phpunit-selenium/Extensions/SeleniumTestCase.phpÀ—��"qUÀ—��Ãv�K¶������1���phpunit-selenium/Extensions/SeleniumTestSuite.php���"qU���®šä¶������7���phpunit-selenium/Extensions/SeleniumTestCase/Driver.phpM°��"qUM°��0âR¶������6���phpunit-selenium/Extensions/Selenium2TestCase/Keys.phpI��"qUI��î†Í¶������H���phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie/Builder.php��"qU��Ó¸q¶������B���phpunit-selenium/Extensions/Selenium2TestCase/Session/Timeouts.php]��"qU]��œ/X¶������A���phpunit-selenium/Extensions/Selenium2TestCase/Session/Storage.php8 ��"qU8 ��›‚º¶������@���phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie.phpý��"qUý��$!¸–¶������;���phpunit-selenium/Extensions/Selenium2TestCase/Exception.phpã ��"qUã ��H"Ç[¶������@���phpunit-selenium/Extensions/Selenium2TestCase/CommandsHolder.phpË��"qUË��Zew¶������D���phpunit-selenium/Extensions/Selenium2TestCase/ScreenshotListener.phpØ��"qUØ��h­7Ƕ������9���phpunit-selenium/Extensions/Selenium2TestCase/Command.phpL ��"qUL ��Îcyƶ������>���phpunit-selenium/Extensions/Selenium2TestCase/StateCommand.phpw
  554. ��"qUw
  555. �� e3Z¶������9���phpunit-selenium/Extensions/Selenium2TestCase/Element.php ��"qU ��&éø¶������:���phpunit-selenium/Extensions/Selenium2TestCase/Response.php��"qU��TZ¶������E���phpunit-selenium/Extensions/Selenium2TestCase/NoSeleniumException.phpÅ ��"qUÅ ��Ûök¶������H���phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Shared.phpH��"qUH��ÚVm’¶������J���phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php’ ��"qU’ ���ìͶ������F���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Click.php+
  556. ��"qU+
  557. ��¡Ä»¶������G���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Equals.php` ��"qU` ��Én±Õ¶������P���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.phpi
  558. ��"qUi
  559. ��•Pe¶������L���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericPost.phpW
  560. ��"qUW
  561. ��ëLq¶������F���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Value.phpG ��"qUG ��+Uç¶������J���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Attribute.phpt ��"qUt �� ˈ¶������D���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Css.phpi ��"qUi ��ó¶������A���phpunit-selenium/Extensions/Selenium2TestCase/ElementCriteria.phpN ��"qUN ���ʶ������8���phpunit-selenium/Extensions/Selenium2TestCase/Window.phpO ��"qUO ��S§ßô¶������8���phpunit-selenium/Extensions/Selenium2TestCase/Driver.phpÑ��"qUÑ��eÅ5v¶������;���phpunit-selenium/Extensions/Selenium2TestCase/WaitUntil.php”��"qU”��z“¶������D���phpunit-selenium/Extensions/Selenium2TestCase/WebDriverException.phpf ��"qUf ��ÍK1ï¶������E���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Keys.php$��"qU$��wîͶ������F���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Click.php» ��"qU» ��^ÿaé¶������I���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Location.phpÏ ��"qUÏ ��ô¡Ë ¶������P���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.phpT
  562. ��"qUT
  563. ��X·ì¶������E���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/File.phpè��"qUè��0“ß—¶������L���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php1
  564. ��"qU1
  565. ��BHǶ������J���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AlertText.phpC ��"qUC ��lXim¶������D���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Url.php ��"qU ��K¸Ž¶������G���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Window.phpÜ
  566. ��"qUÜ
  567. ��•ˆ’¶������Q���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.phpŸ
  568. ��"qUŸ
  569. ��›Bí¶������G���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/MoveTo.phpÎ��"qUÎ��£-
  570. ¶������L���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Orientation.phpÞ ��"qUÞ ��@\WI¶������D���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Log.php ��"qU ��œð"=¶������G���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Active.php
  571. ��"qU
  572. ��×6¸¶������M���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php6
  573. ��"qU6
  574. ��Ñv’l¶������F���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Frame.php¶ ��"qU¶ ��çz"¶������5���phpunit-selenium/Extensions/Selenium2TestCase/URL.php™��"qU™��HFž¶������A���phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy.php¡ ��"qU¡ ��̳ãr¶������<���phpunit-selenium/Extensions/Selenium2TestCase/KeysHolder.php��"qU��Ñ|ÚH¶������B���phpunit-selenium/Extensions/Selenium2TestCase/Element/Accessor.php¯��"qU¯��û\w€¶������@���phpunit-selenium/Extensions/Selenium2TestCase/Element/Select.php­��"qU­��ëL@"¶������9���phpunit-selenium/Extensions/Selenium2TestCase/Session.php!1��"qU!1��š ™¶������6���phpunit-selenium/Extensions/SeleniumCommon/prepend.php? ��"qU? ��°·³¶������5���phpunit-selenium/Extensions/SeleniumCommon/append.php ��"qU ��›·ú÷¶������=���phpunit-selenium/Extensions/SeleniumCommon/RemoteCoverage.phpI��"qUI��Ý\´.¶������:���phpunit-selenium/Extensions/SeleniumCommon/ExitHandler.php*��"qU*��¢èÏ϶������?���phpunit-selenium/Extensions/SeleniumCommon/phpunit_coverage.php`��"qU`��½ùOm¶������4���phpunit-selenium/Extensions/SeleniumBrowserSuite.phpò��"qUò��D³¥¶������1���phpunit-selenium/Extensions/Selenium2TestCase.php!E��"qU!E��ï[‘ñ¶������'���php-code-coverage/CodeCoverage/Util.php��"qU��¥§ŠÌ¶������,���php-code-coverage/CodeCoverage/Exception.phpè��"qUè��Î�l@¶������7���php-code-coverage/CodeCoverage/Report/HTML/Renderer.php ��"qU ��«¬¶������A���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Dashboard.php$(��"qU$(��_ð�‰¶������<���php-code-coverage/CodeCoverage/Report/HTML/Renderer/File.php_M��"qU_M��3}Î�¶������P���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/dashboard.html.distk��"qUk��Üz¶������P���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/directory.html.diste��"qUe��Ç�¥ô¶������S���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/coverage_bar.html.dist1��"qU1��itLì¶������P���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/bootstrap.min.jsoŒ��"qUoŒ��;¦� ¶������I���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/d3.min.jsUN�"qUUN�;Áë1¶������N���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/respond.min.js��"qU��í{¶������P���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/html5shiv.min.jsL
  575. ��"qUL
  576. ��F¨¶������M���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/holder.min.js m��"qU m��JësѶ������L���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/nv.d3.min.jsÏ�"qUÏ�mâ¶������M���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/jquery.min.jsÕv�"qUÕv�†e“¶������P���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/file_item.html.distg��"qUg��V³ P¶������R���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/method_item.html.distx��"qUx��*öŒ¶������U���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/directory_item.html.dist5��"qU5��ñZˆ]¶������K���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/file.html.distþ
  577. ��"qUþ
  578. ��øýŠD¶������J���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/style.css+��"qU+��Y`üg¶������N���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/nv.d3.min.css>!��"qU>!��_ˆl¶������R���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap.min.css9Ê�"qU9Ê�Ü›2ø¶������c���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.ttf\±��"qU\±��š<œ¶������e���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff2lF��"qUlF��vèÃa¶������d���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff€[��"qU€[��ê{õ¶������c���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.eotŸN��"qUŸN��XDZœ¶������c���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.svg¨�"qU¨�|îÆɶ������A���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Directory.phpÀ��"qUÀ��Òi‚¶������0���php-code-coverage/CodeCoverage/Report/Crap4j.php…��"qU…��©¹yð¶������3���php-code-coverage/CodeCoverage/Report/XML/Tests.phpÄ��"qUÄ��¯t0¶������2���php-code-coverage/CodeCoverage/Report/XML/File.phpm��"qUm��†Lk¶������2���php-code-coverage/CodeCoverage/Report/XML/Node.php› ��"qU› ��[Ò¥;¶������5���php-code-coverage/CodeCoverage/Report/XML/Project.phpš��"qUš��U‹:ç¶������4���php-code-coverage/CodeCoverage/Report/XML/Totals.php��"qU��ëÑ÷¶������7���php-code-coverage/CodeCoverage/Report/XML/Directory.phpÆ��"qUÆ��ÎOo¾¶������9���php-code-coverage/CodeCoverage/Report/XML/File/Method.php²��"qU²���6Þ¶������9���php-code-coverage/CodeCoverage/Report/XML/File/Report.php€��"qU€��ºL¬à¶������;���php-code-coverage/CodeCoverage/Report/XML/File/Coverage.phpr��"qUr��T(Ë=¶������7���php-code-coverage/CodeCoverage/Report/XML/File/Unit.php ��"qU ���½ýX¶������.���php-code-coverage/CodeCoverage/Report/Node.php���"qU���‚Ӗ̶������7���php-code-coverage/CodeCoverage/Report/Node/Iterator.php
  579. ��"qU
  580. ��ŒªIµ¶������3���php-code-coverage/CodeCoverage/Report/Node/File.phpDI��"qUDI��‰ H¶������8���php-code-coverage/CodeCoverage/Report/Node/Directory.php*��"qU*��Á”R¶������0���php-code-coverage/CodeCoverage/Report/Clover.php)��"qU)��†ÿAŶ������.���php-code-coverage/CodeCoverage/Report/HTML.phpŒ��"qUŒ��¡±Ä¶������1���php-code-coverage/CodeCoverage/Report/Factory.php–��"qU–��ðï(¶������-���php-code-coverage/CodeCoverage/Report/XML.phpu��"qUu��‹f”¶������-���php-code-coverage/CodeCoverage/Report/PHP.phpm��"qUm��Lé^z¶������.���php-code-coverage/CodeCoverage/Report/Text.php¹"��"qU¹"��xüLî¶������G���php-code-coverage/CodeCoverage/Exception/UnintentionallyCoveredCode.php��"qU��¥Kë¶������)���php-code-coverage/CodeCoverage/Driver.php¦��"qU¦��íN1 ¶������)���php-code-coverage/CodeCoverage/Filter.phpb��"qUb��ä;³Á¶������=���php-code-coverage/CodeCoverage/Util/InvalidArgumentHelper.php„��"qU„��_Þ:
  581. ¶������.���php-code-coverage/CodeCoverage/Driver/HHVM.phpp��"qUp��þØ<r¶������0���php-code-coverage/CodeCoverage/Driver/Xdebug.phpü
  582. ��"qUü
  583. ��œ�Í1¶���������php-code-coverage/LICENSE��"qU��ЉxZ¶������"���php-code-coverage/CodeCoverage.phpg��"qUg��N¨‰¶���������symfony/LICENSE)��"qU)��ë&•¶���������symfony/yaml/Inline.phphM��"qUhM��€</ʶ���������symfony/yaml/Unescaper.phpÐ��"qUÐ��éÒ�m¶���������symfony/yaml/Yaml.php1��"qU1��ð¸ @¶������)���symfony/yaml/Exception/ParseException.php��"qU��Î79‹¶������(���symfony/yaml/Exception/DumpException.phpÒ��"qUÒ��ؙ՚¶������+���symfony/yaml/Exception/RuntimeException.phpð��"qUð��Ï|�-¶������-���symfony/yaml/Exception/ExceptionInterface.phpÆ��"qUÆ��î+­l¶���������symfony/yaml/Parser.phpuh��"qUuh��6Q²}¶���������symfony/yaml/Dumper.php� ��"qU� ��l£D¶���������symfony/yaml/Escaper.php��"qU��K‹ã¶���������ca.pemñ��"qUñ��‹byë¶���������doctrine-instantiator/LICENSE$��"qU$��
  584. Í‚å¶������E���doctrine-instantiator/Doctrine/Instantiator/InstantiatorInterface.php~��"qU~��¶ÿÌ:¶������L���doctrine-instantiator/Doctrine/Instantiator/Exception/ExceptionInterface.php¥��"qU¥��ó.ðö������R���doctrine-instantiator/Doctrine/Instantiator/Exception/InvalidArgumentException.phpô��"qUô��hÅ7I¶������R���doctrine-instantiator/Doctrine/Instantiator/Exception/UnexpectedValueException.phpÎ
  585. ��"qUÎ
  586. ��"Ÿè ¶������<���doctrine-instantiator/Doctrine/Instantiator/Instantiator.phpÊ��"qUÊ��X˜¢¶���������php-token-stream/LICENSE��"qU��ƒ-& ¶������0���php-token-stream/Token/Stream/CachingFactory.php?��"qU?��ì'· ¶������!���php-token-stream/Token/Stream.php¼=��"qU¼=��è/⪶���������php-token-stream/Token.phpBX��"qUBX��0 á)¶������(���dbunit/Extensions/Database/Exception.php4��"qU4��ó¾Ù¶������0���dbunit/Extensions/Database/UI/IMediumPrinter.phpØ��"qUØ��…e c¶������)���dbunit/Extensions/Database/UI/Command.php{��"qU{��ÿëTD¶������.���dbunit/Extensions/Database/UI/Mediums/Text.phpÊ
  587. ��"qUÊ
  588. ��ºÐ]Ó¶������6���dbunit/Extensions/Database/UI/InvalidModeException.phpõ��"qUõ��~Ë%¶������'���dbunit/Extensions/Database/UI/IMode.phpæ��"qUæ��é=̶������)���dbunit/Extensions/Database/UI/Context.phpC��"qUC��îä]¶������?���dbunit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php7 ��"qU7 ��@?¶������5���dbunit/Extensions/Database/UI/Modes/ExportDataSet.php$ ��"qU$ ��×\±À¶������)���dbunit/Extensions/Database/UI/IMedium.php‚��"qU‚��ÐPî÷¶������-���dbunit/Extensions/Database/UI/ModeFactory.phpR ��"qUR ��£²–û¶������.���dbunit/Extensions/Database/UI/IModeFactory.php��"qU��[E†¶������4���dbunit/Extensions/Database/IDatabaseListConsumer.phpj��"qUj��ƒ�‚¶������2���dbunit/Extensions/Database/Operation/Exception.phpó��"qUó��GLO�¶������0���dbunit/Extensions/Database/Operation/Replace.php���"qU���Ä –?¶������/���dbunit/Extensions/Database/Operation/Insert.php
  589. ��"qU
  590. ��{³;¶������/���dbunit/Extensions/Database/Operation/Delete.phpD��"qUD��œ=Œ¶������;���dbunit/Extensions/Database/Operation/IDatabaseOperation.phpü��"qUü��“AÜʶ������-���dbunit/Extensions/Database/Operation/Null.php³��"qU³��L?¶������2���dbunit/Extensions/Database/Operation/DeleteAll.phpË��"qUË��z”¶������/���dbunit/Extensions/Database/Operation/Update.phpÐ ��"qUÐ ��µNÐB¶������1���dbunit/Extensions/Database/Operation/RowBased.phpS��"qUS��hÈ=¶������0���dbunit/Extensions/Database/Operation/Factory.phpá ��"qUá ��~÷õ¶������2���dbunit/Extensions/Database/Operation/Composite.php¸��"qU¸��€fn­¶������1���dbunit/Extensions/Database/Operation/Truncate.phpè
  591. ��"qUè
  592. ��{�÷>¶������'���dbunit/Extensions/Database/TestCase.phpw!��"qUw!��´ƒY¶������-���dbunit/Extensions/Database/AbstractTester.phpM��"qUM��/ýÅh¶������1���dbunit/Extensions/Database/DB/MetaData/Sqlite.php] ��"qU] �� ÂŒ¶������0���dbunit/Extensions/Database/DB/MetaData/Dblib.phpû ��"qUû ��Ý_¶������0���dbunit/Extensions/Database/DB/MetaData/MySQL.phpõ ��"qUõ ���’¥†¶������<���dbunit/Extensions/Database/DB/MetaData/InformationSchema.php“��"qU“��ý뛜¶������3���dbunit/Extensions/Database/DB/MetaData/Firebird.php��"qU��ã{ꙶ������.���dbunit/Extensions/Database/DB/MetaData/Oci.php|��"qU|��•ÍhŸ¶������0���dbunit/Extensions/Database/DB/MetaData/PgSQL.phpÞ��"qUÞ��¸Ç¾�¶������1���dbunit/Extensions/Database/DB/MetaData/SqlSrv.php´��"qU´��¼N|¶������'���dbunit/Extensions/Database/DB/Table.phpÒ��"qUÒ��Ú~˜P¶������1���dbunit/Extensions/Database/DB/FilteredDataSet.phpv��"qUv��[å—T¶������5���dbunit/Extensions/Database/DB/IDatabaseConnection.php½ ��"qU½ ��G$Ú/¶������/���dbunit/Extensions/Database/DB/TableMetaData.phpI��"qUI��âŠ9�¶������*���dbunit/Extensions/Database/DB/MetaData.phpu��"qUu��«ðƒ»¶������;���dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php2��"qU2��ô†ç¾¶������+���dbunit/Extensions/Database/DB/IMetaData.php_��"qU_��aI ¶������/���dbunit/Extensions/Database/DB/TableIterator.php³ ��"qU³ ��åE¢Ï¶������)���dbunit/Extensions/Database/DB/DataSet.php��"qU��Ú«¥.¶������0���dbunit/Extensions/Database/DB/ResultSetTable.php��"qU��‚ƒ%®¶������,���dbunit/Extensions/Database/DefaultTester.phpØ��"qUØ��Õª\¶������6���dbunit/Extensions/Database/Constraint/TableIsEqual.php¬ ��"qU¬ ��ý­G¶������8���dbunit/Extensions/Database/Constraint/DataSetIsEqual.phpº ��"qUº ��ž_ˆÑ¶������7���dbunit/Extensions/Database/Constraint/TableRowCount.php½��"qU½��Reƶ������&���dbunit/Extensions/Database/ITester.phpÓ ��"qUÓ ��–%V¶������6���dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.phpV��"qUV��#꥗¶������3���dbunit/Extensions/Database/DataSet/QueryDataSet.php˜
  593. ��"qU˜
  594. ��Èß¡¶������2���dbunit/Extensions/Database/DataSet/YamlDataSet.php<��"qU<��®Êƒ¶������6���dbunit/Extensions/Database/DataSet/AbstractDataSet.phpÒ��"qUÒ��Ý„¿¶������,���dbunit/Extensions/Database/DataSet/ISpec.php²��"qU²��<Ñòê¶������2���dbunit/Extensions/Database/DataSet/TableFilter.php ��"qU ��}œŽ¶������<���dbunit/Extensions/Database/DataSet/AbstractTableMetaData.php��"qU��bà�¶������7���dbunit/Extensions/Database/DataSet/CompositeDataSet.php: ��"qU: ��¹°&c¶������;���dbunit/Extensions/Database/DataSet/DefaultTableIterator.phpÍ
  595. ��"qUÍ
  596. ��ŽÆoP¶������4���dbunit/Extensions/Database/DataSet/DataSetFilter.php?��"qU?��f9¶k¶������2���dbunit/Extensions/Database/DataSet/IYamlParser.php��"qU��f*¹¶������1���dbunit/Extensions/Database/DataSet/XmlDataSet.php²��"qU²��R�ç)¶������5���dbunit/Extensions/Database/DataSet/DefaultDataSet.phpÀ��"qUÀ��É¥|}¶������8���dbunit/Extensions/Database/DataSet/SymfonyYamlParser.php<��"qU<��hpúì¶������/���dbunit/Extensions/Database/DataSet/IDataSet.phpù��"qUù��¼)V@¶������5���dbunit/Extensions/Database/DataSet/ITableMetaData.phpa��"qUa��£+϶������:���dbunit/Extensions/Database/DataSet/Persistors/Abstract.php ��"qU ��.BEö������5���dbunit/Extensions/Database/DataSet/Persistors/Xml.php? ��"qU? ��}©¥)¶������9���dbunit/Extensions/Database/DataSet/Persistors/FlatXml.php“ ��"qU“ ��6gtæ¶������6���dbunit/Extensions/Database/DataSet/Persistors/Yaml.php��"qU��÷臨������:���dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.phpë��"qUë��=¹j¶������9���dbunit/Extensions/Database/DataSet/Persistors/Factory.phpÞ��"qUÞ��Ù°Å�¶������1���dbunit/Extensions/Database/DataSet/CsvDataSet.php��"qU�� b«¶������?���dbunit/Extensions/Database/DataSet/ReplacementTableIterator.php¹��"qU¹��‚ú·1¶������9���dbunit/Extensions/Database/DataSet/ReplacementDataSet.php‰ ��"qU‰ ��Á´à`¶������3���dbunit/Extensions/Database/DataSet/ArrayDataSet.phps ��"qUs ��L¹#¶������3���dbunit/Extensions/Database/DataSet/DefaultTable.php¯ ��"qU¯ ��È&íâ¶������5���dbunit/Extensions/Database/DataSet/ITableIterator.php3��"qU3��IÕ)ã¶������5���dbunit/Extensions/Database/DataSet/FlatXmlDataSet.php��"qU��ïëèJ¶������3���dbunit/Extensions/Database/DataSet/IPersistable.php½��"qU½��´)Š¶������9���dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.php� ��"qU� ��>ÞQª¶������:���dbunit/Extensions/Database/DataSet/TableMetaDataFilter.phpS��"qUS��íN4µ¶������7���dbunit/Extensions/Database/DataSet/ReplacementTable.php\��"qU\��—/ ¶������4���dbunit/Extensions/Database/DataSet/Specs/DbQuery.php
  597. ��"qU
  598. ��†@é¶������0���dbunit/Extensions/Database/DataSet/Specs/Xml.phpÓ��"qUÓ��þ�ýÙ¶������4���dbunit/Extensions/Database/DataSet/Specs/FlatXml.phpí��"qUí��{Éýt¶������1���dbunit/Extensions/Database/DataSet/Specs/Yaml.phpÙ��"qUÙ��b—"V¶������5���dbunit/Extensions/Database/DataSet/Specs/IFactory.phpz��"qUz��(r¼K¶������0���dbunit/Extensions/Database/DataSet/Specs/Csv.phpŠ ��"qUŠ ��–ÚSu¶������4���dbunit/Extensions/Database/DataSet/Specs/DbTable.php­ ��"qU­ ��/.¹É¶������4���dbunit/Extensions/Database/DataSet/Specs/Factory.phpè��"qUè��w_¸S¶������1���dbunit/Extensions/Database/DataSet/QueryTable.php-��"qU-��dqgƒ¶������4���dbunit/Extensions/Database/DataSet/AbstractTable.php€��"qU€��¾¦=ˆ¶������-���dbunit/Extensions/Database/DataSet/ITable.phpE��"qUE��Ë”À¶������;���dbunit/Extensions/Database/DataSet/DefaultTableMetaData.phpË��"qUË��˜âÒ˶���������php-invoker/Invoker.php&��"qU&��Š-顶������(���php-invoker/Invoker/TimeoutException.phpÕ ��"qUÕ ��•nŠ¶���������phpunit-mock-objects/LICENSE��"qU��C>©¶������5���phpunit-mock-objects/Framework/MockObject/Matcher.php"��"qU"��††Îá¶������8���phpunit-mock-objects/Framework/MockObject/Verifiable.php��"qU��l&¡¶������7���phpunit-mock-objects/Framework/MockObject/Invokable.php ��"qU ��^Ò¶������9���phpunit-mock-objects/Framework/MockObject/MockBuilder.php“��"qU“��Í(ض������A���phpunit-mock-objects/Framework/MockObject/Exception/Exception.phpà��"qUà��K5¶������N���phpunit-mock-objects/Framework/MockObject/Exception/BadMethodCallException.phpû��"qUû��P¿¶������H���phpunit-mock-objects/Framework/MockObject/Exception/RuntimeException.phpï��"qUï��êžõn¶������8���phpunit-mock-objects/Framework/MockObject/Invocation.phpñ��"qUñ��ªk`¶������8���phpunit-mock-objects/Framework/MockObject/MockObject.phpH��"qUH��ñB1ÿ¶������>���phpunit-mock-objects/Framework/MockObject/InvocationMocker.phpŽ��"qUŽ��OO¶������@���phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.php‡��"qU‡��ÊúUÔ¶������H���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.php4��"qU4���ˆû¶������C���phpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.phpª��"qUª��v X¶������@���phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.php÷��"qU÷��{ò4%¶������E���phpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.phpD��"qUD��êO¶������I���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastCount.phph��"qUh��m�k£¶������@���phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.phph ��"qUh ��?¿fj¶������K���phpunit-mock-objects/Framework/MockObject/Matcher/ConsecutiveParameters.php¦��"qU¦��¥\#Ƕ������D���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.phpƒ
  599. ��"qUƒ
  600. ��Gµ0Ô¶������B���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.php ��"qU ��pŸµ¶������H���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtMostCount.php]��"qU]��¿„€:¶������E���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.phpÎ��"qUÎ��t#vó¶������I���phpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.phpÏ ��"qUÏ ��âdÙ¶������7���phpunit-mock-objects/Framework/MockObject/Generator.phpD”��"qUD”��µ#7Ó¶������H���phpunit-mock-objects/Framework/MockObject/Generator/wsdl_method.tpl.dist<���"qU<���¾Ði‰¶������K���phpunit-mock-objects/Framework/MockObject/Generator/unmocked_clone.tpl.distŸ���"qUŸ���8W}ض������I���phpunit-mock-objects/Framework/MockObject/Generator/mocked_class.tpl.dist ��"qU ��¨ÑFZ¶������I���phpunit-mock-objects/Framework/MockObject/Generator/mocked_clone.tpl.dist„���"qU„���œaT¶������K���phpunit-mock-objects/Framework/MockObject/Generator/proxied_method.tpl.distÌ��"qUÌ��?a§¶������G���phpunit-mock-objects/Framework/MockObject/Generator/wsdl_class.tpl.dist³���"qU³���w&S¶������H���phpunit-mock-objects/Framework/MockObject/Generator/trait_class.tpl.dist7���"qU7���²[$~¶������J���phpunit-mock-objects/Framework/MockObject/Generator/mocked_method.tpl.dist„��"qU„��ãbVæ¶������P���phpunit-mock-objects/Framework/MockObject/Generator/mocked_class_method.tpl.distí���"qUí���Ú4Þ¶������Q���phpunit-mock-objects/Framework/MockObject/Generator/mocked_static_method.tpl.dist—���"qU—���+F°ƒ¶������;���phpunit-mock-objects/Framework/MockObject/Builder/Match.php»��"qU»��¨$Ķ������>���phpunit-mock-objects/Framework/MockObject/Builder/Identity.phpø��"qUø��ðMI3¶������F���phpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.phpÚ��"qUÚ��Z€‡1¶������E���phpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.phpd��"qUd��dä9A¶������?���phpunit-mock-objects/Framework/MockObject/Builder/Namespace.php��"qU��Ú14-¶������E���phpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.php���"qU���¤ß¹Ž¶������:���phpunit-mock-objects/Framework/MockObject/Builder/Stub.phpÓ��"qUÓ��¿ã{ ¶������?���phpunit-mock-objects/Framework/MockObject/Invocation/Object.php��"qU��Qð¶������?���phpunit-mock-objects/Framework/MockObject/Invocation/Static.php˜��"qU˜��zÎé¶������2���phpunit-mock-objects/Framework/MockObject/Stub.phpÀ��"qUÀ��àúŒ¶������<���phpunit-mock-objects/Framework/MockObject/Stub/Exception.php%��"qU%��9¦u3¶������9���phpunit-mock-objects/Framework/MockObject/Stub/Return.phpÃ��"qUÃ��Oä϶������=���phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.php_��"qU_��ÌUÐý¶������A���phpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.phpå��"qUå��^ÂØá¶������C���phpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.phpâ��"qUâ��¬;Ä׶������D���phpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.phpž��"qUž��Ô&d¶������A���phpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.phpÿ��"qUÿ��\Š_á¶������A���phpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.phph��"qUh��ƶŒW¶���������phpunit/Exception.php”��"qU”���ü†¶���������phpunit/Framework/Test.php¯��"qU¯��òiKF¶���������phpunit/Framework/Exception.phpF
  601. ��"qUF
  602. ��±Ò¬¶������!���phpunit/Framework/OutputError.php ��"qU ��Ž'þg¶���������phpunit/Framework/Assert.php9‡�"qU9‡�þµ�$¶������+���phpunit/Framework/CodeCoverageException.php—��"qU—��3Í�¶���������phpunit/Framework/TestSuite.php‹v��"qU‹v��h|¢9¶���������phpunit/Framework/RiskyTest.phpÏ��"qUÏ��Ê,yd¶������$���phpunit/Framework/SelfDescribing.php<��"qU<��Äb“ݶ������&���phpunit/Framework/Assert/Functions.php û��"qU û��Ž]¦
  603. ¶������$���phpunit/Framework/SyntheticError.phpA��"qUA��@]öæ¶������$���phpunit/Framework/RiskyTestError.php)��"qU)��<˜D»¶������"���phpunit/Framework/TestListener.phps ��"qUs ��ý@S¶������&���phpunit/Framework/ExceptionWrapper.phpˆ ��"qUˆ ��žø¶¶������!���phpunit/Framework/SkippedTest.php´��"qU´��!÷BŸ¶������2���phpunit/Framework/InvalidCoversTargetException.phpª��"qUª��ú}Äζ���������phpunit/Framework/TestCase.php‰÷��"qU‰÷��O;@¶������0���phpunit/Framework/ExpectationFailedException.php¿��"qU¿��⊙Ÿ¶���������phpunit/Framework/Error.phpJ��"qUJ��ðÛPá¶������ ���phpunit/Framework/Constraint.php…��"qU…��âñc¶������*���phpunit/Framework/AssertionFailedError.php¡��"qU¡��zì&ÿ¶������(���phpunit/Framework/IncompleteTestCase.phpb��"qUb��e{ªÿ¶������,���phpunit/Framework/TestSuite/DataProvider.php¹��"qU¹��
  604. Š2¶������&���phpunit/Framework/Error/Deprecated.phpr��"qUr��%Ç»¶������"���phpunit/Framework/Error/Notice.php\��"qU\��”ä¶������#���phpunit/Framework/Error/Warning.php_��"qU_�� ‰÷'¶������)���phpunit/Framework/IncompleteTestError.php9��"qU9��˜eõ¶������.���phpunit/Framework/InvalidCoversTargetError.phph��"qUh��6R›ª¶������+���phpunit/Framework/SkippedTestSuiteError.php:��"qU:��“4i®¶������ ���phpunit/Framework/TestResult.phpQo��"qUQo��{„��¶������!���phpunit/Framework/TestFailure.php,��"qU,��ÅD0S¶������$���phpunit/Framework/IncompleteTest.php��"qU��±Êûp¶������%���phpunit/Framework/SkippedTestCase.php��"qU��ŒÂW¶������2���phpunit/Framework/Constraint/ClassHasAttribute.php& ��"qU& ��‡H¾‘¶������4���phpunit/Framework/Constraint/TraversableContains.phpR��"qUR��áDì¶������.���phpunit/Framework/Constraint/ExceptionCode.php’��"qU’��HK}¶������*���phpunit/Framework/Constraint/Exception.php� ��"qU� ��à¼í€¶������)���phpunit/Framework/Constraint/SameSize.phpÏ��"qUÏ��ýonp¶������,���phpunit/Framework/Constraint/JsonMatches.php>��"qU>��t r¶������-���phpunit/Framework/Constraint/IsInstanceOf.php!
  605. ��"qU!
  606. ��Y?›¤¶������3���phpunit/Framework/Constraint/ObjectHasAttribute.php��"qU��p½´Ç¶������'���phpunit/Framework/Constraint/IsType.phpX��"qUX��ƒ¢M¤¶������)���phpunit/Framework/Constraint/LessThan.php&��"qU&��> ÀJ¶������,���phpunit/Framework/Constraint/ArraySubset.phpm ��"qUm ��¼çÇ…¶������'���phpunit/Framework/Constraint/IsTrue.phpÙ��"qUÙ��D�¿˜¶������'���phpunit/Framework/Constraint/IsJson.php½��"qU½��â+¹¶������(���phpunit/Framework/Constraint/IsEqual.php”��"qU”�� Kôì¶������$���phpunit/Framework/Constraint/Xor.php¨ ��"qU¨ ��²½B¶������A���phpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.phpÈ��"qUÈ��|q"ž¶������.���phpunit/Framework/Constraint/StringMatches.php�
  607. ��"qU�
  608. ��c¶������$���phpunit/Framework/Constraint/Not.phpÖ��"qUÖ��ÃO|Ѷ������7���phpunit/Framework/Constraint/ExceptionMessageRegExp.php���"qU���–vøö¶������,���phpunit/Framework/Constraint/GreaterThan.php/��"qU/��“,Ð߶������1���phpunit/Framework/Constraint/ExceptionMessage.phpv��"qUv��zÞ§¶������)���phpunit/Framework/Constraint/Callback.php•��"qU•��
  609. ø'“¶������,���phpunit/Framework/Constraint/ArrayHasKey.php# ��"qU# ��q{E¶������/���phpunit/Framework/Constraint/StringContains.phpŸ��"qUŸ��žÞ=Ŷ������8���phpunit/Framework/Constraint/TraversableContainsOnly.php„ ��"qU„ ��â¼gt¶������(���phpunit/Framework/Constraint/IsEmpty.php‰��"qU‰��O–ñѶ������*���phpunit/Framework/Constraint/PCREMatch.php%��"qU%��1ü휶������'���phpunit/Framework/Constraint/IsNull.phpÙ��"qUÙ��˜ÿ_=¶������*���phpunit/Framework/Constraint/Attribute.phpj ��"qUj ��A=qĶ������(���phpunit/Framework/Constraint/IsFalse.phpÝ��"qUÝ��Ó¢i‘¶������8���phpunit/Framework/Constraint/ClassHasStaticAttribute.phpå��"qUå��óæ‰B¶������#���phpunit/Framework/Constraint/Or.php5 ��"qU5 ��ÅΧ¼¶������,���phpunit/Framework/Constraint/IsIdentical.php¥��"qU¥���Ú&¶������+���phpunit/Framework/Constraint/FileExists.php��"qU��€Áf¶������*���phpunit/Framework/Constraint/Composite.php� ��"qU� ��k°Ù¶������1���phpunit/Framework/Constraint/StringStartsWith.php.��"qU.��ÆV—'¶������/���phpunit/Framework/Constraint/StringEndsWith.php?��"qU?��l6¼¶������+���phpunit/Framework/Constraint/IsAnything.phpB��"qUB��áë¼E¶������&���phpunit/Framework/Constraint/Count.phpX ��"qUX ��'m¯ý¶������$���phpunit/Framework/Constraint/And.phpÿ ��"qUÿ ��ƒ\�)¶������&���phpunit/Framework/BaseTestListener.php“��"qU“��.ØŠ¶������&���phpunit/Framework/SkippedTestError.php/��"qU/��¨§—þ¶������5���phpunit/Framework/UnintentionallyCoveredCodeError.php-��"qU-��ó‹Ù±¶���������phpunit/Framework/Warning.phpå��"qUå��7£þ¶������%���phpunit/Extensions/GroupTestSuite.php«��"qU«��Pz¦¶������$���phpunit/Extensions/PhptTestSuite.phpL��"qUL��XgPp¶������#���phpunit/Extensions/RepeatedTest.phpÞ
  610. ��"qUÞ
  611. ��Ò®¸®¶������%���phpunit/Extensions/TicketListener.php—��"qU—��Š“Bó¶������$���phpunit/Extensions/TestDecorator.phph
  612. ��"qUh
  613. ��Ϻ‰W¶������#���phpunit/Extensions/PhptTestCase.phpó��"qUó��2ðiª¶���������phpunit/TextUI/Command.php{��"qU{��|÷¶���������phpunit/TextUI/TestRunner.phpNŸ��"qUNŸ�� Aø�¶������ ���phpunit/TextUI/ResultPrinter.php<E��"qU<E��,j:Û¶���������phpunit/Util/Test.php<{��"qU<{��´ÂK™¶���������phpunit/Util/Filesystem.phpª��"qUª��£•a¶���������phpunit/Util/Getopt.php'��"qU'��¿ºû�¶���������phpunit/Util/ErrorHandler.php&��"qU&��Û[Ð!¶���������phpunit/Util/String.php˜��"qU˜��µl"߶������&���phpunit/Util/InvalidArgumentHelper.php¯��"qU¯��µ©¶���������phpunit/Util/Printer.php”��"qU”��{…Z¶���������phpunit/Util/Configuration.phpê‰��"qUê‰��`à€¶���������phpunit/Util/GlobalState.phpU��"qUU��}¼RL¶���������phpunit/Util/Log/JSON.phpï��"qUï��f'ª—¶���������phpunit/Util/Log/TAP.php
  614. ��"qU
  615. ��ì�„¶���������phpunit/Util/Log/JUnit.phpð5��"qUð5��F¤ÃJ¶���������phpunit/Util/Blacklist.phpÌ ��"qUÌ ��Ê脶������"���phpunit/Util/TestSuiteIterator.phpX ��"qUX ��÷8¤Ä¶���������phpunit/Util/Filter.phpò ��"qUò ��B¼}ƒ¶������+���phpunit/Util/TestDox/ResultPrinter/HTML.phpé��"qUé��+ =¶������+���phpunit/Util/TestDox/ResultPrinter/Text.php¢��"qU¢��IVz¶������&���phpunit/Util/TestDox/ResultPrinter.php§ ��"qU§ ��úO³¸¶������'���phpunit/Util/TestDox/NamePrettifier.phpw ��"qUw ��¸$™|¶���������phpunit/Util/Regex.phpó��"qUó��=g¾¥¶���������phpunit/Util/Type.php)��"qU)��_ûž¶���������phpunit/Util/PHP/Default.phpè��"qUè��Zµoþ¶������1���phpunit/Util/PHP/Template/TestCaseMethod.tpl.dist6��"qU6��+}ÕV¶���������phpunit/Util/PHP/Windows.php™ ��"qU™ ��^¤ñ¶���������phpunit/Util/Fileloader.phpþ��"qUþ��˜NÅ϶���������phpunit/Util/XML.phpñw��"qUñw��»Ê[•¶���������phpunit/Util/PHP.phpá��"qUá��0¸KÚ¶���������phpunit/Runner/Exception.php—��"qU—��Íl £¶���������phpunit/Runner/Filter/Test.php1 ��"qU1 ��{4:s¶������'���phpunit/Runner/Filter/Group/Exclude.php��"qU��øÎY¾¶������'���phpunit/Runner/Filter/Group/Include.php��"qU��‹p»t¶������!���phpunit/Runner/Filter/Factory.phpõ��"qUõ��©‰¢ß¶���������phpunit/Runner/Filter/Group.php&��"qU&��ÐõÓŠ¶������"���phpunit/Runner/TestSuiteLoader.php ��"qU ��5 b¶������!���phpunit/Runner/BaseTestRunner.php½��"qU½��_DZ{¶������*���phpunit/Runner/StandardTestSuiteLoader.php��"qU���îP¶���������phpunit/Runner/Version.phpÍ��"qUÍ��T"¯¶���������sebastian-environment/LICENSE
  616. ��"qU
  617. ��¶îá߶������!���sebastian-environment/Runtime.phpÄ��"qUÄ�� ¹º¶������!���sebastian-environment/Console.php©��"qU©��qí*¶������)���phpdocumentor-reflection-docblock/LICENSE8��"qU8��á‰Ê¶������G���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock.phpc6��"qUc6��õËq¶������P���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Location.phpq��"qUq��uÁ/¶������T���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SinceTag.php|��"qU|��tøûR¶������R���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SeeTag.phpÿ��"qUÿ��ià?$¶������V���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/VersionTag.phpx
  618. ��"qUx
  619. ��ÓËEƶ������W���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyTag.phpO��"qUO��«Î#m¶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ReturnTag.phpÙ��"qUÙ��pS�ž¶������Y���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTag.php†��"qU†��K § ¶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTag.phpL��"qUL��œ"â¶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/CoversTag.phpI��"qUI��9¹{¶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SourceTag.php� ��"qU� ��äÙn*¶������S���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/UsesTag.phpE��"qUE��.�„˶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/MethodTag.php~��"qU~��å!kͶ������[���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyReadTag.php[��"qU[��Í< =¶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/AuthorTag.phpM ��"qUM ��1ôú¶������R���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/VarTag.phpE��"qUE��ƒ•üͶ������S���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/LinkTag.phpL��"qUL���ªF¶������V���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ExampleTag.php™��"qU™�� £
  620. ï¶������T���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ParamTag.phpH ��"qUH ��±ñ ¶������\���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyWriteTag.php]��"qU]��Rp¶������R���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Serializer.php��"qU��òrж������O���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Context.php5��"qU5��l.%¶������W���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Type/Collection.php���"qU���+=4¶������K���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag.phpÛ(��"qUÛ(��ŒE6 ¶������S���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Description.php—��"qU—��ñԲض���������sebastian-version/LICENSE��"qU��n¶���������sebastian-version/Version.phpH��"qUH��ÿê'¶������<?php
  621. /**
  622. * GlobalState
  623. *
  624. * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  625. * All rights reserved.
  626. *
  627. * Redistribution and use in source and binary forms, with or without
  628. * modification, are permitted provided that the following conditions
  629. * are met:
  630. *
  631. * * Redistributions of source code must retain the above copyright
  632. * notice, this list of conditions and the following disclaimer.
  633. *
  634. * * Redistributions in binary form must reproduce the above copyright
  635. * notice, this list of conditions and the following disclaimer in
  636. * the documentation and/or other materials provided with the
  637. * distribution.
  638. *
  639. * * Neither the name of Sebastian Bergmann nor the names of his
  640. * contributors may be used to endorse or promote products derived
  641. * from this software without specific prior written permission.
  642. *
  643. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  644. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  645. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  646. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  647. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  648. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  649. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  650. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  651. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  652. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  653. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  654. * POSSIBILITY OF SUCH DAMAGE.
  655. *
  656. * @author Sebastian Bergmann <sebastian@phpunit.de>
  657. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  658. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  659. * @link http://www.github.com/sebastianbergmann/global-state
  660. */
  661. namespace SebastianBergmann\GlobalState;
  662. /**
  663. * @author Sebastian Bergmann <sebastian@phpunit.de>
  664. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  665. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  666. * @link http://www.github.com/sebastianbergmann/global-state
  667. */
  668. interface Exception
  669. {
  670. }
  671. <?php
  672. /**
  673. * GlobalState
  674. *
  675. * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  676. * All rights reserved.
  677. *
  678. * Redistribution and use in source and binary forms, with or without
  679. * modification, are permitted provided that the following conditions
  680. * are met:
  681. *
  682. * * Redistributions of source code must retain the above copyright
  683. * notice, this list of conditions and the following disclaimer.
  684. *
  685. * * Redistributions in binary form must reproduce the above copyright
  686. * notice, this list of conditions and the following disclaimer in
  687. * the documentation and/or other materials provided with the
  688. * distribution.
  689. *
  690. * * Neither the name of Sebastian Bergmann nor the names of his
  691. * contributors may be used to endorse or promote products derived
  692. * from this software without specific prior written permission.
  693. *
  694. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  695. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  696. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  697. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  698. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  699. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  700. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  701. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  702. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  703. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  704. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  705. * POSSIBILITY OF SUCH DAMAGE.
  706. *
  707. * @author Sebastian Bergmann <sebastian@phpunit.de>
  708. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  709. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  710. * @link http://www.github.com/sebastianbergmann/global-state
  711. */
  712. namespace SebastianBergmann\GlobalState;
  713. use Closure;
  714. use ReflectionClass;
  715. /**
  716. * A snapshot of global state.
  717. *
  718. * @author Sebastian Bergmann <sebastian@phpunit.de>
  719. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  720. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  721. * @link http://www.github.com/sebastianbergmann/global-state
  722. */
  723. class Snapshot
  724. {
  725. /**
  726. * @var Blacklist
  727. */
  728. private $blacklist;
  729. /**
  730. * @var array
  731. */
  732. private $globalVariables = array();
  733. /**
  734. * @var array
  735. */
  736. private $superGlobalArrays = array();
  737. /**
  738. * @var array
  739. */
  740. private $superGlobalVariables = array();
  741. /**
  742. * @var array
  743. */
  744. private $staticAttributes = array();
  745. /**
  746. * @var array
  747. */
  748. private $iniSettings = array();
  749. /**
  750. * @var array
  751. */
  752. private $includedFiles = array();
  753. /**
  754. * @var array
  755. */
  756. private $constants = array();
  757. /**
  758. * @var array
  759. */
  760. private $functions = array();
  761. /**
  762. * @var array
  763. */
  764. private $interfaces = array();
  765. /**
  766. * @var array
  767. */
  768. private $classes = array();
  769. /**
  770. * @var array
  771. */
  772. private $traits = array();
  773. /**
  774. * Creates a snapshot of the current global state.
  775. *
  776. * @param Blacklist $blacklist
  777. * @param boolean $includeGlobalVariables
  778. * @param boolean $includeStaticAttributes
  779. * @param boolean $includeConstants
  780. * @param boolean $includeFunctions
  781. * @param boolean $includeClasses
  782. * @param boolean $includeInterfaces
  783. * @param boolean $includeTraits
  784. * @param boolean $includeIniSettings
  785. * @param boolean $includeIncludedFiles
  786. */
  787. public function __construct(Blacklist $blacklist = null, $includeGlobalVariables = true, $includeStaticAttributes = true, $includeConstants = true, $includeFunctions = true, $includeClasses = true, $includeInterfaces = true, $includeTraits = true, $includeIniSettings = true, $includeIncludedFiles = true)
  788. {
  789. if ($blacklist === null) {
  790. $blacklist = new Blacklist;
  791. }
  792. $this->blacklist = $blacklist;
  793. if ($includeConstants) {
  794. $this->snapshotConstants();
  795. }
  796. if ($includeFunctions) {
  797. $this->snapshotFunctions();
  798. }
  799. if ($includeClasses || $includeStaticAttributes) {
  800. $this->snapshotClasses();
  801. }
  802. if ($includeInterfaces) {
  803. $this->snapshotInterfaces();
  804. }
  805. if ($includeGlobalVariables) {
  806. $this->setupSuperGlobalArrays();
  807. $this->snapshotGlobals();
  808. }
  809. if ($includeStaticAttributes) {
  810. $this->snapshotStaticAttributes();
  811. }
  812. if ($includeIniSettings) {
  813. $this->iniSettings = ini_get_all(null, false);
  814. }
  815. if ($includeIncludedFiles) {
  816. $this->includedFiles = get_included_files();
  817. }
  818. if (function_exists('get_declared_traits')) {
  819. $this->traits = get_declared_traits();
  820. }
  821. }
  822. /**
  823. * @return Blacklist
  824. */
  825. public function blacklist()
  826. {
  827. return $this->blacklist;
  828. }
  829. /**
  830. * @return array
  831. */
  832. public function globalVariables()
  833. {
  834. return $this->globalVariables;
  835. }
  836. /**
  837. * @return array
  838. */
  839. public function superGlobalVariables()
  840. {
  841. return $this->superGlobalVariables;
  842. }
  843. /**
  844. * Returns a list of all super-global variable arrays.
  845. *
  846. * @return array
  847. */
  848. public function superGlobalArrays()
  849. {
  850. return $this->superGlobalArrays;
  851. }
  852. /**
  853. * @return array
  854. */
  855. public function staticAttributes()
  856. {
  857. return $this->staticAttributes;
  858. }
  859. /**
  860. * @return array
  861. */
  862. public function iniSettings()
  863. {
  864. return $this->iniSettings;
  865. }
  866. /**
  867. * @return array
  868. */
  869. public function includedFiles()
  870. {
  871. return $this->includedFiles;
  872. }
  873. /**
  874. * @return array
  875. */
  876. public function constants()
  877. {
  878. return $this->constants;
  879. }
  880. /**
  881. * @return array
  882. */
  883. public function functions()
  884. {
  885. return $this->functions;
  886. }
  887. /**
  888. * @return array
  889. */
  890. public function interfaces()
  891. {
  892. return $this->interfaces;
  893. }
  894. /**
  895. * @return array
  896. */
  897. public function classes()
  898. {
  899. return $this->classes;
  900. }
  901. /**
  902. * @return array
  903. */
  904. public function traits()
  905. {
  906. return $this->traits;
  907. }
  908. /**
  909. * Creates a snapshot user-defined constants.
  910. */
  911. private function snapshotConstants()
  912. {
  913. $constants = get_defined_constants(true);
  914. if (isset($constants['user'])) {
  915. $this->constants = $constants['user'];
  916. }
  917. }
  918. /**
  919. * Creates a snapshot user-defined functions.
  920. */
  921. private function snapshotFunctions()
  922. {
  923. $functions = get_defined_functions();
  924. $this->functions = $functions['user'];
  925. }
  926. /**
  927. * Creates a snapshot user-defined classes.
  928. */
  929. private function snapshotClasses()
  930. {
  931. foreach (array_reverse(get_declared_classes()) as $className) {
  932. $class = new ReflectionClass($className);
  933. if (!$class->isUserDefined()) {
  934. break;
  935. }
  936. $this->classes[] = $className;
  937. }
  938. $this->classes = array_reverse($this->classes);
  939. }
  940. /**
  941. * Creates a snapshot user-defined interfaces.
  942. */
  943. private function snapshotInterfaces()
  944. {
  945. foreach (array_reverse(get_declared_interfaces()) as $interfaceName) {
  946. $class = new ReflectionClass($interfaceName);
  947. if (!$class->isUserDefined()) {
  948. break;
  949. }
  950. $this->interfaces[] = $interfaceName;
  951. }
  952. $this->interfaces = array_reverse($this->interfaces);
  953. }
  954. /**
  955. * Creates a snapshot of all global and super-global variables.
  956. */
  957. private function snapshotGlobals()
  958. {
  959. $superGlobalArrays = $this->superGlobalArrays();
  960. foreach ($superGlobalArrays as $superGlobalArray) {
  961. $this->snapshotSuperGlobalArray($superGlobalArray);
  962. }
  963. foreach (array_keys($GLOBALS) as $key) {
  964. if ($key != 'GLOBALS' &&
  965. !in_array($key, $superGlobalArrays) &&
  966. $this->canBeSerialized($GLOBALS[$key]) &&
  967. !$this->blacklist->isGlobalVariableBlacklisted($key)) {
  968. $this->globalVariables[$key] = unserialize(serialize($GLOBALS[$key]));
  969. }
  970. }
  971. }
  972. /**
  973. * Creates a snapshot a super-global variable array.
  974. *
  975. * @param $superGlobalArray
  976. */
  977. private function snapshotSuperGlobalArray($superGlobalArray)
  978. {
  979. $this->superGlobalVariables[$superGlobalArray] = array();
  980. if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
  981. foreach ($GLOBALS[$superGlobalArray] as $key => $value) {
  982. $this->superGlobalVariables[$superGlobalArray][$key] = unserialize(serialize($value));
  983. }
  984. }
  985. }
  986. /**
  987. * Creates a snapshot of all static attributes in user-defined classes.
  988. */
  989. private function snapshotStaticAttributes()
  990. {
  991. foreach ($this->classes as $className) {
  992. $class = new ReflectionClass($className);
  993. $snapshot = array();
  994. foreach ($class->getProperties() as $attribute) {
  995. if ($attribute->isStatic()) {
  996. $name = $attribute->getName();
  997. if ($this->blacklist->isStaticAttributeBlacklisted($className, $name)) {
  998. continue;
  999. }
  1000. $attribute->setAccessible(true);
  1001. $value = $attribute->getValue();
  1002. if ($this->canBeSerialized($value)) {
  1003. $snapshot[$name] = unserialize(serialize($value));
  1004. }
  1005. }
  1006. }
  1007. if (!empty($snapshot)) {
  1008. $this->staticAttributes[$className] = $snapshot;
  1009. }
  1010. }
  1011. }
  1012. /**
  1013. * Returns a list of all super-global variable arrays.
  1014. *
  1015. * @return array
  1016. */
  1017. private function setupSuperGlobalArrays()
  1018. {
  1019. $this->superGlobalArrays = array(
  1020. '_ENV',
  1021. '_POST',
  1022. '_GET',
  1023. '_COOKIE',
  1024. '_SERVER',
  1025. '_FILES',
  1026. '_REQUEST'
  1027. );
  1028. if (ini_get('register_long_arrays') == '1') {
  1029. $this->superGlobalArrays = array_merge(
  1030. $this->superGlobalArrays,
  1031. array(
  1032. 'HTTP_ENV_VARS',
  1033. 'HTTP_POST_VARS',
  1034. 'HTTP_GET_VARS',
  1035. 'HTTP_COOKIE_VARS',
  1036. 'HTTP_SERVER_VARS',
  1037. 'HTTP_POST_FILES'
  1038. )
  1039. );
  1040. }
  1041. }
  1042. /**
  1043. * @param mixed $variable
  1044. * @return boolean
  1045. * @todo Implement this properly
  1046. */
  1047. private function canBeSerialized($variable) {
  1048. return !$variable instanceof Closure;
  1049. }
  1050. }
  1051. GlobalState
  1052. Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  1053. All rights reserved.
  1054. Redistribution and use in source and binary forms, with or without
  1055. modification, are permitted provided that the following conditions
  1056. are met:
  1057. * Redistributions of source code must retain the above copyright
  1058. notice, this list of conditions and the following disclaimer.
  1059. * Redistributions in binary form must reproduce the above copyright
  1060. notice, this list of conditions and the following disclaimer in
  1061. the documentation and/or other materials provided with the
  1062. distribution.
  1063. * Neither the name of Sebastian Bergmann nor the names of his
  1064. contributors may be used to endorse or promote products derived
  1065. from this software without specific prior written permission.
  1066. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1067. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1068. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1069. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1070. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1071. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1072. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1073. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1074. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1075. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1076. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1077. POSSIBILITY OF SUCH DAMAGE.
  1078. <?php
  1079. /**
  1080. * GlobalState
  1081. *
  1082. * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  1083. * All rights reserved.
  1084. *
  1085. * Redistribution and use in source and binary forms, with or without
  1086. * modification, are permitted provided that the following conditions
  1087. * are met:
  1088. *
  1089. * * Redistributions of source code must retain the above copyright
  1090. * notice, this list of conditions and the following disclaimer.
  1091. *
  1092. * * Redistributions in binary form must reproduce the above copyright
  1093. * notice, this list of conditions and the following disclaimer in
  1094. * the documentation and/or other materials provided with the
  1095. * distribution.
  1096. *
  1097. * * Neither the name of Sebastian Bergmann nor the names of his
  1098. * contributors may be used to endorse or promote products derived
  1099. * from this software without specific prior written permission.
  1100. *
  1101. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1102. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1103. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1104. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1105. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1106. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1107. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1108. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1109. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1110. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1111. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1112. * POSSIBILITY OF SUCH DAMAGE.
  1113. *
  1114. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1115. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1116. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1117. * @link http://www.github.com/sebastianbergmann/global-state
  1118. */
  1119. namespace SebastianBergmann\GlobalState;
  1120. use ReflectionProperty;
  1121. /**
  1122. * Restorer of snapshots of global state.
  1123. *
  1124. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1125. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1126. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1127. * @link http://www.github.com/sebastianbergmann/global-state
  1128. */
  1129. class Restorer
  1130. {
  1131. /**
  1132. * Deletes function definitions that are not defined in a snapshot.
  1133. *
  1134. * @param Snapshot $snapshot
  1135. * @throws RuntimeException when the uopz_delete() function is not available
  1136. * @see https://github.com/krakjoe/uopz
  1137. */
  1138. public function restoreFunctions(Snapshot $snapshot)
  1139. {
  1140. if (!function_exists('uopz_delete')) {
  1141. throw new RuntimeException('The uopz_delete() function is required for this operation');
  1142. }
  1143. $functions = get_defined_functions();
  1144. foreach (array_diff($functions['user'], $snapshot->functions()) as $function) {
  1145. uopz_delete($function);
  1146. }
  1147. }
  1148. /**
  1149. * Restores all global and super-global variables from a snapshot.
  1150. *
  1151. * @param Snapshot $snapshot
  1152. */
  1153. public function restoreGlobalVariables(Snapshot $snapshot)
  1154. {
  1155. $superGlobalArrays = $snapshot->superGlobalArrays();
  1156. foreach ($superGlobalArrays as $superGlobalArray) {
  1157. $this->restoreSuperGlobalArray($snapshot, $superGlobalArray);
  1158. }
  1159. $globalVariables = $snapshot->globalVariables();
  1160. foreach (array_keys($GLOBALS) as $key) {
  1161. if ($key != 'GLOBALS' &&
  1162. !in_array($key, $superGlobalArrays) &&
  1163. !$snapshot->blacklist()->isGlobalVariableBlacklisted($key)) {
  1164. if (isset($globalVariables[$key])) {
  1165. $GLOBALS[$key] = $globalVariables[$key];
  1166. } else {
  1167. unset($GLOBALS[$key]);
  1168. }
  1169. }
  1170. }
  1171. }
  1172. /**
  1173. * Restores all static attributes in user-defined classes from this snapshot.
  1174. *
  1175. * @param Snapshot $snapshot
  1176. */
  1177. public function restoreStaticAttributes(Snapshot $snapshot)
  1178. {
  1179. foreach ($snapshot->staticAttributes() as $className => $staticAttributes) {
  1180. foreach ($staticAttributes as $name => $value) {
  1181. $reflector = new ReflectionProperty($className, $name);
  1182. $reflector->setAccessible(true);
  1183. $reflector->setValue($value);
  1184. }
  1185. }
  1186. }
  1187. /**
  1188. * Restores a super-global variable array from this snapshot.
  1189. *
  1190. * @param Snapshot $snapshot
  1191. * @param $superGlobalArray
  1192. */
  1193. private function restoreSuperGlobalArray(Snapshot $snapshot, $superGlobalArray)
  1194. {
  1195. $superGlobalVariables = $snapshot->superGlobalVariables();
  1196. if (isset($GLOBALS[$superGlobalArray]) &&
  1197. is_array($GLOBALS[$superGlobalArray]) &&
  1198. isset($superGlobalVariables[$superGlobalArray])) {
  1199. $keys = array_keys(
  1200. array_merge(
  1201. $GLOBALS[$superGlobalArray],
  1202. $superGlobalVariables[$superGlobalArray]
  1203. )
  1204. );
  1205. foreach ($keys as $key) {
  1206. if (isset($superGlobalVariables[$superGlobalArray][$key])) {
  1207. $GLOBALS[$superGlobalArray][$key] = $superGlobalVariables[$superGlobalArray][$key];
  1208. } else {
  1209. unset($GLOBALS[$superGlobalArray][$key]);
  1210. }
  1211. }
  1212. }
  1213. }
  1214. }
  1215. <?php
  1216. /**
  1217. * GlobalState
  1218. *
  1219. * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  1220. * All rights reserved.
  1221. *
  1222. * Redistribution and use in source and binary forms, with or without
  1223. * modification, are permitted provided that the following conditions
  1224. * are met:
  1225. *
  1226. * * Redistributions of source code must retain the above copyright
  1227. * notice, this list of conditions and the following disclaimer.
  1228. *
  1229. * * Redistributions in binary form must reproduce the above copyright
  1230. * notice, this list of conditions and the following disclaimer in
  1231. * the documentation and/or other materials provided with the
  1232. * distribution.
  1233. *
  1234. * * Neither the name of Sebastian Bergmann nor the names of his
  1235. * contributors may be used to endorse or promote products derived
  1236. * from this software without specific prior written permission.
  1237. *
  1238. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1239. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1240. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1241. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1242. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1243. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1244. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1245. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1246. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1247. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1248. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1249. * POSSIBILITY OF SUCH DAMAGE.
  1250. *
  1251. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1252. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1253. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1254. * @link http://www.github.com/sebastianbergmann/global-state
  1255. */
  1256. namespace SebastianBergmann\GlobalState;
  1257. use ReflectionClass;
  1258. /**
  1259. * A blacklist for global state elements that should not be snapshotted.
  1260. *
  1261. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1262. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1263. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1264. * @link http://www.github.com/sebastianbergmann/global-state
  1265. */
  1266. class Blacklist
  1267. {
  1268. /**
  1269. * @var array
  1270. */
  1271. private $globalVariables = array();
  1272. /**
  1273. * @var array
  1274. */
  1275. private $classes = array();
  1276. /**
  1277. * @var array
  1278. */
  1279. private $classNamePrefixes = array();
  1280. /**
  1281. * @var array
  1282. */
  1283. private $parentClasses = array();
  1284. /**
  1285. * @var array
  1286. */
  1287. private $interfaces = array();
  1288. /**
  1289. * @var array
  1290. */
  1291. private $staticAttributes = array();
  1292. /**
  1293. * @param string $variableName
  1294. */
  1295. public function addGlobalVariable($variableName)
  1296. {
  1297. $this->globalVariables[$variableName] = true;
  1298. }
  1299. /**
  1300. * @param string $className
  1301. */
  1302. public function addClass($className)
  1303. {
  1304. $this->classes[] = $className;
  1305. }
  1306. /**
  1307. * @param string $className
  1308. */
  1309. public function addSubclassesOf($className)
  1310. {
  1311. $this->parentClasses[] = $className;
  1312. }
  1313. /**
  1314. * @param string $interfaceName
  1315. */
  1316. public function addImplementorsOf($interfaceName)
  1317. {
  1318. $this->interfaces[] = $interfaceName;
  1319. }
  1320. /**
  1321. * @param string $classNamePrefix
  1322. */
  1323. public function addClassNamePrefix($classNamePrefix)
  1324. {
  1325. $this->classNamePrefixes[] = $classNamePrefix;
  1326. }
  1327. /**
  1328. * @param string $className
  1329. * @param string $attributeName
  1330. */
  1331. public function addStaticAttribute($className, $attributeName)
  1332. {
  1333. if (!isset($this->staticAttributes[$className])) {
  1334. $this->staticAttributes[$className] = array();
  1335. }
  1336. $this->staticAttributes[$className][$attributeName] = true;
  1337. }
  1338. /**
  1339. * @param string $variableName
  1340. * @return boolean
  1341. */
  1342. public function isGlobalVariableBlacklisted($variableName)
  1343. {
  1344. return isset($this->globalVariables[$variableName]);
  1345. }
  1346. /**
  1347. * @param string $className
  1348. * @param string $attributeName
  1349. * @return boolean
  1350. */
  1351. public function isStaticAttributeBlacklisted($className, $attributeName)
  1352. {
  1353. if (in_array($className, $this->classes)) {
  1354. return true;
  1355. }
  1356. foreach ($this->classNamePrefixes as $prefix) {
  1357. if (strpos($className, $prefix) === 0) {
  1358. return true;
  1359. }
  1360. }
  1361. $class = new ReflectionClass($className);
  1362. foreach ($this->parentClasses as $type) {
  1363. if ($class->isSubclassOf($type)) {
  1364. return true;
  1365. }
  1366. }
  1367. foreach ($this->interfaces as $type) {
  1368. if ($class->implementsInterface($type)) {
  1369. return true;
  1370. }
  1371. }
  1372. if (isset($this->staticAttributes[$className][$attributeName])) {
  1373. return true;
  1374. }
  1375. return false;
  1376. }
  1377. }
  1378. <?php
  1379. /**
  1380. * GlobalState
  1381. *
  1382. * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  1383. * All rights reserved.
  1384. *
  1385. * Redistribution and use in source and binary forms, with or without
  1386. * modification, are permitted provided that the following conditions
  1387. * are met:
  1388. *
  1389. * * Redistributions of source code must retain the above copyright
  1390. * notice, this list of conditions and the following disclaimer.
  1391. *
  1392. * * Redistributions in binary form must reproduce the above copyright
  1393. * notice, this list of conditions and the following disclaimer in
  1394. * the documentation and/or other materials provided with the
  1395. * distribution.
  1396. *
  1397. * * Neither the name of Sebastian Bergmann nor the names of his
  1398. * contributors may be used to endorse or promote products derived
  1399. * from this software without specific prior written permission.
  1400. *
  1401. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1402. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1403. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1404. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1405. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1406. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1407. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1408. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1409. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1410. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1411. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1412. * POSSIBILITY OF SUCH DAMAGE.
  1413. *
  1414. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1415. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1416. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1417. * @link http://www.github.com/sebastianbergmann/global-state
  1418. */
  1419. namespace SebastianBergmann\GlobalState;
  1420. /**
  1421. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1422. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1423. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1424. * @link http://www.github.com/sebastianbergmann/global-state
  1425. */
  1426. class RuntimeException extends \RuntimeException implements Exception
  1427. {
  1428. }
  1429. Text_Template
  1430. Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  1431. All rights reserved.
  1432. Redistribution and use in source and binary forms, with or without
  1433. modification, are permitted provided that the following conditions
  1434. are met:
  1435. * Redistributions of source code must retain the above copyright
  1436. notice, this list of conditions and the following disclaimer.
  1437. * Redistributions in binary form must reproduce the above copyright
  1438. notice, this list of conditions and the following disclaimer in
  1439. the documentation and/or other materials provided with the
  1440. distribution.
  1441. * Neither the name of Sebastian Bergmann nor the names of his
  1442. contributors may be used to endorse or promote products derived
  1443. from this software without specific prior written permission.
  1444. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1445. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1446. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1447. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1448. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1449. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1450. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1451. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1452. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1453. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1454. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1455. POSSIBILITY OF SUCH DAMAGE.
  1456. <?php
  1457. /**
  1458. * Text_Template
  1459. *
  1460. * Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  1461. * All rights reserved.
  1462. *
  1463. * Redistribution and use in source and binary forms, with or without
  1464. * modification, are permitted provided that the following conditions
  1465. * are met:
  1466. *
  1467. * * Redistributions of source code must retain the above copyright
  1468. * notice, this list of conditions and the following disclaimer.
  1469. *
  1470. * * Redistributions in binary form must reproduce the above copyright
  1471. * notice, this list of conditions and the following disclaimer in
  1472. * the documentation and/or other materials provided with the
  1473. * distribution.
  1474. *
  1475. * * Neither the name of Sebastian Bergmann nor the names of his
  1476. * contributors may be used to endorse or promote products derived
  1477. * from this software without specific prior written permission.
  1478. *
  1479. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1480. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1481. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1482. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1483. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1484. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1485. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1486. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1487. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1488. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1489. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1490. * POSSIBILITY OF SUCH DAMAGE.
  1491. *
  1492. * @category Text
  1493. * @package Template
  1494. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1495. * @copyright 2009-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1496. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1497. * @link http://github.com/sebastianbergmann/php-text-template
  1498. * @since File available since Release 1.0.0
  1499. */
  1500. /**
  1501. * A simple template engine.
  1502. *
  1503. * @category Text
  1504. * @package Template
  1505. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1506. * @copyright 2009-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1507. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1508. * @version Release: @package_version@
  1509. * @link http://github.com/sebastianbergmann/php-text-template
  1510. * @since Class available since Release 1.0.0
  1511. */
  1512. class Text_Template
  1513. {
  1514. /**
  1515. * @var string
  1516. */
  1517. protected $template = '';
  1518. /**
  1519. * @var string
  1520. */
  1521. protected $openDelimiter = '{';
  1522. /**
  1523. * @var string
  1524. */
  1525. protected $closeDelimiter = '}';
  1526. /**
  1527. * @var array
  1528. */
  1529. protected $values = array();
  1530. /**
  1531. * Constructor.
  1532. *
  1533. * @param string $file
  1534. * @throws InvalidArgumentException
  1535. */
  1536. public function __construct($file = '', $openDelimiter = '{', $closeDelimiter = '}')
  1537. {
  1538. $this->setFile($file);
  1539. $this->openDelimiter = $openDelimiter;
  1540. $this->closeDelimiter = $closeDelimiter;
  1541. }
  1542. /**
  1543. * Sets the template file.
  1544. *
  1545. * @param string $file
  1546. * @throws InvalidArgumentException
  1547. */
  1548. public function setFile($file)
  1549. {
  1550. $distFile = $file . '.dist';
  1551. if (file_exists($file)) {
  1552. $this->template = file_get_contents($file);
  1553. }
  1554. else if (file_exists($distFile)) {
  1555. $this->template = file_get_contents($distFile);
  1556. }
  1557. else {
  1558. throw new InvalidArgumentException(
  1559. 'Template file could not be loaded.'
  1560. );
  1561. }
  1562. }
  1563. /**
  1564. * Sets one or more template variables.
  1565. *
  1566. * @param array $values
  1567. * @param boolean $merge
  1568. */
  1569. public function setVar(array $values, $merge = TRUE)
  1570. {
  1571. if (!$merge || empty($this->values)) {
  1572. $this->values = $values;
  1573. } else {
  1574. $this->values = array_merge($this->values, $values);
  1575. }
  1576. }
  1577. /**
  1578. * Renders the template and returns the result.
  1579. *
  1580. * @return string
  1581. */
  1582. public function render()
  1583. {
  1584. $keys = array();
  1585. foreach ($this->values as $key => $value) {
  1586. $keys[] = $this->openDelimiter . $key . $this->closeDelimiter;
  1587. }
  1588. return str_replace($keys, $this->values, $this->template);
  1589. }
  1590. /**
  1591. * Renders the template and writes the result to a file.
  1592. *
  1593. * @param string $target
  1594. */
  1595. public function renderTo($target)
  1596. {
  1597. $fp = @fopen($target, 'wt');
  1598. if ($fp) {
  1599. fwrite($fp, $this->render());
  1600. fclose($fp);
  1601. } else {
  1602. $error = error_get_last();
  1603. throw new RuntimeException(
  1604. sprintf(
  1605. 'Could not write to %s: %s',
  1606. $target,
  1607. substr(
  1608. $error['message'],
  1609. strpos($error['message'], ':') + 2
  1610. )
  1611. )
  1612. );
  1613. }
  1614. }
  1615. }
  1616. Diff
  1617. Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  1618. All rights reserved.
  1619. Redistribution and use in source and binary forms, with or without
  1620. modification, are permitted provided that the following conditions
  1621. are met:
  1622. * Redistributions of source code must retain the above copyright
  1623. notice, this list of conditions and the following disclaimer.
  1624. * Redistributions in binary form must reproduce the above copyright
  1625. notice, this list of conditions and the following disclaimer in
  1626. the documentation and/or other materials provided with the
  1627. distribution.
  1628. * Neither the name of Sebastian Bergmann nor the names of his
  1629. contributors may be used to endorse or promote products derived
  1630. from this software without specific prior written permission.
  1631. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1632. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1633. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1634. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1635. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1636. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1637. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1638. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1639. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1640. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1641. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1642. POSSIBILITY OF SUCH DAMAGE.
  1643. <?php
  1644. /*
  1645. * This file is part of the Diff package.
  1646. *
  1647. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1648. *
  1649. * For the full copyright and license information, please view the LICENSE
  1650. * file that was distributed with this source code.
  1651. */
  1652. namespace SebastianBergmann\Diff\LCS;
  1653. /**
  1654. * Interface for implementations of longest common subsequence calculation.
  1655. *
  1656. * @package Diff
  1657. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1658. * @author Kore Nordmann <mail@kore-nordmann.de>
  1659. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  1660. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1661. * @link http://www.github.com/sebastianbergmann/diff
  1662. */
  1663. interface LongestCommonSubsequence
  1664. {
  1665. /**
  1666. * Calculates the longest common subsequence of two arrays.
  1667. *
  1668. * @param array $from
  1669. * @param array $to
  1670. * @return array
  1671. */
  1672. public function calculate(array $from, array $to);
  1673. }
  1674. <?php
  1675. /*
  1676. * This file is part of the Diff package.
  1677. *
  1678. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1679. *
  1680. * For the full copyright and license information, please view the LICENSE
  1681. * file that was distributed with this source code.
  1682. */
  1683. namespace SebastianBergmann\Diff\LCS;
  1684. /**
  1685. * Memory-efficient implementation of longest common subsequence calculation.
  1686. *
  1687. * @package Diff
  1688. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1689. * @author Denes Lados <lados.denes@gmail.com>
  1690. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  1691. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1692. * @link http://www.github.com/sebastianbergmann/diff
  1693. */
  1694. class MemoryEfficientImplementation implements LongestCommonSubsequence
  1695. {
  1696. /**
  1697. * Calculates the longest common subsequence of two arrays.
  1698. *
  1699. * @param array $from
  1700. * @param array $to
  1701. * @return array
  1702. */
  1703. public function calculate(array $from, array $to)
  1704. {
  1705. $cFrom = count($from);
  1706. $cTo = count($to);
  1707. if ($cFrom == 0) {
  1708. return array();
  1709. } elseif ($cFrom == 1) {
  1710. if (in_array($from[0], $to)) {
  1711. return array($from[0]);
  1712. } else {
  1713. return array();
  1714. }
  1715. } else {
  1716. $i = intval($cFrom / 2);
  1717. $fromStart = array_slice($from, 0, $i);
  1718. $fromEnd = array_slice($from, $i);
  1719. $llB = $this->length($fromStart, $to);
  1720. $llE = $this->length(array_reverse($fromEnd), array_reverse($to));
  1721. $jMax = 0;
  1722. $max = 0;
  1723. for ($j = 0; $j <= $cTo; $j++) {
  1724. $m = $llB[$j] + $llE[$cTo - $j];
  1725. if ($m >= $max) {
  1726. $max = $m;
  1727. $jMax = $j;
  1728. }
  1729. }
  1730. $toStart = array_slice($to, 0, $jMax);
  1731. $toEnd = array_slice($to, $jMax);
  1732. return array_merge(
  1733. $this->calculate($fromStart, $toStart),
  1734. $this->calculate($fromEnd, $toEnd)
  1735. );
  1736. }
  1737. }
  1738. /**
  1739. * @param array $from
  1740. * @param array $to
  1741. * @return array
  1742. */
  1743. private function length(array $from, array $to)
  1744. {
  1745. $current = array_fill(0, count($to) + 1, 0);
  1746. $cFrom = count($from);
  1747. $cTo = count($to);
  1748. for ($i = 0; $i < $cFrom; $i++) {
  1749. $prev = $current;
  1750. for ($j = 0; $j < $cTo; $j++) {
  1751. if ($from[$i] == $to[$j]) {
  1752. $current[$j + 1] = $prev[$j] + 1;
  1753. } else {
  1754. $current[$j + 1] = max($current[$j], $prev[$j + 1]);
  1755. }
  1756. }
  1757. }
  1758. return $current;
  1759. }
  1760. }
  1761. <?php
  1762. /*
  1763. * This file is part of the Diff package.
  1764. *
  1765. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1766. *
  1767. * For the full copyright and license information, please view the LICENSE
  1768. * file that was distributed with this source code.
  1769. */
  1770. namespace SebastianBergmann\Diff\LCS;
  1771. /**
  1772. * Time-efficient implementation of longest common subsequence calculation.
  1773. *
  1774. * @package Diff
  1775. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1776. * @author Kore Nordmann <mail@kore-nordmann.de>
  1777. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  1778. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1779. * @link http://www.github.com/sebastianbergmann/diff
  1780. */
  1781. class TimeEfficientImplementation implements LongestCommonSubsequence
  1782. {
  1783. /**
  1784. * Calculates the longest common subsequence of two arrays.
  1785. *
  1786. * @param array $from
  1787. * @param array $to
  1788. * @return array
  1789. */
  1790. public function calculate(array $from, array $to)
  1791. {
  1792. $common = array();
  1793. $fromLength = count($from);
  1794. $toLength = count($to);
  1795. $width = $fromLength + 1;
  1796. $matrix = new \SplFixedArray($width * ($toLength + 1));
  1797. for ($i = 0; $i <= $fromLength; ++$i) {
  1798. $matrix[$i] = 0;
  1799. }
  1800. for ($j = 0; $j <= $toLength; ++$j) {
  1801. $matrix[$j * $width] = 0;
  1802. }
  1803. for ($i = 1; $i <= $fromLength; ++$i) {
  1804. for ($j = 1; $j <= $toLength; ++$j) {
  1805. $o = ($j * $width) + $i;
  1806. $matrix[$o] = max(
  1807. $matrix[$o - 1],
  1808. $matrix[$o - $width],
  1809. $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0
  1810. );
  1811. }
  1812. }
  1813. $i = $fromLength;
  1814. $j = $toLength;
  1815. while ($i > 0 && $j > 0) {
  1816. if ($from[$i-1] === $to[$j-1]) {
  1817. $common[] = $from[$i-1];
  1818. --$i;
  1819. --$j;
  1820. } else {
  1821. $o = ($j * $width) + $i;
  1822. if ($matrix[$o - $width] > $matrix[$o - 1]) {
  1823. --$j;
  1824. } else {
  1825. --$i;
  1826. }
  1827. }
  1828. }
  1829. return array_reverse($common);
  1830. }
  1831. }
  1832. <?php
  1833. /*
  1834. * This file is part of the Diff package.
  1835. *
  1836. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1837. *
  1838. * For the full copyright and license information, please view the LICENSE
  1839. * file that was distributed with this source code.
  1840. */
  1841. namespace SebastianBergmann\Diff;
  1842. /**
  1843. * @package Diff
  1844. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1845. * @author Kore Nordmann <mail@kore-nordmann.de>
  1846. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  1847. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1848. * @link http://www.github.com/sebastianbergmann/diff
  1849. */
  1850. class Line
  1851. {
  1852. const ADDED = 1;
  1853. const REMOVED = 2;
  1854. const UNCHANGED = 3;
  1855. /**
  1856. * @var int
  1857. */
  1858. private $type;
  1859. /**
  1860. * @var string
  1861. */
  1862. private $content;
  1863. /**
  1864. * @param int $type
  1865. * @param string $content
  1866. */
  1867. public function __construct($type = self::UNCHANGED, $content = '')
  1868. {
  1869. $this->type = $type;
  1870. $this->content = $content;
  1871. }
  1872. /**
  1873. * @return string
  1874. */
  1875. public function getContent()
  1876. {
  1877. return $this->content;
  1878. }
  1879. /**
  1880. * @return int
  1881. */
  1882. public function getType()
  1883. {
  1884. return $this->type;
  1885. }
  1886. }
  1887. <?php
  1888. /*
  1889. * This file is part of the Diff package.
  1890. *
  1891. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1892. *
  1893. * For the full copyright and license information, please view the LICENSE
  1894. * file that was distributed with this source code.
  1895. */
  1896. namespace SebastianBergmann\Diff;
  1897. use SebastianBergmann\Diff\LCS\LongestCommonSubsequence;
  1898. use SebastianBergmann\Diff\LCS\TimeEfficientImplementation;
  1899. use SebastianBergmann\Diff\LCS\MemoryEfficientImplementation;
  1900. /**
  1901. * Diff implementation.
  1902. *
  1903. * @package Diff
  1904. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1905. * @author Kore Nordmann <mail@kore-nordmann.de>
  1906. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  1907. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1908. * @link http://www.github.com/sebastianbergmann/diff
  1909. */
  1910. class Differ
  1911. {
  1912. /**
  1913. * @var string
  1914. */
  1915. private $header;
  1916. /**
  1917. * @param string $header
  1918. */
  1919. public function __construct($header = "--- Original\n+++ New\n")
  1920. {
  1921. $this->header = $header;
  1922. }
  1923. /**
  1924. * Returns the diff between two arrays or strings as string.
  1925. *
  1926. * @param array|string $from
  1927. * @param array|string $to
  1928. * @param LongestCommonSubsequence $lcs
  1929. * @return string
  1930. */
  1931. public function diff($from, $to, LongestCommonSubsequence $lcs = null)
  1932. {
  1933. if (!is_array($from) && !is_string($from)) {
  1934. $from = (string) $from;
  1935. }
  1936. if (!is_array($to) && !is_string($to)) {
  1937. $to = (string) $to;
  1938. }
  1939. $buffer = $this->header;
  1940. $diff = $this->diffToArray($from, $to, $lcs);
  1941. $inOld = false;
  1942. $i = 0;
  1943. $old = array();
  1944. foreach ($diff as $line) {
  1945. if ($line[1] === 0 /* OLD */) {
  1946. if ($inOld === false) {
  1947. $inOld = $i;
  1948. }
  1949. } elseif ($inOld !== false) {
  1950. if (($i - $inOld) > 5) {
  1951. $old[$inOld] = $i - 1;
  1952. }
  1953. $inOld = false;
  1954. }
  1955. ++$i;
  1956. }
  1957. $start = isset($old[0]) ? $old[0] : 0;
  1958. $end = count($diff);
  1959. if ($tmp = array_search($end, $old)) {
  1960. $end = $tmp;
  1961. }
  1962. $newChunk = true;
  1963. for ($i = $start; $i < $end; $i++) {
  1964. if (isset($old[$i])) {
  1965. $buffer .= "\n";
  1966. $newChunk = true;
  1967. $i = $old[$i];
  1968. }
  1969. if ($newChunk) {
  1970. $buffer .= "@@ @@\n";
  1971. $newChunk = false;
  1972. }
  1973. if ($diff[$i][1] === 1 /* ADDED */) {
  1974. $buffer .= '+' . $diff[$i][0] . "\n";
  1975. } elseif ($diff[$i][1] === 2 /* REMOVED */) {
  1976. $buffer .= '-' . $diff[$i][0] . "\n";
  1977. } else {
  1978. $buffer .= ' ' . $diff[$i][0] . "\n";
  1979. }
  1980. }
  1981. return $buffer;
  1982. }
  1983. /**
  1984. * Returns the diff between two arrays or strings as array.
  1985. *
  1986. * Each array element contains two elements:
  1987. * - [0] => string $token
  1988. * - [1] => 2|1|0
  1989. *
  1990. * - 2: REMOVED: $token was removed from $from
  1991. * - 1: ADDED: $token was added to $from
  1992. * - 0: OLD: $token is not changed in $to
  1993. *
  1994. * @param array|string $from
  1995. * @param array|string $to
  1996. * @param LongestCommonSubsequence $lcs
  1997. * @return array
  1998. */
  1999. public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null)
  2000. {
  2001. preg_match_all('(\r\n|\r|\n)', $from, $fromMatches);
  2002. preg_match_all('(\r\n|\r|\n)', $to, $toMatches);
  2003. if (is_string($from)) {
  2004. $from = preg_split('(\r\n|\r|\n)', $from);
  2005. }
  2006. if (is_string($to)) {
  2007. $to = preg_split('(\r\n|\r|\n)', $to);
  2008. }
  2009. $start = array();
  2010. $end = array();
  2011. $fromLength = count($from);
  2012. $toLength = count($to);
  2013. $length = min($fromLength, $toLength);
  2014. for ($i = 0; $i < $length; ++$i) {
  2015. if ($from[$i] === $to[$i]) {
  2016. $start[] = $from[$i];
  2017. unset($from[$i], $to[$i]);
  2018. } else {
  2019. break;
  2020. }
  2021. }
  2022. $length -= $i;
  2023. for ($i = 1; $i < $length; ++$i) {
  2024. if ($from[$fromLength - $i] === $to[$toLength - $i]) {
  2025. array_unshift($end, $from[$fromLength - $i]);
  2026. unset($from[$fromLength - $i], $to[$toLength - $i]);
  2027. } else {
  2028. break;
  2029. }
  2030. }
  2031. if ($lcs === null) {
  2032. $lcs = $this->selectLcsImplementation($from, $to);
  2033. }
  2034. $common = $lcs->calculate(array_values($from), array_values($to));
  2035. $diff = array();
  2036. if (isset($fromMatches[0]) && $toMatches[0] &&
  2037. count($fromMatches[0]) === count($toMatches[0]) &&
  2038. $fromMatches[0] !== $toMatches[0]) {
  2039. $diff[] = array(
  2040. '#Warning: Strings contain different line endings!', 0
  2041. );
  2042. }
  2043. foreach ($start as $token) {
  2044. $diff[] = array($token, 0 /* OLD */);
  2045. }
  2046. reset($from);
  2047. reset($to);
  2048. foreach ($common as $token) {
  2049. while ((($fromToken = reset($from)) !== $token)) {
  2050. $diff[] = array(array_shift($from), 2 /* REMOVED */);
  2051. }
  2052. while ((($toToken = reset($to)) !== $token)) {
  2053. $diff[] = array(array_shift($to), 1 /* ADDED */);
  2054. }
  2055. $diff[] = array($token, 0 /* OLD */);
  2056. array_shift($from);
  2057. array_shift($to);
  2058. }
  2059. while (($token = array_shift($from)) !== null) {
  2060. $diff[] = array($token, 2 /* REMOVED */);
  2061. }
  2062. while (($token = array_shift($to)) !== null) {
  2063. $diff[] = array($token, 1 /* ADDED */);
  2064. }
  2065. foreach ($end as $token) {
  2066. $diff[] = array($token, 0 /* OLD */);
  2067. }
  2068. return $diff;
  2069. }
  2070. /**
  2071. * @param array $from
  2072. * @param array $to
  2073. * @return LongestCommonSubsequence
  2074. */
  2075. private function selectLcsImplementation(array $from, array $to)
  2076. {
  2077. // We do not want to use the time-efficient implementation if its memory
  2078. // footprint will probably exceed this value. Note that the footprint
  2079. // calculation is only an estimation for the matrix and the LCS method
  2080. // will typically allocate a bit more memory than this.
  2081. $memoryLimit = 100 * 1024 * 1024;
  2082. if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) {
  2083. return new MemoryEfficientImplementation;
  2084. }
  2085. return new TimeEfficientImplementation;
  2086. }
  2087. /**
  2088. * Calculates the estimated memory footprint for the DP-based method.
  2089. *
  2090. * @param array $from
  2091. * @param array $to
  2092. * @return integer
  2093. */
  2094. private function calculateEstimatedFootprint(array $from, array $to)
  2095. {
  2096. $itemSize = PHP_INT_SIZE == 4 ? 76 : 144;
  2097. return $itemSize * pow(min(count($from), count($to)), 2);
  2098. }
  2099. }
  2100. <?php
  2101. /*
  2102. * This file is part of the Diff package.
  2103. *
  2104. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2105. *
  2106. * For the full copyright and license information, please view the LICENSE
  2107. * file that was distributed with this source code.
  2108. */
  2109. namespace SebastianBergmann\Diff;
  2110. /**
  2111. * Unified diff parser.
  2112. *
  2113. * @package Diff
  2114. * @author Sebastian Bergmann <sebastian@phpunit.de>
  2115. * @author Kore Nordmann <mail@kore-nordmann.de>
  2116. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2117. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2118. * @link http://www.github.com/sebastianbergmann/diff
  2119. */
  2120. class Parser
  2121. {
  2122. /**
  2123. * @param string $string
  2124. * @return Diff[]
  2125. */
  2126. public function parse($string)
  2127. {
  2128. $lines = preg_split('(\r\n|\r|\n)', $string);
  2129. $lineCount = count($lines);
  2130. $diffs = array();
  2131. $diff = null;
  2132. $collected = array();
  2133. for ($i = 0; $i < $lineCount; ++$i) {
  2134. if (preg_match('(^---\\s+(?P<file>\\S+))', $lines[$i], $fromMatch) &&
  2135. preg_match('(^\\+\\+\\+\\s+(?P<file>\\S+))', $lines[$i + 1], $toMatch)) {
  2136. if ($diff !== null) {
  2137. $this->parseFileDiff($diff, $collected);
  2138. $diffs[] = $diff;
  2139. $collected = array();
  2140. }
  2141. $diff = new Diff($fromMatch['file'], $toMatch['file']);
  2142. ++$i;
  2143. } else {
  2144. if (preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) {
  2145. continue;
  2146. }
  2147. $collected[] = $lines[$i];
  2148. }
  2149. }
  2150. if (count($collected) && ($diff !== null)) {
  2151. $this->parseFileDiff($diff, $collected);
  2152. $diffs[] = $diff;
  2153. }
  2154. return $diffs;
  2155. }
  2156. /**
  2157. * @param Diff $diff
  2158. * @param array $lines
  2159. */
  2160. private function parseFileDiff(Diff $diff, array $lines)
  2161. {
  2162. $chunks = array();
  2163. foreach ($lines as $line) {
  2164. if (preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match)) {
  2165. $chunk = new Chunk(
  2166. $match['start'],
  2167. isset($match['startrange']) ? max(1, $match['startrange']) : 1,
  2168. $match['end'],
  2169. isset($match['endrange']) ? max(1, $match['endrange']) : 1
  2170. );
  2171. $chunks[] = $chunk;
  2172. $diffLines = array();
  2173. continue;
  2174. }
  2175. if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
  2176. $type = Line::UNCHANGED;
  2177. if ($match['type'] == '+') {
  2178. $type = Line::ADDED;
  2179. } elseif ($match['type'] == '-') {
  2180. $type = Line::REMOVED;
  2181. }
  2182. $diffLines[] = new Line($type, $match['line']);
  2183. if (isset($chunk)) {
  2184. $chunk->setLines($diffLines);
  2185. }
  2186. }
  2187. }
  2188. $diff->setChunks($chunks);
  2189. }
  2190. }
  2191. <?php
  2192. /*
  2193. * This file is part of the Diff package.
  2194. *
  2195. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2196. *
  2197. * For the full copyright and license information, please view the LICENSE
  2198. * file that was distributed with this source code.
  2199. */
  2200. namespace SebastianBergmann\Diff;
  2201. /**
  2202. * @package Diff
  2203. * @author Sebastian Bergmann <sebastian@phpunit.de>
  2204. * @author Kore Nordmann <mail@kore-nordmann.de>
  2205. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2206. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2207. * @link http://www.github.com/sebastianbergmann/diff
  2208. */
  2209. class Diff
  2210. {
  2211. /**
  2212. * @var string
  2213. */
  2214. private $from;
  2215. /**
  2216. * @var string
  2217. */
  2218. private $to;
  2219. /**
  2220. * @var Chunk[]
  2221. */
  2222. private $chunks;
  2223. /**
  2224. * @param string $from
  2225. * @param string $to
  2226. * @param Chunk[] $chunks
  2227. */
  2228. public function __construct($from, $to, array $chunks = array())
  2229. {
  2230. $this->from = $from;
  2231. $this->to = $to;
  2232. $this->chunks = $chunks;
  2233. }
  2234. /**
  2235. * @return string
  2236. */
  2237. public function getFrom()
  2238. {
  2239. return $this->from;
  2240. }
  2241. /**
  2242. * @return string
  2243. */
  2244. public function getTo()
  2245. {
  2246. return $this->to;
  2247. }
  2248. /**
  2249. * @return Chunk[]
  2250. */
  2251. public function getChunks()
  2252. {
  2253. return $this->chunks;
  2254. }
  2255. /**
  2256. * @param Chunk[] $chunks
  2257. */
  2258. public function setChunks(array $chunks)
  2259. {
  2260. $this->chunks = $chunks;
  2261. }
  2262. }
  2263. <?php
  2264. /*
  2265. * This file is part of the Diff package.
  2266. *
  2267. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2268. *
  2269. * For the full copyright and license information, please view the LICENSE
  2270. * file that was distributed with this source code.
  2271. */
  2272. namespace SebastianBergmann\Diff;
  2273. /**
  2274. * @package Diff
  2275. * @author Sebastian Bergmann <sebastian@phpunit.de>
  2276. * @author Kore Nordmann <mail@kore-nordmann.de>
  2277. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2278. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2279. * @link http://www.github.com/sebastianbergmann/diff
  2280. */
  2281. class Chunk
  2282. {
  2283. /**
  2284. * @var int
  2285. */
  2286. private $start;
  2287. /**
  2288. * @var int
  2289. */
  2290. private $startRange;
  2291. /**
  2292. * @var int
  2293. */
  2294. private $end;
  2295. /**
  2296. * @var int
  2297. */
  2298. private $endRange;
  2299. /**
  2300. * @var array
  2301. */
  2302. private $lines;
  2303. /**
  2304. * @param int $start
  2305. * @param int $startRange
  2306. * @param int $end
  2307. * @param int $endRange
  2308. * @param array $lines
  2309. */
  2310. public function __construct($start = 0, $startRange = 1, $end = 0, $endRange = 1, array $lines = array())
  2311. {
  2312. $this->start = (int) $start;
  2313. $this->startRange = (int) $startRange;
  2314. $this->end = (int) $end;
  2315. $this->endRange = (int) $endRange;
  2316. $this->lines = $lines;
  2317. }
  2318. /**
  2319. * @return int
  2320. */
  2321. public function getStart()
  2322. {
  2323. return $this->start;
  2324. }
  2325. /**
  2326. * @return int
  2327. */
  2328. public function getStartRange()
  2329. {
  2330. return $this->startRange;
  2331. }
  2332. /**
  2333. * @return int
  2334. */
  2335. public function getEnd()
  2336. {
  2337. return $this->end;
  2338. }
  2339. /**
  2340. * @return int
  2341. */
  2342. public function getEndRange()
  2343. {
  2344. return $this->endRange;
  2345. }
  2346. /**
  2347. * @return array
  2348. */
  2349. public function getLines()
  2350. {
  2351. return $this->lines;
  2352. }
  2353. /**
  2354. * @param array $lines
  2355. */
  2356. public function setLines(array $lines)
  2357. {
  2358. $this->lines = $lines;
  2359. }
  2360. }
  2361. <?php
  2362. /**
  2363. * PHP_Timer
  2364. *
  2365. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  2366. * All rights reserved.
  2367. *
  2368. * Redistribution and use in source and binary forms, with or without
  2369. * modification, are permitted provided that the following conditions
  2370. * are met:
  2371. *
  2372. * * Redistributions of source code must retain the above copyright
  2373. * notice, this list of conditions and the following disclaimer.
  2374. *
  2375. * * Redistributions in binary form must reproduce the above copyright
  2376. * notice, this list of conditions and the following disclaimer in
  2377. * the documentation and/or other materials provided with the
  2378. * distribution.
  2379. *
  2380. * * Neither the name of Sebastian Bergmann nor the names of his
  2381. * contributors may be used to endorse or promote products derived
  2382. * from this software without specific prior written permission.
  2383. *
  2384. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  2385. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  2386. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  2387. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  2388. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  2389. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  2390. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  2391. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  2392. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  2393. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  2394. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  2395. * POSSIBILITY OF SUCH DAMAGE.
  2396. *
  2397. * @package PHP
  2398. * @subpackage Timer
  2399. * @author Sebastian Bergmann <sebastian@phpunit.de>
  2400. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  2401. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2402. * @link http://github.com/sebastianbergmann/php-timer
  2403. * @since File available since Release 1.0.0
  2404. */
  2405. /**
  2406. * Utility class for timing.
  2407. *
  2408. * @package PHP
  2409. * @subpackage Timer
  2410. * @author Sebastian Bergmann <sebastian@phpunit.de>
  2411. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  2412. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2413. * @version Release: @package_version@
  2414. * @link http://github.com/sebastianbergmann/php-timer
  2415. * @since Class available since Release 1.0.0
  2416. */
  2417. class PHP_Timer
  2418. {
  2419. /**
  2420. * @var array
  2421. */
  2422. private static $times = array(
  2423. 'hour' => 3600000,
  2424. 'minute' => 60000,
  2425. 'second' => 1000
  2426. );
  2427. /**
  2428. * @var array
  2429. */
  2430. private static $startTimes = array();
  2431. /**
  2432. * @var float
  2433. */
  2434. public static $requestTime;
  2435. /**
  2436. * Starts the timer.
  2437. */
  2438. public static function start()
  2439. {
  2440. array_push(self::$startTimes, microtime(TRUE));
  2441. }
  2442. /**
  2443. * Stops the timer and returns the elapsed time.
  2444. *
  2445. * @return float
  2446. */
  2447. public static function stop()
  2448. {
  2449. return microtime(TRUE) - array_pop(self::$startTimes);
  2450. }
  2451. /**
  2452. * Formats the elapsed time as a string.
  2453. *
  2454. * @param float $time
  2455. * @return string
  2456. */
  2457. public static function secondsToTimeString($time)
  2458. {
  2459. $ms = round($time * 1000);
  2460. foreach (self::$times as $unit => $value) {
  2461. if ($ms >= $value) {
  2462. $time = floor($ms / $value * 100.0) / 100.0;
  2463. return $time . ' ' . ($time == 1 ? $unit : $unit . 's');
  2464. }
  2465. }
  2466. return $ms . ' ms';
  2467. }
  2468. /**
  2469. * Formats the elapsed time since the start of the request as a string.
  2470. *
  2471. * @return string
  2472. */
  2473. public static function timeSinceStartOfRequest()
  2474. {
  2475. return self::secondsToTimeString(microtime(TRUE) - self::$requestTime);
  2476. }
  2477. /**
  2478. * Returns the resources (time, memory) of the request as a string.
  2479. *
  2480. * @return string
  2481. */
  2482. public static function resourceUsage()
  2483. {
  2484. return sprintf(
  2485. 'Time: %s, Memory: %4.2fMb',
  2486. self::timeSinceStartOfRequest(),
  2487. memory_get_peak_usage(TRUE) / 1048576
  2488. );
  2489. }
  2490. }
  2491. if (isset($_SERVER['REQUEST_TIME_FLOAT'])) {
  2492. PHP_Timer::$requestTime = $_SERVER['REQUEST_TIME_FLOAT'];
  2493. }
  2494. else {
  2495. PHP_Timer::$requestTime = microtime(TRUE);
  2496. }
  2497. PHP_Timer
  2498. Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  2499. All rights reserved.
  2500. Redistribution and use in source and binary forms, with or without
  2501. modification, are permitted provided that the following conditions
  2502. are met:
  2503. * Redistributions of source code must retain the above copyright
  2504. notice, this list of conditions and the following disclaimer.
  2505. * Redistributions in binary form must reproduce the above copyright
  2506. notice, this list of conditions and the following disclaimer in
  2507. the documentation and/or other materials provided with the
  2508. distribution.
  2509. * Neither the name of Sebastian Bergmann nor the names of his
  2510. contributors may be used to endorse or promote products derived
  2511. from this software without specific prior written permission.
  2512. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  2513. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  2514. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  2515. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  2516. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  2517. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  2518. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  2519. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  2520. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  2521. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  2522. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  2523. POSSIBILITY OF SUCH DAMAGE.
  2524. Comparator
  2525. Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  2526. All rights reserved.
  2527. Redistribution and use in source and binary forms, with or without
  2528. modification, are permitted provided that the following conditions
  2529. are met:
  2530. * Redistributions of source code must retain the above copyright
  2531. notice, this list of conditions and the following disclaimer.
  2532. * Redistributions in binary form must reproduce the above copyright
  2533. notice, this list of conditions and the following disclaimer in
  2534. the documentation and/or other materials provided with the
  2535. distribution.
  2536. * Neither the name of Sebastian Bergmann nor the names of his
  2537. contributors may be used to endorse or promote products derived
  2538. from this software without specific prior written permission.
  2539. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  2540. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  2541. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  2542. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  2543. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  2544. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  2545. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  2546. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  2547. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  2548. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  2549. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  2550. POSSIBILITY OF SUCH DAMAGE.
  2551. <?php
  2552. /*
  2553. * This file is part of the Comparator package.
  2554. *
  2555. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2556. *
  2557. * For the full copyright and license information, please view the LICENSE
  2558. * file that was distributed with this source code.
  2559. */
  2560. namespace SebastianBergmann\Comparator;
  2561. use SebastianBergmann\Exporter\Exporter;
  2562. /**
  2563. * Abstract base class for comparators which compare values for equality.
  2564. *
  2565. * @package Comparator
  2566. * @subpackage Framework
  2567. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2568. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2569. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2570. * @link http://www.github.com/sebastianbergmann/comparator
  2571. */
  2572. abstract class Comparator
  2573. {
  2574. /**
  2575. * @var Factory
  2576. */
  2577. protected $factory;
  2578. /**
  2579. * @var Exporter
  2580. */
  2581. protected $exporter;
  2582. public function __construct()
  2583. {
  2584. $this->exporter = new Exporter;
  2585. }
  2586. /**
  2587. * @param Factory $factory
  2588. */
  2589. public function setFactory(Factory $factory)
  2590. {
  2591. $this->factory = $factory;
  2592. }
  2593. /**
  2594. * Returns whether the comparator can compare two values.
  2595. *
  2596. * @param mixed $expected The first value to compare
  2597. * @param mixed $actual The second value to compare
  2598. * @return boolean
  2599. */
  2600. abstract public function accepts($expected, $actual);
  2601. /**
  2602. * Asserts that two values are equal.
  2603. *
  2604. * @param mixed $expected The first value to compare
  2605. * @param mixed $actual The second value to compare
  2606. * @param float $delta The allowed numerical distance between two values to
  2607. * consider them equal
  2608. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2609. * comparison
  2610. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2611. * ignored when comparing string values
  2612. * @throws ComparisonFailure Thrown when the comparison
  2613. * fails. Contains information about the
  2614. * specific errors that lead to the failure.
  2615. */
  2616. abstract public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false);
  2617. }
  2618. <?php
  2619. /*
  2620. * This file is part of the Comparator package.
  2621. *
  2622. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2623. *
  2624. * For the full copyright and license information, please view the LICENSE
  2625. * file that was distributed with this source code.
  2626. */
  2627. namespace SebastianBergmann\Comparator;
  2628. /**
  2629. * Compares \SplObjectStorage instances for equality.
  2630. *
  2631. * @package Comparator
  2632. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2633. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2634. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2635. * @link http://www.github.com/sebastianbergmann/comparator
  2636. */
  2637. class SplObjectStorageComparator extends Comparator
  2638. {
  2639. /**
  2640. * Returns whether the comparator can compare two values.
  2641. *
  2642. * @param mixed $expected The first value to compare
  2643. * @param mixed $actual The second value to compare
  2644. * @return boolean
  2645. */
  2646. public function accepts($expected, $actual)
  2647. {
  2648. return $expected instanceof \SplObjectStorage && $actual instanceof \SplObjectStorage;
  2649. }
  2650. /**
  2651. * Asserts that two values are equal.
  2652. *
  2653. * @param mixed $expected The first value to compare
  2654. * @param mixed $actual The second value to compare
  2655. * @param float $delta The allowed numerical distance between two values to
  2656. * consider them equal
  2657. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2658. * comparison
  2659. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2660. * ignored when comparing string values
  2661. * @throws ComparisonFailure Thrown when the comparison
  2662. * fails. Contains information about the
  2663. * specific errors that lead to the failure.
  2664. */
  2665. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  2666. {
  2667. foreach ($actual as $object) {
  2668. if (!$expected->contains($object)) {
  2669. throw new ComparisonFailure(
  2670. $expected,
  2671. $actual,
  2672. $this->exporter->export($expected),
  2673. $this->exporter->export($actual),
  2674. false,
  2675. 'Failed asserting that two objects are equal.'
  2676. );
  2677. }
  2678. }
  2679. foreach ($expected as $object) {
  2680. if (!$actual->contains($object)) {
  2681. throw new ComparisonFailure(
  2682. $expected,
  2683. $actual,
  2684. $this->exporter->export($expected),
  2685. $this->exporter->export($actual),
  2686. false,
  2687. 'Failed asserting that two objects are equal.'
  2688. );
  2689. }
  2690. }
  2691. }
  2692. }
  2693. <?php
  2694. /*
  2695. * This file is part of the Comparator package.
  2696. *
  2697. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2698. *
  2699. * For the full copyright and license information, please view the LICENSE
  2700. * file that was distributed with this source code.
  2701. */
  2702. namespace SebastianBergmann\Comparator;
  2703. /**
  2704. * Compares values for type equality.
  2705. *
  2706. * @package Comparator
  2707. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2708. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2709. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2710. * @link http://www.github.com/sebastianbergmann/comparator
  2711. */
  2712. class TypeComparator extends Comparator
  2713. {
  2714. /**
  2715. * Returns whether the comparator can compare two values.
  2716. *
  2717. * @param mixed $expected The first value to compare
  2718. * @param mixed $actual The second value to compare
  2719. * @return boolean
  2720. */
  2721. public function accepts($expected, $actual)
  2722. {
  2723. return true;
  2724. }
  2725. /**
  2726. * Asserts that two values are equal.
  2727. *
  2728. * @param mixed $expected The first value to compare
  2729. * @param mixed $actual The second value to compare
  2730. * @param float $delta The allowed numerical distance between two values to
  2731. * consider them equal
  2732. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2733. * comparison
  2734. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2735. * ignored when comparing string values
  2736. * @throws ComparisonFailure Thrown when the comparison
  2737. * fails. Contains information about the
  2738. * specific errors that lead to the failure.
  2739. */
  2740. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  2741. {
  2742. if (gettype($expected) != gettype($actual)) {
  2743. throw new ComparisonFailure(
  2744. $expected,
  2745. $actual,
  2746. // we don't need a diff
  2747. '',
  2748. '',
  2749. false,
  2750. sprintf(
  2751. '%s does not match expected type "%s".',
  2752. $this->exporter->shortenedExport($actual),
  2753. gettype($expected)
  2754. )
  2755. );
  2756. }
  2757. }
  2758. }
  2759. <?php
  2760. /*
  2761. * This file is part of the Comparator package.
  2762. *
  2763. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2764. *
  2765. * For the full copyright and license information, please view the LICENSE
  2766. * file that was distributed with this source code.
  2767. */
  2768. namespace SebastianBergmann\Comparator;
  2769. /**
  2770. * Compares objects for equality.
  2771. *
  2772. * @package Comparator
  2773. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2774. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2775. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2776. * @link http://www.github.com/sebastianbergmann/comparator
  2777. */
  2778. class ObjectComparator extends ArrayComparator
  2779. {
  2780. /**
  2781. * Returns whether the comparator can compare two values.
  2782. *
  2783. * @param mixed $expected The first value to compare
  2784. * @param mixed $actual The second value to compare
  2785. * @return boolean
  2786. */
  2787. public function accepts($expected, $actual)
  2788. {
  2789. return is_object($expected) && is_object($actual);
  2790. }
  2791. /**
  2792. * Asserts that two values are equal.
  2793. *
  2794. * @param mixed $expected The first value to compare
  2795. * @param mixed $actual The second value to compare
  2796. * @param float $delta The allowed numerical distance between two values to
  2797. * consider them equal
  2798. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2799. * comparison
  2800. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2801. * ignored when comparing string values
  2802. * @param array $processed
  2803. * @throws ComparisonFailure Thrown when the comparison
  2804. * fails. Contains information about the
  2805. * specific errors that lead to the failure.
  2806. */
  2807. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
  2808. {
  2809. if (get_class($actual) !== get_class($expected)) {
  2810. throw new ComparisonFailure(
  2811. $expected,
  2812. $actual,
  2813. $this->exporter->export($expected),
  2814. $this->exporter->export($actual),
  2815. false,
  2816. sprintf(
  2817. '%s is not instance of expected class "%s".',
  2818. $this->exporter->export($actual),
  2819. get_class($expected)
  2820. )
  2821. );
  2822. }
  2823. // don't compare twice to allow for cyclic dependencies
  2824. if (in_array(array($actual, $expected), $processed, true) ||
  2825. in_array(array($expected, $actual), $processed, true)) {
  2826. return;
  2827. }
  2828. $processed[] = array($actual, $expected);
  2829. // don't compare objects if they are identical
  2830. // this helps to avoid the error "maximum function nesting level reached"
  2831. // CAUTION: this conditional clause is not tested
  2832. if ($actual !== $expected) {
  2833. try {
  2834. parent::assertEquals(
  2835. $this->toArray($expected),
  2836. $this->toArray($actual),
  2837. $delta,
  2838. $canonicalize,
  2839. $ignoreCase,
  2840. $processed
  2841. );
  2842. } catch (ComparisonFailure $e) {
  2843. throw new ComparisonFailure(
  2844. $expected,
  2845. $actual,
  2846. // replace "Array" with "MyClass object"
  2847. substr_replace($e->getExpectedAsString(), get_class($expected) . ' Object', 0, 5),
  2848. substr_replace($e->getActualAsString(), get_class($actual) . ' Object', 0, 5),
  2849. false,
  2850. 'Failed asserting that two objects are equal.'
  2851. );
  2852. }
  2853. }
  2854. }
  2855. /**
  2856. * Converts an object to an array containing all of its private, protected
  2857. * and public properties.
  2858. *
  2859. * @param object $object
  2860. * @return array
  2861. */
  2862. protected function toArray($object)
  2863. {
  2864. return $this->exporter->toArray($object);
  2865. }
  2866. }
  2867. <?php
  2868. /*
  2869. * This file is part of the Comparator package.
  2870. *
  2871. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2872. *
  2873. * For the full copyright and license information, please view the LICENSE
  2874. * file that was distributed with this source code.
  2875. */
  2876. namespace SebastianBergmann\Comparator;
  2877. /**
  2878. * Compares resources for equality.
  2879. *
  2880. * @package Comparator
  2881. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2882. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2883. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2884. * @link http://www.github.com/sebastianbergmann/comparator
  2885. */
  2886. class ResourceComparator extends Comparator
  2887. {
  2888. /**
  2889. * Returns whether the comparator can compare two values.
  2890. *
  2891. * @param mixed $expected The first value to compare
  2892. * @param mixed $actual The second value to compare
  2893. * @return boolean
  2894. */
  2895. public function accepts($expected, $actual)
  2896. {
  2897. return is_resource($expected) && is_resource($actual);
  2898. }
  2899. /**
  2900. * Asserts that two values are equal.
  2901. *
  2902. * @param mixed $expected The first value to compare
  2903. * @param mixed $actual The second value to compare
  2904. * @param float $delta The allowed numerical distance between two values to
  2905. * consider them equal
  2906. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2907. * comparison
  2908. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2909. * ignored when comparing string values
  2910. * @throws ComparisonFailure Thrown when the comparison
  2911. * fails. Contains information about the
  2912. * specific errors that lead to the failure.
  2913. */
  2914. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  2915. {
  2916. if ($actual != $expected) {
  2917. throw new ComparisonFailure(
  2918. $expected,
  2919. $actual,
  2920. $this->exporter->export($expected),
  2921. $this->exporter->export($actual)
  2922. );
  2923. }
  2924. }
  2925. }
  2926. <?php
  2927. /*
  2928. * This file is part of the Comparator package.
  2929. *
  2930. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2931. *
  2932. * For the full copyright and license information, please view the LICENSE
  2933. * file that was distributed with this source code.
  2934. */
  2935. namespace SebastianBergmann\Comparator;
  2936. /**
  2937. * Compares arrays for equality.
  2938. *
  2939. * @package Comparator
  2940. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2941. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2942. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2943. * @link http://www.github.com/sebastianbergmann/comparator
  2944. */
  2945. class ArrayComparator extends Comparator
  2946. {
  2947. /**
  2948. * Returns whether the comparator can compare two values.
  2949. *
  2950. * @param mixed $expected The first value to compare
  2951. * @param mixed $actual The second value to compare
  2952. * @return boolean
  2953. */
  2954. public function accepts($expected, $actual)
  2955. {
  2956. return is_array($expected) && is_array($actual);
  2957. }
  2958. /**
  2959. * Asserts that two values are equal.
  2960. *
  2961. * @param mixed $expected The first value to compare
  2962. * @param mixed $actual The second value to compare
  2963. * @param float $delta The allowed numerical distance between two values to
  2964. * consider them equal
  2965. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2966. * comparison
  2967. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2968. * ignored when comparing string values
  2969. * @param array $processed
  2970. * @throws ComparisonFailure Thrown when the comparison
  2971. * fails. Contains information about the
  2972. * specific errors that lead to the failure.
  2973. */
  2974. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
  2975. {
  2976. if ($canonicalize) {
  2977. sort($expected);
  2978. sort($actual);
  2979. }
  2980. $remaining = $actual;
  2981. $expString = $actString = "Array (\n";
  2982. $equal = true;
  2983. foreach ($expected as $key => $value) {
  2984. unset($remaining[$key]);
  2985. if (!array_key_exists($key, $actual)) {
  2986. $expString .= sprintf(
  2987. " %s => %s\n",
  2988. $this->exporter->export($key),
  2989. $this->exporter->shortenedExport($value)
  2990. );
  2991. $equal = false;
  2992. continue;
  2993. }
  2994. try {
  2995. $comparator = $this->factory->getComparatorFor($value, $actual[$key]);
  2996. $comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
  2997. $expString .= sprintf(
  2998. " %s => %s\n",
  2999. $this->exporter->export($key),
  3000. $this->exporter->shortenedExport($value)
  3001. );
  3002. $actString .= sprintf(
  3003. " %s => %s\n",
  3004. $this->exporter->export($key),
  3005. $this->exporter->shortenedExport($actual[$key])
  3006. );
  3007. } catch (ComparisonFailure $e) {
  3008. $expString .= sprintf(
  3009. " %s => %s\n",
  3010. $this->exporter->export($key),
  3011. $e->getExpectedAsString()
  3012. ? $this->indent($e->getExpectedAsString())
  3013. : $this->exporter->shortenedExport($e->getExpected())
  3014. );
  3015. $actString .= sprintf(
  3016. " %s => %s\n",
  3017. $this->exporter->export($key),
  3018. $e->getActualAsString()
  3019. ? $this->indent($e->getActualAsString())
  3020. : $this->exporter->shortenedExport($e->getActual())
  3021. );
  3022. $equal = false;
  3023. }
  3024. }
  3025. foreach ($remaining as $key => $value) {
  3026. $actString .= sprintf(
  3027. " %s => %s\n",
  3028. $this->exporter->export($key),
  3029. $this->exporter->shortenedExport($value)
  3030. );
  3031. $equal = false;
  3032. }
  3033. $expString .= ')';
  3034. $actString .= ')';
  3035. if (!$equal) {
  3036. throw new ComparisonFailure(
  3037. $expected,
  3038. $actual,
  3039. $expString,
  3040. $actString,
  3041. false,
  3042. 'Failed asserting that two arrays are equal.'
  3043. );
  3044. }
  3045. }
  3046. protected function indent($lines)
  3047. {
  3048. return trim(str_replace("\n", "\n ", $lines));
  3049. }
  3050. }
  3051. <?php
  3052. /*
  3053. * This file is part of the Comparator package.
  3054. *
  3055. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3056. *
  3057. * For the full copyright and license information, please view the LICENSE
  3058. * file that was distributed with this source code.
  3059. */
  3060. namespace SebastianBergmann\Comparator;
  3061. /**
  3062. * Compares DateTime instances for equality.
  3063. *
  3064. * @package Comparator
  3065. * @author Jeff Welch <whatthejeff@gmail.com>
  3066. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3067. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3068. * @link http://www.github.com/sebastianbergmann/comparator
  3069. */
  3070. class DateTimeComparator extends ObjectComparator
  3071. {
  3072. /**
  3073. * Returns whether the comparator can compare two values.
  3074. *
  3075. * @param mixed $expected The first value to compare
  3076. * @param mixed $actual The second value to compare
  3077. * @return boolean
  3078. */
  3079. public function accepts($expected, $actual)
  3080. {
  3081. return $expected instanceof \DateTime && $actual instanceof \DateTime;
  3082. }
  3083. /**
  3084. * Asserts that two values are equal.
  3085. *
  3086. * @param mixed $expected The first value to compare
  3087. * @param mixed $actual The second value to compare
  3088. * @param float $delta The allowed numerical distance between two values to
  3089. * consider them equal
  3090. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  3091. * comparison
  3092. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  3093. * ignored when comparing string values
  3094. * @throws ComparisonFailure Thrown when the comparison
  3095. * fails. Contains information about the
  3096. * specific errors that lead to the failure.
  3097. */
  3098. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  3099. {
  3100. $delta = new \DateInterval(sprintf('PT%sS', abs($delta)));
  3101. $expectedLower = clone $expected;
  3102. $expectedUpper = clone $expected;
  3103. if ($actual < $expectedLower->sub($delta) ||
  3104. $actual > $expectedUpper->add($delta)) {
  3105. throw new ComparisonFailure(
  3106. $expected,
  3107. $actual,
  3108. $this->dateTimeToString($expected),
  3109. $this->dateTimeToString($actual),
  3110. false,
  3111. 'Failed asserting that two DateTime objects are equal.'
  3112. );
  3113. }
  3114. }
  3115. /**
  3116. * Returns an ISO 8601 formatted string representation of a datetime or
  3117. * 'Invalid DateTime object' if the provided DateTime was not properly
  3118. * initialized.
  3119. *
  3120. * @param \DateTime $datetime
  3121. * @return string
  3122. */
  3123. protected function dateTimeToString(\DateTime $datetime)
  3124. {
  3125. $string = $datetime->format(\DateTime::ISO8601);
  3126. return $string ? $string : 'Invalid DateTime object';
  3127. }
  3128. }
  3129. <?php
  3130. /*
  3131. * This file is part of the Comparator package.
  3132. *
  3133. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3134. *
  3135. * For the full copyright and license information, please view the LICENSE
  3136. * file that was distributed with this source code.
  3137. */
  3138. namespace SebastianBergmann\Comparator;
  3139. /**
  3140. * Compares Exception instances for equality.
  3141. *
  3142. * @package Comparator
  3143. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3144. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3145. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3146. * @link http://www.github.com/sebastianbergmann/comparator
  3147. */
  3148. class ExceptionComparator extends ObjectComparator
  3149. {
  3150. /**
  3151. * Returns whether the comparator can compare two values.
  3152. *
  3153. * @param mixed $expected The first value to compare
  3154. * @param mixed $actual The second value to compare
  3155. * @return boolean
  3156. */
  3157. public function accepts($expected, $actual)
  3158. {
  3159. return $expected instanceof \Exception && $actual instanceof \Exception;
  3160. }
  3161. /**
  3162. * Converts an object to an array containing all of its private, protected
  3163. * and public properties.
  3164. *
  3165. * @param object $object
  3166. * @return array
  3167. */
  3168. protected function toArray($object)
  3169. {
  3170. $array = parent::toArray($object);
  3171. unset(
  3172. $array['file'],
  3173. $array['line'],
  3174. $array['trace'],
  3175. $array['string'],
  3176. $array['xdebug_message']
  3177. );
  3178. return $array;
  3179. }
  3180. }
  3181. <?php
  3182. /*
  3183. * This file is part of the Comparator package.
  3184. *
  3185. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3186. *
  3187. * For the full copyright and license information, please view the LICENSE
  3188. * file that was distributed with this source code.
  3189. */
  3190. namespace SebastianBergmann\Comparator;
  3191. use DOMDocument;
  3192. use DOMNode;
  3193. /**
  3194. * Compares DOMNode instances for equality.
  3195. *
  3196. * @package Comparator
  3197. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3198. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3199. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3200. * @link http://www.github.com/sebastianbergmann/comparator
  3201. */
  3202. class DOMNodeComparator extends ObjectComparator
  3203. {
  3204. /**
  3205. * Returns whether the comparator can compare two values.
  3206. *
  3207. * @param mixed $expected The first value to compare
  3208. * @param mixed $actual The second value to compare
  3209. * @return boolean
  3210. */
  3211. public function accepts($expected, $actual)
  3212. {
  3213. return $expected instanceof DOMNode && $actual instanceof DOMNode;
  3214. }
  3215. /**
  3216. * Asserts that two values are equal.
  3217. *
  3218. * @param mixed $expected The first value to compare
  3219. * @param mixed $actual The second value to compare
  3220. * @param float $delta The allowed numerical distance between two values to
  3221. * consider them equal
  3222. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  3223. * comparison
  3224. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  3225. * ignored when comparing string values
  3226. * @throws ComparisonFailure Thrown when the comparison
  3227. * fails. Contains information about the
  3228. * specific errors that lead to the failure.
  3229. */
  3230. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  3231. {
  3232. $expectedAsString = $this->nodeToText($expected, true, $ignoreCase);
  3233. $actualAsString = $this->nodeToText($actual, true, $ignoreCase);
  3234. if ($expectedAsString !== $actualAsString) {
  3235. if ($expected instanceof DOMDocument) {
  3236. $type = 'documents';
  3237. } else {
  3238. $type = 'nodes';
  3239. }
  3240. throw new ComparisonFailure(
  3241. $expected,
  3242. $actual,
  3243. $expectedAsString,
  3244. $actualAsString,
  3245. false,
  3246. sprintf("Failed asserting that two DOM %s are equal.\n", $type)
  3247. );
  3248. }
  3249. }
  3250. /**
  3251. * Returns the normalized, whitespace-cleaned, and indented textual
  3252. * representation of a DOMNode.
  3253. *
  3254. * @param DOMNode $node
  3255. * @param boolean $canonicalize
  3256. * @param boolean $ignoreCase
  3257. * @return string
  3258. */
  3259. private function nodeToText(DOMNode $node, $canonicalize, $ignoreCase)
  3260. {
  3261. if ($canonicalize) {
  3262. $document = new DOMDocument;
  3263. $document->loadXML($node->C14N());
  3264. $node = $document;
  3265. }
  3266. if ($node instanceof DOMDocument) {
  3267. $document = $node;
  3268. } else {
  3269. $document = $node->ownerDocument;
  3270. }
  3271. $document->formatOutput = true;
  3272. $document->normalizeDocument();
  3273. if ($node instanceof DOMDocument) {
  3274. $text = $node->saveXML();
  3275. } else {
  3276. $text = $document->saveXML($node);
  3277. }
  3278. if ($ignoreCase) {
  3279. $text = strtolower($text);
  3280. }
  3281. return $text;
  3282. }
  3283. }
  3284. <?php
  3285. /*
  3286. * This file is part of the Comparator package.
  3287. *
  3288. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3289. *
  3290. * For the full copyright and license information, please view the LICENSE
  3291. * file that was distributed with this source code.
  3292. */
  3293. namespace SebastianBergmann\Comparator;
  3294. /**
  3295. * Compares scalar or NULL values for equality.
  3296. *
  3297. * @package Comparator
  3298. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3299. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3300. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3301. * @link http://www.github.com/sebastianbergmann/comparator
  3302. */
  3303. class ScalarComparator extends Comparator
  3304. {
  3305. /**
  3306. * Returns whether the comparator can compare two values.
  3307. *
  3308. * @param mixed $expected The first value to compare
  3309. * @param mixed $actual The second value to compare
  3310. * @return boolean
  3311. * @since Method available since Release 3.6.0
  3312. */
  3313. public function accepts($expected, $actual)
  3314. {
  3315. return ((is_scalar($expected) xor null === $expected) &&
  3316. (is_scalar($actual) xor null === $actual))
  3317. // allow comparison between strings and objects featuring __toString()
  3318. || (is_string($expected) && is_object($actual) && method_exists($actual, '__toString'))
  3319. || (is_object($expected) && method_exists($expected, '__toString') && is_string($actual));
  3320. }
  3321. /**
  3322. * Asserts that two values are equal.
  3323. *
  3324. * @param mixed $expected The first value to compare
  3325. * @param mixed $actual The second value to compare
  3326. * @param float $delta The allowed numerical distance between two values to
  3327. * consider them equal
  3328. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  3329. * comparison
  3330. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  3331. * ignored when comparing string values
  3332. * @throws ComparisonFailure Thrown when the comparison
  3333. * fails. Contains information about the
  3334. * specific errors that lead to the failure.
  3335. */
  3336. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  3337. {
  3338. $expectedToCompare = $expected;
  3339. $actualToCompare = $actual;
  3340. // always compare as strings to avoid strange behaviour
  3341. // otherwise 0 == 'Foobar'
  3342. if (is_string($expected) || is_string($actual)) {
  3343. $expectedToCompare = (string)$expectedToCompare;
  3344. $actualToCompare = (string)$actualToCompare;
  3345. if ($ignoreCase) {
  3346. $expectedToCompare = strtolower($expectedToCompare);
  3347. $actualToCompare = strtolower($actualToCompare);
  3348. }
  3349. }
  3350. if ($expectedToCompare != $actualToCompare) {
  3351. if (is_string($expected) && is_string($actual)) {
  3352. throw new ComparisonFailure(
  3353. $expected,
  3354. $actual,
  3355. $this->exporter->export($expected),
  3356. $this->exporter->export($actual),
  3357. false,
  3358. 'Failed asserting that two strings are equal.'
  3359. );
  3360. }
  3361. throw new ComparisonFailure(
  3362. $expected,
  3363. $actual,
  3364. // no diff is required
  3365. '',
  3366. '',
  3367. false,
  3368. sprintf(
  3369. 'Failed asserting that %s matches expected %s.',
  3370. $this->exporter->export($actual),
  3371. $this->exporter->export($expected)
  3372. )
  3373. );
  3374. }
  3375. }
  3376. }
  3377. <?php
  3378. /*
  3379. * This file is part of the Comparator package.
  3380. *
  3381. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3382. *
  3383. * For the full copyright and license information, please view the LICENSE
  3384. * file that was distributed with this source code.
  3385. */
  3386. namespace SebastianBergmann\Comparator;
  3387. /**
  3388. * Compares PHPUnit_Framework_MockObject_MockObject instances for equality.
  3389. *
  3390. * @package Comparator
  3391. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3392. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3393. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3394. * @link http://www.github.com/sebastianbergmann/comparator
  3395. */
  3396. class MockObjectComparator extends ObjectComparator
  3397. {
  3398. /**
  3399. * Returns whether the comparator can compare two values.
  3400. *
  3401. * @param mixed $expected The first value to compare
  3402. * @param mixed $actual The second value to compare
  3403. * @return boolean
  3404. */
  3405. public function accepts($expected, $actual)
  3406. {
  3407. return $expected instanceof \PHPUnit_Framework_MockObject_MockObject && $actual instanceof \PHPUnit_Framework_MockObject_MockObject;
  3408. }
  3409. /**
  3410. * Converts an object to an array containing all of its private, protected
  3411. * and public properties.
  3412. *
  3413. * @param object $object
  3414. * @return array
  3415. */
  3416. protected function toArray($object)
  3417. {
  3418. $array = parent::toArray($object);
  3419. unset($array['__phpunit_invocationMocker']);
  3420. return $array;
  3421. }
  3422. }<?php
  3423. /*
  3424. * This file is part of the Comparator package.
  3425. *
  3426. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3427. *
  3428. * For the full copyright and license information, please view the LICENSE
  3429. * file that was distributed with this source code.
  3430. */
  3431. namespace SebastianBergmann\Comparator;
  3432. /**
  3433. * Compares numerical values for equality.
  3434. *
  3435. * @package Comparator
  3436. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3437. * @author Alexander <iam.asm89@gmail.com>
  3438. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3439. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3440. * @link http://www.github.com/sebastianbergmann/comparator
  3441. */
  3442. class NumericComparator extends ScalarComparator
  3443. {
  3444. /**
  3445. * Returns whether the comparator can compare two values.
  3446. *
  3447. * @param mixed $expected The first value to compare
  3448. * @param mixed $actual The second value to compare
  3449. * @return boolean
  3450. */
  3451. public function accepts($expected, $actual)
  3452. {
  3453. // all numerical values, but not if one of them is a double
  3454. // or both of them are strings
  3455. return is_numeric($expected) && is_numeric($actual) &&
  3456. !(is_double($expected) || is_double($actual)) &&
  3457. !(is_string($expected) && is_string($actual));
  3458. }
  3459. /**
  3460. * Asserts that two values are equal.
  3461. *
  3462. * @param mixed $expected The first value to compare
  3463. * @param mixed $actual The second value to compare
  3464. * @param float $delta The allowed numerical distance between two values to
  3465. * consider them equal
  3466. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  3467. * comparison
  3468. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  3469. * ignored when comparing string values
  3470. * @throws ComparisonFailure Thrown when the comparison
  3471. * fails. Contains information about the
  3472. * specific errors that lead to the failure.
  3473. */
  3474. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  3475. {
  3476. if (is_infinite($actual) && is_infinite($expected)) {
  3477. return;
  3478. }
  3479. if ((is_infinite($actual) xor is_infinite($expected)) ||
  3480. (is_nan($actual) or is_nan($expected)) ||
  3481. abs($actual - $expected) > $delta) {
  3482. throw new ComparisonFailure(
  3483. $expected,
  3484. $actual,
  3485. '',
  3486. '',
  3487. false,
  3488. sprintf(
  3489. 'Failed asserting that %s matches expected %s.',
  3490. $this->exporter->export($actual),
  3491. $this->exporter->export($expected)
  3492. )
  3493. );
  3494. }
  3495. }
  3496. }
  3497. <?php
  3498. /*
  3499. * This file is part of the Comparator package.
  3500. *
  3501. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3502. *
  3503. * For the full copyright and license information, please view the LICENSE
  3504. * file that was distributed with this source code.
  3505. */
  3506. namespace SebastianBergmann\Comparator;
  3507. /**
  3508. * Factory for comparators which compare values for equality.
  3509. *
  3510. * @package Comparator
  3511. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3512. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3513. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3514. * @link http://www.github.com/sebastianbergmann/comparator
  3515. */
  3516. class Factory
  3517. {
  3518. /**
  3519. * @var Comparator[]
  3520. */
  3521. private $comparators = array();
  3522. /**
  3523. * @var Factory
  3524. */
  3525. private static $instance;
  3526. /**
  3527. * Constructs a new factory.
  3528. */
  3529. public function __construct()
  3530. {
  3531. $this->register(new TypeComparator);
  3532. $this->register(new ScalarComparator);
  3533. $this->register(new NumericComparator);
  3534. $this->register(new DoubleComparator);
  3535. $this->register(new ArrayComparator);
  3536. $this->register(new ResourceComparator);
  3537. $this->register(new ObjectComparator);
  3538. $this->register(new ExceptionComparator);
  3539. $this->register(new SplObjectStorageComparator);
  3540. $this->register(new DOMNodeComparator);
  3541. $this->register(new MockObjectComparator);
  3542. $this->register(new DateTimeComparator);
  3543. }
  3544. /**
  3545. * @return Factory
  3546. */
  3547. public static function getInstance()
  3548. {
  3549. if (self::$instance === null) {
  3550. self::$instance = new Factory;
  3551. }
  3552. return self::$instance;
  3553. }
  3554. /**
  3555. * Returns the correct comparator for comparing two values.
  3556. *
  3557. * @param mixed $expected The first value to compare
  3558. * @param mixed $actual The second value to compare
  3559. * @return Comparator
  3560. */
  3561. public function getComparatorFor($expected, $actual)
  3562. {
  3563. foreach ($this->comparators as $comparator) {
  3564. if ($comparator->accepts($expected, $actual)) {
  3565. return $comparator;
  3566. }
  3567. }
  3568. }
  3569. /**
  3570. * Registers a new comparator.
  3571. *
  3572. * This comparator will be returned by getInstance() if its accept() method
  3573. * returns TRUE for the compared values. It has higher priority than the
  3574. * existing comparators, meaning that its accept() method will be tested
  3575. * before those of the other comparators.
  3576. *
  3577. * @param Comparator $comparator The registered comparator
  3578. */
  3579. public function register(Comparator $comparator)
  3580. {
  3581. array_unshift($this->comparators, $comparator);
  3582. $comparator->setFactory($this);
  3583. }
  3584. /**
  3585. * Unregisters a comparator.
  3586. *
  3587. * This comparator will no longer be returned by getInstance().
  3588. *
  3589. * @param Comparator $comparator The unregistered comparator
  3590. */
  3591. public function unregister(Comparator $comparator)
  3592. {
  3593. foreach ($this->comparators as $key => $_comparator) {
  3594. if ($comparator === $_comparator) {
  3595. unset($this->comparators[$key]);
  3596. }
  3597. }
  3598. }
  3599. }
  3600. <?php
  3601. /*
  3602. * This file is part of the Comparator package.
  3603. *
  3604. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3605. *
  3606. * For the full copyright and license information, please view the LICENSE
  3607. * file that was distributed with this source code.
  3608. */
  3609. namespace SebastianBergmann\Comparator;
  3610. /**
  3611. * Compares doubles for equality.
  3612. *
  3613. * @package Comparator
  3614. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3615. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3616. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3617. * @link http://www.github.com/sebastianbergmann/comparator
  3618. */
  3619. class DoubleComparator extends NumericComparator
  3620. {
  3621. /**
  3622. * Smallest value available in PHP.
  3623. *
  3624. * @var float
  3625. */
  3626. const EPSILON = 0.0000000001;
  3627. /**
  3628. * Returns whether the comparator can compare two values.
  3629. *
  3630. * @param mixed $expected The first value to compare
  3631. * @param mixed $actual The second value to compare
  3632. * @return boolean
  3633. */
  3634. public function accepts($expected, $actual)
  3635. {
  3636. return (is_double($expected) || is_double($actual)) && is_numeric($expected) && is_numeric($actual);
  3637. }
  3638. /**
  3639. * Asserts that two values are equal.
  3640. *
  3641. * @param mixed $expected The first value to compare
  3642. * @param mixed $actual The second value to compare
  3643. * @param float $delta The allowed numerical distance between two values to
  3644. * consider them equal
  3645. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  3646. * comparison
  3647. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  3648. * ignored when comparing string values
  3649. * @throws ComparisonFailure Thrown when the comparison
  3650. * fails. Contains information about the
  3651. * specific errors that lead to the failure.
  3652. */
  3653. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  3654. {
  3655. if ($delta == 0) {
  3656. $delta = self::EPSILON;
  3657. }
  3658. parent::assertEquals($expected, $actual, $delta, $canonicalize, $ignoreCase);
  3659. }
  3660. }
  3661. <?php
  3662. /*
  3663. * This file is part of the Comparator package.
  3664. *
  3665. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3666. *
  3667. * For the full copyright and license information, please view the LICENSE
  3668. * file that was distributed with this source code.
  3669. */
  3670. namespace SebastianBergmann\Comparator;
  3671. use SebastianBergmann\Diff\Differ;
  3672. /**
  3673. * Thrown when an assertion for string equality failed.
  3674. *
  3675. * @package Comparator
  3676. * @author Sebastian Bergmann <sebastian@phpunit.de>
  3677. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3678. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3679. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3680. * @link http://www.github.com/sebastianbergmann/comparator
  3681. */
  3682. class ComparisonFailure extends \RuntimeException
  3683. {
  3684. /**
  3685. * Expected value of the retrieval which does not match $actual.
  3686. * @var mixed
  3687. */
  3688. protected $expected;
  3689. /**
  3690. * Actually retrieved value which does not match $expected.
  3691. * @var mixed
  3692. */
  3693. protected $actual;
  3694. /**
  3695. * The string representation of the expected value
  3696. * @var string
  3697. */
  3698. protected $expectedAsString;
  3699. /**
  3700. * The string representation of the actual value
  3701. * @var string
  3702. */
  3703. protected $actualAsString;
  3704. /**
  3705. * @var boolean
  3706. */
  3707. protected $identical;
  3708. /**
  3709. * Optional message which is placed in front of the first line
  3710. * returned by toString().
  3711. * @var string
  3712. */
  3713. protected $message;
  3714. /**
  3715. * Initialises with the expected value and the actual value.
  3716. *
  3717. * @param mixed $expected Expected value retrieved.
  3718. * @param mixed $actual Actual value retrieved.
  3719. * @param string $expectedAsString
  3720. * @param string $actualAsString
  3721. * @param boolean $identical
  3722. * @param string $message A string which is prefixed on all returned lines
  3723. * in the difference output.
  3724. */
  3725. public function __construct($expected, $actual, $expectedAsString, $actualAsString, $identical = false, $message = '')
  3726. {
  3727. $this->expected = $expected;
  3728. $this->actual = $actual;
  3729. $this->expectedAsString = $expectedAsString;
  3730. $this->actualAsString = $actualAsString;
  3731. $this->message = $message;
  3732. }
  3733. /**
  3734. * @return mixed
  3735. */
  3736. public function getActual()
  3737. {
  3738. return $this->actual;
  3739. }
  3740. /**
  3741. * @return mixed
  3742. */
  3743. public function getExpected()
  3744. {
  3745. return $this->expected;
  3746. }
  3747. /**
  3748. * @return string
  3749. */
  3750. public function getActualAsString()
  3751. {
  3752. return $this->actualAsString;
  3753. }
  3754. /**
  3755. * @return string
  3756. */
  3757. public function getExpectedAsString()
  3758. {
  3759. return $this->expectedAsString;
  3760. }
  3761. /**
  3762. * @return string
  3763. */
  3764. public function getDiff()
  3765. {
  3766. if (!$this->actualAsString && !$this->expectedAsString) {
  3767. return '';
  3768. }
  3769. $differ = new Differ("\n--- Expected\n+++ Actual\n");
  3770. return $differ->diff($this->expectedAsString, $this->actualAsString);
  3771. }
  3772. /**
  3773. * @return string
  3774. */
  3775. public function toString()
  3776. {
  3777. return $this->message . $this->getDiff();
  3778. }
  3779. }
  3780. Copyright (c) 2013 Konstantin Kudryashov <ever.zet@gmail.com>
  3781. Marcello Duarte <marcello.duarte@gmail.com>
  3782. Permission is hereby granted, free of charge, to any person
  3783. obtaining a copy of this software and associated documentation
  3784. files (the "Software"), to deal in the Software without
  3785. restriction, including without limitation the rights to use,
  3786. copy, modify, merge, publish, distribute, sublicense, and/or sell
  3787. copies of the Software, and to permit persons to whom the
  3788. Software is furnished to do so, subject to the following
  3789. conditions:
  3790. The above copyright notice and this permission notice shall be
  3791. included in all copies or substantial portions of the Software.
  3792. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  3793. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  3794. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  3795. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  3796. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  3797. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  3798. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  3799. OTHER DEALINGS IN THE SOFTWARE.
  3800. <?php
  3801. /*
  3802. * This file is part of the Prophecy.
  3803. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  3804. * Marcello Duarte <marcello.duarte@gmail.com>
  3805. *
  3806. * For the full copyright and license information, please view the LICENSE
  3807. * file that was distributed with this source code.
  3808. */
  3809. namespace Prophecy\Prophecy;
  3810. /**
  3811. * Prophecies revealer interface.
  3812. *
  3813. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  3814. */
  3815. interface RevealerInterface
  3816. {
  3817. /**
  3818. * Unwraps value(s).
  3819. *
  3820. * @param mixed $value
  3821. *
  3822. * @return mixed
  3823. */
  3824. public function reveal($value);
  3825. }
  3826. <?php
  3827. /*
  3828. * This file is part of the Prophecy.
  3829. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  3830. * Marcello Duarte <marcello.duarte@gmail.com>
  3831. *
  3832. * For the full copyright and license information, please view the LICENSE
  3833. * file that was distributed with this source code.
  3834. */
  3835. namespace Prophecy\Prophecy;
  3836. /**
  3837. * Controllable doubles interface.
  3838. *
  3839. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  3840. */
  3841. interface ProphecySubjectInterface
  3842. {
  3843. /**
  3844. * Sets subject prophecy.
  3845. *
  3846. * @param ProphecyInterface $prophecy
  3847. */
  3848. public function setProphecy(ProphecyInterface $prophecy);
  3849. /**
  3850. * Returns subject prophecy.
  3851. *
  3852. * @return ProphecyInterface
  3853. */
  3854. public function getProphecy();
  3855. }
  3856. <?php
  3857. /*
  3858. * This file is part of the Prophecy.
  3859. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  3860. * Marcello Duarte <marcello.duarte@gmail.com>
  3861. *
  3862. * For the full copyright and license information, please view the LICENSE
  3863. * file that was distributed with this source code.
  3864. */
  3865. namespace Prophecy\Prophecy;
  3866. /**
  3867. * Basic prophecies revealer.
  3868. *
  3869. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  3870. */
  3871. class Revealer implements RevealerInterface
  3872. {
  3873. /**
  3874. * Unwraps value(s).
  3875. *
  3876. * @param mixed $value
  3877. *
  3878. * @return mixed
  3879. */
  3880. public function reveal($value)
  3881. {
  3882. if (is_array($value)) {
  3883. return array_map(array($this, __FUNCTION__), $value);
  3884. }
  3885. if (!is_object($value)) {
  3886. return $value;
  3887. }
  3888. if ($value instanceof ProphecyInterface) {
  3889. $value = $value->reveal();
  3890. }
  3891. return $value;
  3892. }
  3893. }
  3894. <?php
  3895. /*
  3896. * This file is part of the Prophecy.
  3897. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  3898. * Marcello Duarte <marcello.duarte@gmail.com>
  3899. *
  3900. * For the full copyright and license information, please view the LICENSE
  3901. * file that was distributed with this source code.
  3902. */
  3903. namespace Prophecy\Prophecy;
  3904. /**
  3905. * Core Prophecy interface.
  3906. *
  3907. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  3908. */
  3909. interface ProphecyInterface
  3910. {
  3911. /**
  3912. * Reveals prophecy object (double) .
  3913. *
  3914. * @return object
  3915. */
  3916. public function reveal();
  3917. }
  3918. <?php
  3919. /*
  3920. * This file is part of the Prophecy.
  3921. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  3922. * Marcello Duarte <marcello.duarte@gmail.com>
  3923. *
  3924. * For the full copyright and license information, please view the LICENSE
  3925. * file that was distributed with this source code.
  3926. */
  3927. namespace Prophecy\Prophecy;
  3928. use SebastianBergmann\Comparator\ComparisonFailure;
  3929. use Prophecy\Comparator\Factory as ComparatorFactory;
  3930. use Prophecy\Call\Call;
  3931. use Prophecy\Doubler\LazyDouble;
  3932. use Prophecy\Argument\ArgumentsWildcard;
  3933. use Prophecy\Call\CallCenter;
  3934. use Prophecy\Exception\Prophecy\ObjectProphecyException;
  3935. use Prophecy\Exception\Prophecy\MethodProphecyException;
  3936. use Prophecy\Exception\Prediction\AggregateException;
  3937. use Prophecy\Exception\Prediction\PredictionException;
  3938. /**
  3939. * Object prophecy.
  3940. *
  3941. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  3942. */
  3943. class ObjectProphecy implements ProphecyInterface
  3944. {
  3945. private $lazyDouble;
  3946. private $callCenter;
  3947. private $revealer;
  3948. private $comparatorFactory;
  3949. /**
  3950. * @var MethodProphecy[][]
  3951. */
  3952. private $methodProphecies = array();
  3953. /**
  3954. * Initializes object prophecy.
  3955. *
  3956. * @param LazyDouble $lazyDouble
  3957. * @param CallCenter $callCenter
  3958. * @param RevealerInterface $revealer
  3959. * @param ComparatorFactory $comparatorFactory
  3960. */
  3961. public function __construct(
  3962. LazyDouble $lazyDouble,
  3963. CallCenter $callCenter = null,
  3964. RevealerInterface $revealer = null,
  3965. ComparatorFactory $comparatorFactory = null
  3966. ) {
  3967. $this->lazyDouble = $lazyDouble;
  3968. $this->callCenter = $callCenter ?: new CallCenter;
  3969. $this->revealer = $revealer ?: new Revealer;
  3970. $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance();
  3971. }
  3972. /**
  3973. * Forces double to extend specific class.
  3974. *
  3975. * @param string $class
  3976. *
  3977. * @return $this
  3978. */
  3979. public function willExtend($class)
  3980. {
  3981. $this->lazyDouble->setParentClass($class);
  3982. return $this;
  3983. }
  3984. /**
  3985. * Forces double to implement specific interface.
  3986. *
  3987. * @param string $interface
  3988. *
  3989. * @return $this
  3990. */
  3991. public function willImplement($interface)
  3992. {
  3993. $this->lazyDouble->addInterface($interface);
  3994. return $this;
  3995. }
  3996. /**
  3997. * Sets constructor arguments.
  3998. *
  3999. * @param array $arguments
  4000. *
  4001. * @return $this
  4002. */
  4003. public function willBeConstructedWith(array $arguments = null)
  4004. {
  4005. $this->lazyDouble->setArguments($arguments);
  4006. return $this;
  4007. }
  4008. /**
  4009. * Reveals double.
  4010. *
  4011. * @return object
  4012. *
  4013. * @throws \Prophecy\Exception\Prophecy\ObjectProphecyException If double doesn't implement needed interface
  4014. */
  4015. public function reveal()
  4016. {
  4017. $double = $this->lazyDouble->getInstance();
  4018. if (null === $double || !$double instanceof ProphecySubjectInterface) {
  4019. throw new ObjectProphecyException(
  4020. "Generated double must implement ProphecySubjectInterface, but it does not.\n".
  4021. 'It seems you have wrongly configured doubler without required ClassPatch.',
  4022. $this
  4023. );
  4024. }
  4025. $double->setProphecy($this);
  4026. return $double;
  4027. }
  4028. /**
  4029. * Adds method prophecy to object prophecy.
  4030. *
  4031. * @param MethodProphecy $methodProphecy
  4032. *
  4033. * @throws \Prophecy\Exception\Prophecy\MethodProphecyException If method prophecy doesn't
  4034. * have arguments wildcard
  4035. */
  4036. public function addMethodProphecy(MethodProphecy $methodProphecy)
  4037. {
  4038. $argumentsWildcard = $methodProphecy->getArgumentsWildcard();
  4039. if (null === $argumentsWildcard) {
  4040. throw new MethodProphecyException(sprintf(
  4041. "Can not add prophecy for a method `%s::%s()`\n".
  4042. "as you did not specify arguments wildcard for it.",
  4043. get_class($this->reveal()),
  4044. $methodProphecy->getMethodName()
  4045. ), $methodProphecy);
  4046. }
  4047. $methodName = $methodProphecy->getMethodName();
  4048. if (!isset($this->methodProphecies[$methodName])) {
  4049. $this->methodProphecies[$methodName] = array();
  4050. }
  4051. $this->methodProphecies[$methodName][] = $methodProphecy;
  4052. }
  4053. /**
  4054. * Returns either all or related to single method prophecies.
  4055. *
  4056. * @param null|string $methodName
  4057. *
  4058. * @return MethodProphecy[]
  4059. */
  4060. public function getMethodProphecies($methodName = null)
  4061. {
  4062. if (null === $methodName) {
  4063. return $this->methodProphecies;
  4064. }
  4065. if (!isset($this->methodProphecies[$methodName])) {
  4066. return array();
  4067. }
  4068. return $this->methodProphecies[$methodName];
  4069. }
  4070. /**
  4071. * Makes specific method call.
  4072. *
  4073. * @param string $methodName
  4074. * @param array $arguments
  4075. *
  4076. * @return mixed
  4077. */
  4078. public function makeProphecyMethodCall($methodName, array $arguments)
  4079. {
  4080. $arguments = $this->revealer->reveal($arguments);
  4081. $return = $this->callCenter->makeCall($this, $methodName, $arguments);
  4082. return $this->revealer->reveal($return);
  4083. }
  4084. /**
  4085. * Finds calls by method name & arguments wildcard.
  4086. *
  4087. * @param string $methodName
  4088. * @param ArgumentsWildcard $wildcard
  4089. *
  4090. * @return Call[]
  4091. */
  4092. public function findProphecyMethodCalls($methodName, ArgumentsWildcard $wildcard)
  4093. {
  4094. return $this->callCenter->findCalls($methodName, $wildcard);
  4095. }
  4096. /**
  4097. * Checks that registered method predictions do not fail.
  4098. *
  4099. * @throws \Prophecy\Exception\Prediction\AggregateException If any of registered predictions fail
  4100. */
  4101. public function checkProphecyMethodsPredictions()
  4102. {
  4103. $exception = new AggregateException(sprintf("%s:\n", get_class($this->reveal())));
  4104. $exception->setObjectProphecy($this);
  4105. foreach ($this->methodProphecies as $prophecies) {
  4106. foreach ($prophecies as $prophecy) {
  4107. try {
  4108. $prophecy->checkPrediction();
  4109. } catch (PredictionException $e) {
  4110. $exception->append($e);
  4111. }
  4112. }
  4113. }
  4114. if (count($exception->getExceptions())) {
  4115. throw $exception;
  4116. }
  4117. }
  4118. /**
  4119. * Creates new method prophecy using specified method name and arguments.
  4120. *
  4121. * @param string $methodName
  4122. * @param array $arguments
  4123. *
  4124. * @return MethodProphecy
  4125. */
  4126. public function __call($methodName, array $arguments)
  4127. {
  4128. $arguments = new ArgumentsWildcard($this->revealer->reveal($arguments));
  4129. foreach ($this->getMethodProphecies($methodName) as $prophecy) {
  4130. $argumentsWildcard = $prophecy->getArgumentsWildcard();
  4131. $comparator = $this->comparatorFactory->getComparatorFor(
  4132. $argumentsWildcard, $arguments
  4133. );
  4134. try {
  4135. $comparator->assertEquals($argumentsWildcard, $arguments);
  4136. return $prophecy;
  4137. } catch (ComparisonFailure $failure) {}
  4138. }
  4139. return new MethodProphecy($this, $methodName, $arguments);
  4140. }
  4141. /**
  4142. * Tries to get property value from double.
  4143. *
  4144. * @param string $name
  4145. */
  4146. public function __get($name)
  4147. {
  4148. return $this->reveal()->$name;
  4149. }
  4150. /**
  4151. * Tries to set property value to double.
  4152. *
  4153. * @param string $name
  4154. * @param string $value
  4155. */
  4156. public function __set($name, $value)
  4157. {
  4158. $this->reveal()->$name = $this->revealer->reveal($value);
  4159. }
  4160. }
  4161. <?php
  4162. /*
  4163. * This file is part of the Prophecy.
  4164. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4165. * Marcello Duarte <marcello.duarte@gmail.com>
  4166. *
  4167. * For the full copyright and license information, please view the LICENSE
  4168. * file that was distributed with this source code.
  4169. */
  4170. namespace Prophecy\Prophecy;
  4171. use Prophecy\Argument;
  4172. use Prophecy\Promise;
  4173. use Prophecy\Prediction;
  4174. use Prophecy\Exception\Doubler\MethodNotFoundException;
  4175. use Prophecy\Exception\InvalidArgumentException;
  4176. use Prophecy\Exception\Prophecy\MethodProphecyException;
  4177. /**
  4178. * Method prophecy.
  4179. *
  4180. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4181. */
  4182. class MethodProphecy
  4183. {
  4184. private $objectProphecy;
  4185. private $methodName;
  4186. private $argumentsWildcard;
  4187. private $promise;
  4188. private $prediction;
  4189. private $checkedPredictions = array();
  4190. private $bound = false;
  4191. /**
  4192. * Initializes method prophecy.
  4193. *
  4194. * @param ObjectProphecy $objectProphecy
  4195. * @param string $methodName
  4196. * @param null|Argument\ArgumentsWildcard|array $arguments
  4197. *
  4198. * @throws \Prophecy\Exception\Doubler\MethodNotFoundException If method not found
  4199. */
  4200. public function __construct(ObjectProphecy $objectProphecy, $methodName, $arguments = null)
  4201. {
  4202. $double = $objectProphecy->reveal();
  4203. if (!method_exists($double, $methodName)) {
  4204. throw new MethodNotFoundException(sprintf(
  4205. 'Method `%s::%s()` is not defined.', get_class($double), $methodName
  4206. ), get_class($double), $methodName, $arguments);
  4207. }
  4208. $this->objectProphecy = $objectProphecy;
  4209. $this->methodName = $methodName;
  4210. $reflectedMethod = new \ReflectionMethod($double, $methodName);
  4211. if ($reflectedMethod->isFinal()) {
  4212. throw new MethodProphecyException(sprintf(
  4213. "Can not add prophecy for a method `%s::%s()`\n".
  4214. "as it is a final method.",
  4215. get_class($double),
  4216. $methodName
  4217. ), $this);
  4218. }
  4219. if (null !== $arguments) {
  4220. $this->withArguments($arguments);
  4221. }
  4222. }
  4223. /**
  4224. * Sets argument wildcard.
  4225. *
  4226. * @param array|Argument\ArgumentsWildcard $arguments
  4227. *
  4228. * @return $this
  4229. *
  4230. * @throws \Prophecy\Exception\InvalidArgumentException
  4231. */
  4232. public function withArguments($arguments)
  4233. {
  4234. if (is_array($arguments)) {
  4235. $arguments = new Argument\ArgumentsWildcard($arguments);
  4236. }
  4237. if (!$arguments instanceof Argument\ArgumentsWildcard) {
  4238. throw new InvalidArgumentException(sprintf(
  4239. "Either an array or an instance of ArgumentsWildcard expected as\n".
  4240. 'a `MethodProphecy::withArguments()` argument, but got %s.',
  4241. gettype($arguments)
  4242. ));
  4243. }
  4244. $this->argumentsWildcard = $arguments;
  4245. return $this;
  4246. }
  4247. /**
  4248. * Sets custom promise to the prophecy.
  4249. *
  4250. * @param callable|Promise\PromiseInterface $promise
  4251. *
  4252. * @return $this
  4253. *
  4254. * @throws \Prophecy\Exception\InvalidArgumentException
  4255. */
  4256. public function will($promise)
  4257. {
  4258. if (is_callable($promise)) {
  4259. $promise = new Promise\CallbackPromise($promise);
  4260. }
  4261. if (!$promise instanceof Promise\PromiseInterface) {
  4262. throw new InvalidArgumentException(sprintf(
  4263. 'Expected callable or instance of PromiseInterface, but got %s.',
  4264. gettype($promise)
  4265. ));
  4266. }
  4267. $this->bindToObjectProphecy();
  4268. $this->promise = $promise;
  4269. return $this;
  4270. }
  4271. /**
  4272. * Sets return promise to the prophecy.
  4273. *
  4274. * @see Prophecy\Promise\ReturnPromise
  4275. *
  4276. * @return $this
  4277. */
  4278. public function willReturn()
  4279. {
  4280. return $this->will(new Promise\ReturnPromise(func_get_args()));
  4281. }
  4282. /**
  4283. * Sets return argument promise to the prophecy.
  4284. *
  4285. * @param int $index The zero-indexed number of the argument to return
  4286. *
  4287. * @see Prophecy\Promise\ReturnArgumentPromise
  4288. *
  4289. * @return $this
  4290. */
  4291. public function willReturnArgument($index = 0)
  4292. {
  4293. return $this->will(new Promise\ReturnArgumentPromise($index));
  4294. }
  4295. /**
  4296. * Sets throw promise to the prophecy.
  4297. *
  4298. * @see Prophecy\Promise\ThrowPromise
  4299. *
  4300. * @param string|\Exception $exception Exception class or instance
  4301. *
  4302. * @return $this
  4303. */
  4304. public function willThrow($exception)
  4305. {
  4306. return $this->will(new Promise\ThrowPromise($exception));
  4307. }
  4308. /**
  4309. * Sets custom prediction to the prophecy.
  4310. *
  4311. * @param callable|Prediction\PredictionInterface $prediction
  4312. *
  4313. * @return $this
  4314. *
  4315. * @throws \Prophecy\Exception\InvalidArgumentException
  4316. */
  4317. public function should($prediction)
  4318. {
  4319. if (is_callable($prediction)) {
  4320. $prediction = new Prediction\CallbackPrediction($prediction);
  4321. }
  4322. if (!$prediction instanceof Prediction\PredictionInterface) {
  4323. throw new InvalidArgumentException(sprintf(
  4324. 'Expected callable or instance of PredictionInterface, but got %s.',
  4325. gettype($prediction)
  4326. ));
  4327. }
  4328. $this->bindToObjectProphecy();
  4329. $this->prediction = $prediction;
  4330. return $this;
  4331. }
  4332. /**
  4333. * Sets call prediction to the prophecy.
  4334. *
  4335. * @see Prophecy\Prediction\CallPrediction
  4336. *
  4337. * @return $this
  4338. */
  4339. public function shouldBeCalled()
  4340. {
  4341. return $this->should(new Prediction\CallPrediction);
  4342. }
  4343. /**
  4344. * Sets no calls prediction to the prophecy.
  4345. *
  4346. * @see Prophecy\Prediction\NoCallsPrediction
  4347. *
  4348. * @return $this
  4349. */
  4350. public function shouldNotBeCalled()
  4351. {
  4352. return $this->should(new Prediction\NoCallsPrediction);
  4353. }
  4354. /**
  4355. * Sets call times prediction to the prophecy.
  4356. *
  4357. * @see Prophecy\Prediction\CallTimesPrediction
  4358. *
  4359. * @param $count
  4360. *
  4361. * @return $this
  4362. */
  4363. public function shouldBeCalledTimes($count)
  4364. {
  4365. return $this->should(new Prediction\CallTimesPrediction($count));
  4366. }
  4367. /**
  4368. * Checks provided prediction immediately.
  4369. *
  4370. * @param callable|Prediction\PredictionInterface $prediction
  4371. *
  4372. * @return $this
  4373. *
  4374. * @throws \Prophecy\Exception\InvalidArgumentException
  4375. */
  4376. public function shouldHave($prediction)
  4377. {
  4378. if (is_callable($prediction)) {
  4379. $prediction = new Prediction\CallbackPrediction($prediction);
  4380. }
  4381. if (!$prediction instanceof Prediction\PredictionInterface) {
  4382. throw new InvalidArgumentException(sprintf(
  4383. 'Expected callable or instance of PredictionInterface, but got %s.',
  4384. gettype($prediction)
  4385. ));
  4386. }
  4387. if (null === $this->promise) {
  4388. $this->willReturn();
  4389. }
  4390. $calls = $this->getObjectProphecy()->findProphecyMethodCalls(
  4391. $this->getMethodName(),
  4392. $this->getArgumentsWildcard()
  4393. );
  4394. try {
  4395. $prediction->check($calls, $this->getObjectProphecy(), $this);
  4396. $this->checkedPredictions[] = $prediction;
  4397. } catch (\Exception $e) {
  4398. $this->checkedPredictions[] = $prediction;
  4399. throw $e;
  4400. }
  4401. return $this;
  4402. }
  4403. /**
  4404. * Checks call prediction.
  4405. *
  4406. * @see Prophecy\Prediction\CallPrediction
  4407. *
  4408. * @return $this
  4409. */
  4410. public function shouldHaveBeenCalled()
  4411. {
  4412. return $this->shouldHave(new Prediction\CallPrediction);
  4413. }
  4414. /**
  4415. * Checks no calls prediction.
  4416. *
  4417. * @see Prophecy\Prediction\NoCallsPrediction
  4418. *
  4419. * @return $this
  4420. */
  4421. public function shouldNotHaveBeenCalled()
  4422. {
  4423. return $this->shouldHave(new Prediction\NoCallsPrediction);
  4424. }
  4425. /**
  4426. * Checks no calls prediction.
  4427. *
  4428. * @see Prophecy\Prediction\NoCallsPrediction
  4429. * @deprecated
  4430. *
  4431. * @return $this
  4432. */
  4433. public function shouldNotBeenCalled()
  4434. {
  4435. return $this->shouldNotHaveBeenCalled();
  4436. }
  4437. /**
  4438. * Checks call times prediction.
  4439. *
  4440. * @see Prophecy\Prediction\CallTimesPrediction
  4441. *
  4442. * @param int $count
  4443. *
  4444. * @return $this
  4445. */
  4446. public function shouldHaveBeenCalledTimes($count)
  4447. {
  4448. return $this->shouldHave(new Prediction\CallTimesPrediction($count));
  4449. }
  4450. /**
  4451. * Checks currently registered [with should(...)] prediction.
  4452. */
  4453. public function checkPrediction()
  4454. {
  4455. if (null === $this->prediction) {
  4456. return;
  4457. }
  4458. $this->shouldHave($this->prediction);
  4459. }
  4460. /**
  4461. * Returns currently registered promise.
  4462. *
  4463. * @return null|Promise\PromiseInterface
  4464. */
  4465. public function getPromise()
  4466. {
  4467. return $this->promise;
  4468. }
  4469. /**
  4470. * Returns currently registered prediction.
  4471. *
  4472. * @return null|Prediction\PredictionInterface
  4473. */
  4474. public function getPrediction()
  4475. {
  4476. return $this->prediction;
  4477. }
  4478. /**
  4479. * Returns predictions that were checked on this object.
  4480. *
  4481. * @return Prediction\PredictionInterface[]
  4482. */
  4483. public function getCheckedPredictions()
  4484. {
  4485. return $this->checkedPredictions;
  4486. }
  4487. /**
  4488. * Returns object prophecy this method prophecy is tied to.
  4489. *
  4490. * @return ObjectProphecy
  4491. */
  4492. public function getObjectProphecy()
  4493. {
  4494. return $this->objectProphecy;
  4495. }
  4496. /**
  4497. * Returns method name.
  4498. *
  4499. * @return string
  4500. */
  4501. public function getMethodName()
  4502. {
  4503. return $this->methodName;
  4504. }
  4505. /**
  4506. * Returns arguments wildcard.
  4507. *
  4508. * @return Argument\ArgumentsWildcard
  4509. */
  4510. public function getArgumentsWildcard()
  4511. {
  4512. return $this->argumentsWildcard;
  4513. }
  4514. private function bindToObjectProphecy()
  4515. {
  4516. if ($this->bound) {
  4517. return;
  4518. }
  4519. $this->getObjectProphecy()->addMethodProphecy($this);
  4520. $this->bound = true;
  4521. }
  4522. }
  4523. <?php
  4524. /*
  4525. * This file is part of the Prophecy.
  4526. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4527. * Marcello Duarte <marcello.duarte@gmail.com>
  4528. *
  4529. * For the full copyright and license information, please view the LICENSE
  4530. * file that was distributed with this source code.
  4531. */
  4532. namespace Prophecy\Comparator;
  4533. use SebastianBergmann\Comparator\Comparator;
  4534. use SebastianBergmann\Comparator\ComparisonFailure;
  4535. /**
  4536. * Closure comparator.
  4537. *
  4538. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4539. */
  4540. final class ClosureComparator extends Comparator
  4541. {
  4542. public function accepts($expected, $actual)
  4543. {
  4544. return is_object($expected) && $expected instanceof \Closure
  4545. && is_object($actual) && $actual instanceof \Closure;
  4546. }
  4547. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  4548. {
  4549. throw new ComparisonFailure(
  4550. $expected,
  4551. $actual,
  4552. // we don't need a diff
  4553. '',
  4554. '',
  4555. false,
  4556. 'all closures are born different'
  4557. );
  4558. }
  4559. }
  4560. <?php
  4561. /*
  4562. * This file is part of the Prophecy.
  4563. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4564. * Marcello Duarte <marcello.duarte@gmail.com>
  4565. *
  4566. * For the full copyright and license information, please view the LICENSE
  4567. * file that was distributed with this source code.
  4568. */
  4569. namespace Prophecy\Comparator;
  4570. use SebastianBergmann\Comparator\Factory as BaseFactory;
  4571. /**
  4572. * Prophecy comparator factory.
  4573. *
  4574. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4575. */
  4576. final class Factory extends BaseFactory
  4577. {
  4578. /**
  4579. * @var Factory
  4580. */
  4581. private static $instance;
  4582. public function __construct()
  4583. {
  4584. parent::__construct();
  4585. $this->register(new ClosureComparator());
  4586. }
  4587. /**
  4588. * @return Factory
  4589. */
  4590. public static function getInstance()
  4591. {
  4592. if (self::$instance === null) {
  4593. self::$instance = new Factory;
  4594. }
  4595. return self::$instance;
  4596. }
  4597. }
  4598. <?php
  4599. /*
  4600. * This file is part of the Prophecy.
  4601. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4602. * Marcello Duarte <marcello.duarte@gmail.com>
  4603. *
  4604. * For the full copyright and license information, please view the LICENSE
  4605. * file that was distributed with this source code.
  4606. */
  4607. namespace Prophecy;
  4608. use Prophecy\Argument\Token;
  4609. /**
  4610. * Argument tokens shortcuts.
  4611. *
  4612. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4613. */
  4614. class Argument
  4615. {
  4616. /**
  4617. * Checks that argument is exact value or object.
  4618. *
  4619. * @param mixed $value
  4620. *
  4621. * @return Token\ExactValueToken
  4622. */
  4623. public static function exact($value)
  4624. {
  4625. return new Token\ExactValueToken($value);
  4626. }
  4627. /**
  4628. * Checks that argument is of specific type or instance of specific class.
  4629. *
  4630. * @param string $type Type name (`integer`, `string`) or full class name
  4631. *
  4632. * @return Token\TypeToken
  4633. */
  4634. public static function type($type)
  4635. {
  4636. return new Token\TypeToken($type);
  4637. }
  4638. /**
  4639. * Checks that argument object has specific state.
  4640. *
  4641. * @param string $methodName
  4642. * @param mixed $value
  4643. *
  4644. * @return Token\ObjectStateToken
  4645. */
  4646. public static function which($methodName, $value)
  4647. {
  4648. return new Token\ObjectStateToken($methodName, $value);
  4649. }
  4650. /**
  4651. * Checks that argument matches provided callback.
  4652. *
  4653. * @param callable $callback
  4654. *
  4655. * @return Token\CallbackToken
  4656. */
  4657. public static function that($callback)
  4658. {
  4659. return new Token\CallbackToken($callback);
  4660. }
  4661. /**
  4662. * Matches any single value.
  4663. *
  4664. * @return Token\AnyValueToken
  4665. */
  4666. public static function any()
  4667. {
  4668. return new Token\AnyValueToken;
  4669. }
  4670. /**
  4671. * Matches all values to the rest of the signature.
  4672. *
  4673. * @return Token\AnyValuesToken
  4674. */
  4675. public static function cetera()
  4676. {
  4677. return new Token\AnyValuesToken;
  4678. }
  4679. /**
  4680. * Checks that argument matches all tokens
  4681. *
  4682. * @param mixed ... a list of tokens
  4683. *
  4684. * @return Token\LogicalAndToken
  4685. */
  4686. public static function allOf()
  4687. {
  4688. return new Token\LogicalAndToken(func_get_args());
  4689. }
  4690. /**
  4691. * Checks that argument array or countable object has exact number of elements.
  4692. *
  4693. * @param integer $value array elements count
  4694. *
  4695. * @return Token\ArrayCountToken
  4696. */
  4697. public static function size($value)
  4698. {
  4699. return new Token\ArrayCountToken($value);
  4700. }
  4701. /**
  4702. * Checks that argument array contains (key, value) pair
  4703. *
  4704. * @param mixed $key exact value or token
  4705. * @param mixed $value exact value or token
  4706. *
  4707. * @return Token\ArrayEntryToken
  4708. */
  4709. public static function withEntry($key, $value)
  4710. {
  4711. return new Token\ArrayEntryToken($key, $value);
  4712. }
  4713. /**
  4714. * Checks that arguments array entries all match value
  4715. *
  4716. * @param mixed $value
  4717. *
  4718. * @return Token\ArrayEveryEntryToken
  4719. */
  4720. public static function withEveryEntry($value)
  4721. {
  4722. return new Token\ArrayEveryEntryToken($value);
  4723. }
  4724. /**
  4725. * Checks that argument array contains value
  4726. *
  4727. * @param mixed $value
  4728. *
  4729. * @return Token\ArrayEntryToken
  4730. */
  4731. public static function containing($value)
  4732. {
  4733. return new Token\ArrayEntryToken(self::any(), $value);
  4734. }
  4735. /**
  4736. * Checks that argument array has key
  4737. *
  4738. * @param mixed $key exact value or token
  4739. *
  4740. * @return Token\ArrayEntryToken
  4741. */
  4742. public static function withKey($key)
  4743. {
  4744. return new Token\ArrayEntryToken($key, self::any());
  4745. }
  4746. /**
  4747. * Checks that argument does not match the value|token.
  4748. *
  4749. * @param mixed $value either exact value or argument token
  4750. *
  4751. * @return Token\LogicalNotToken
  4752. */
  4753. public static function not($value)
  4754. {
  4755. return new Token\LogicalNotToken($value);
  4756. }
  4757. /**
  4758. * @param string $value
  4759. *
  4760. * @return Token\StringContainsToken
  4761. */
  4762. public static function containingString($value)
  4763. {
  4764. return new Token\StringContainsToken($value);
  4765. }
  4766. /**
  4767. * Checks that argument is identical value.
  4768. *
  4769. * @param mixed $value
  4770. *
  4771. * @return Token\IdenticalValueToken
  4772. */
  4773. public static function is($value)
  4774. {
  4775. return new Token\IdenticalValueToken($value);
  4776. }
  4777. }
  4778. <?php
  4779. /*
  4780. * This file is part of the Prophecy.
  4781. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4782. * Marcello Duarte <marcello.duarte@gmail.com>
  4783. *
  4784. * For the full copyright and license information, please view the LICENSE
  4785. * file that was distributed with this source code.
  4786. */
  4787. namespace Prophecy;
  4788. use Prophecy\Doubler\Doubler;
  4789. use Prophecy\Doubler\LazyDouble;
  4790. use Prophecy\Doubler\ClassPatch;
  4791. use Prophecy\Prophecy\ObjectProphecy;
  4792. use Prophecy\Prophecy\RevealerInterface;
  4793. use Prophecy\Prophecy\Revealer;
  4794. use Prophecy\Call\CallCenter;
  4795. use Prophecy\Util\StringUtil;
  4796. use Prophecy\Exception\Prediction\PredictionException;
  4797. use Prophecy\Exception\Prediction\AggregateException;
  4798. /**
  4799. * Prophet creates prophecies.
  4800. *
  4801. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4802. */
  4803. class Prophet
  4804. {
  4805. private $doubler;
  4806. private $revealer;
  4807. private $util;
  4808. /**
  4809. * @var ObjectProphecy[]
  4810. */
  4811. private $prophecies = array();
  4812. /**
  4813. * Initializes Prophet.
  4814. *
  4815. * @param null|Doubler $doubler
  4816. * @param null|RevealerInterface $revealer
  4817. * @param null|StringUtil $util
  4818. */
  4819. public function __construct(Doubler $doubler = null, RevealerInterface $revealer = null,
  4820. StringUtil $util = null)
  4821. {
  4822. if (null === $doubler) {
  4823. $doubler = new Doubler;
  4824. $doubler->registerClassPatch(new ClassPatch\SplFileInfoPatch);
  4825. $doubler->registerClassPatch(new ClassPatch\TraversablePatch);
  4826. $doubler->registerClassPatch(new ClassPatch\DisableConstructorPatch);
  4827. $doubler->registerClassPatch(new ClassPatch\ProphecySubjectPatch);
  4828. $doubler->registerClassPatch(new ClassPatch\ReflectionClassNewInstancePatch);
  4829. $doubler->registerClassPatch(new ClassPatch\HhvmExceptionPatch());
  4830. $doubler->registerClassPatch(new ClassPatch\MagicCallPatch);
  4831. $doubler->registerClassPatch(new ClassPatch\KeywordPatch);
  4832. }
  4833. $this->doubler = $doubler;
  4834. $this->revealer = $revealer ?: new Revealer;
  4835. $this->util = $util ?: new StringUtil;
  4836. }
  4837. /**
  4838. * Creates new object prophecy.
  4839. *
  4840. * @param null|string $classOrInterface Class or interface name
  4841. *
  4842. * @return ObjectProphecy
  4843. */
  4844. public function prophesize($classOrInterface = null)
  4845. {
  4846. $this->prophecies[] = $prophecy = new ObjectProphecy(
  4847. new LazyDouble($this->doubler),
  4848. new CallCenter($this->util),
  4849. $this->revealer
  4850. );
  4851. if ($classOrInterface && class_exists($classOrInterface)) {
  4852. return $prophecy->willExtend($classOrInterface);
  4853. }
  4854. if ($classOrInterface && interface_exists($classOrInterface)) {
  4855. return $prophecy->willImplement($classOrInterface);
  4856. }
  4857. return $prophecy;
  4858. }
  4859. /**
  4860. * Returns all created object prophecies.
  4861. *
  4862. * @return ObjectProphecy[]
  4863. */
  4864. public function getProphecies()
  4865. {
  4866. return $this->prophecies;
  4867. }
  4868. /**
  4869. * Returns Doubler instance assigned to this Prophet.
  4870. *
  4871. * @return Doubler
  4872. */
  4873. public function getDoubler()
  4874. {
  4875. return $this->doubler;
  4876. }
  4877. /**
  4878. * Checks all predictions defined by prophecies of this Prophet.
  4879. *
  4880. * @throws Exception\Prediction\AggregateException If any prediction fails
  4881. */
  4882. public function checkPredictions()
  4883. {
  4884. $exception = new AggregateException("Some predictions failed:\n");
  4885. foreach ($this->prophecies as $prophecy) {
  4886. try {
  4887. $prophecy->checkProphecyMethodsPredictions();
  4888. } catch (PredictionException $e) {
  4889. $exception->append($e);
  4890. }
  4891. }
  4892. if (count($exception->getExceptions())) {
  4893. throw $exception;
  4894. }
  4895. }
  4896. }
  4897. <?php
  4898. /*
  4899. * This file is part of the Prophecy.
  4900. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4901. * Marcello Duarte <marcello.duarte@gmail.com>
  4902. *
  4903. * For the full copyright and license information, please view the LICENSE
  4904. * file that was distributed with this source code.
  4905. */
  4906. namespace Prophecy\Exception;
  4907. /**
  4908. * Core Prophecy exception interface.
  4909. * All Prophecy exceptions implement it.
  4910. *
  4911. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4912. */
  4913. interface Exception
  4914. {
  4915. /**
  4916. * @return string
  4917. */
  4918. public function getMessage();
  4919. }
  4920. <?php
  4921. /*
  4922. * This file is part of the Prophecy.
  4923. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4924. * Marcello Duarte <marcello.duarte@gmail.com>
  4925. *
  4926. * For the full copyright and license information, please view the LICENSE
  4927. * file that was distributed with this source code.
  4928. */
  4929. namespace Prophecy\Exception\Prophecy;
  4930. use Prophecy\Prophecy\ObjectProphecy;
  4931. class ObjectProphecyException extends \RuntimeException implements ProphecyException
  4932. {
  4933. private $objectProphecy;
  4934. public function __construct($message, ObjectProphecy $objectProphecy)
  4935. {
  4936. parent::__construct($message);
  4937. $this->objectProphecy = $objectProphecy;
  4938. }
  4939. /**
  4940. * @return ObjectProphecy
  4941. */
  4942. public function getObjectProphecy()
  4943. {
  4944. return $this->objectProphecy;
  4945. }
  4946. }
  4947. <?php
  4948. /*
  4949. * This file is part of the Prophecy.
  4950. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4951. * Marcello Duarte <marcello.duarte@gmail.com>
  4952. *
  4953. * For the full copyright and license information, please view the LICENSE
  4954. * file that was distributed with this source code.
  4955. */
  4956. namespace Prophecy\Exception\Prophecy;
  4957. use Prophecy\Exception\Exception;
  4958. interface ProphecyException extends Exception
  4959. {
  4960. }
  4961. <?php
  4962. /*
  4963. * This file is part of the Prophecy.
  4964. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4965. * Marcello Duarte <marcello.duarte@gmail.com>
  4966. *
  4967. * For the full copyright and license information, please view the LICENSE
  4968. * file that was distributed with this source code.
  4969. */
  4970. namespace Prophecy\Exception\Prophecy;
  4971. use Prophecy\Prophecy\MethodProphecy;
  4972. class MethodProphecyException extends ObjectProphecyException
  4973. {
  4974. private $methodProphecy;
  4975. public function __construct($message, MethodProphecy $methodProphecy)
  4976. {
  4977. parent::__construct($message, $methodProphecy->getObjectProphecy());
  4978. $this->methodProphecy = $methodProphecy;
  4979. }
  4980. /**
  4981. * @return MethodProphecy
  4982. */
  4983. public function getMethodProphecy()
  4984. {
  4985. return $this->methodProphecy;
  4986. }
  4987. }
  4988. <?php
  4989. /*
  4990. * This file is part of the Prophecy.
  4991. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4992. * Marcello Duarte <marcello.duarte@gmail.com>
  4993. *
  4994. * For the full copyright and license information, please view the LICENSE
  4995. * file that was distributed with this source code.
  4996. */
  4997. namespace Prophecy\Exception\Doubler;
  4998. class InterfaceNotFoundException extends ClassNotFoundException
  4999. {
  5000. public function getInterfaceName()
  5001. {
  5002. return $this->getClassname();
  5003. }
  5004. }
  5005. <?php
  5006. /*
  5007. * This file is part of the Prophecy.
  5008. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5009. * Marcello Duarte <marcello.duarte@gmail.com>
  5010. *
  5011. * For the full copyright and license information, please view the LICENSE
  5012. * file that was distributed with this source code.
  5013. */
  5014. namespace Prophecy\Exception\Doubler;
  5015. use ReflectionClass;
  5016. class ClassMirrorException extends \RuntimeException implements DoublerException
  5017. {
  5018. private $class;
  5019. public function __construct($message, ReflectionClass $class)
  5020. {
  5021. parent::__construct($message);
  5022. $this->class = $class;
  5023. }
  5024. public function getReflectedClass()
  5025. {
  5026. return $this->class;
  5027. }
  5028. }
  5029. <?php
  5030. /*
  5031. * This file is part of the Prophecy.
  5032. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5033. * Marcello Duarte <marcello.duarte@gmail.com>
  5034. *
  5035. * For the full copyright and license information, please view the LICENSE
  5036. * file that was distributed with this source code.
  5037. */
  5038. namespace Prophecy\Exception\Doubler;
  5039. use RuntimeException;
  5040. class DoubleException extends RuntimeException implements DoublerException
  5041. {
  5042. }
  5043. <?php
  5044. /*
  5045. * This file is part of the Prophecy.
  5046. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5047. * Marcello Duarte <marcello.duarte@gmail.com>
  5048. *
  5049. * For the full copyright and license information, please view the LICENSE
  5050. * file that was distributed with this source code.
  5051. */
  5052. namespace Prophecy\Exception\Doubler;
  5053. use Prophecy\Exception\Exception;
  5054. interface DoublerException extends Exception
  5055. {
  5056. }
  5057. <?php
  5058. /*
  5059. * This file is part of the Prophecy.
  5060. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5061. * Marcello Duarte <marcello.duarte@gmail.com>
  5062. *
  5063. * For the full copyright and license information, please view the LICENSE
  5064. * file that was distributed with this source code.
  5065. */
  5066. namespace Prophecy\Exception\Doubler;
  5067. class MethodNotFoundException extends DoubleException
  5068. {
  5069. /**
  5070. * @var string
  5071. */
  5072. private $classname;
  5073. /**
  5074. * @var string
  5075. */
  5076. private $methodName;
  5077. /**
  5078. * @var array
  5079. */
  5080. private $arguments;
  5081. /**
  5082. * @param string $message
  5083. * @param string $classname
  5084. * @param string $methodName
  5085. * @param null|Argument\ArgumentsWildcard|array $arguments
  5086. */
  5087. public function __construct($message, $classname, $methodName, $arguments = null)
  5088. {
  5089. parent::__construct($message);
  5090. $this->classname = $classname;
  5091. $this->methodName = $methodName;
  5092. $this->arguments = $arguments;
  5093. }
  5094. public function getClassname()
  5095. {
  5096. return $this->classname;
  5097. }
  5098. public function getMethodName()
  5099. {
  5100. return $this->methodName;
  5101. }
  5102. public function getArguments()
  5103. {
  5104. return $this->arguments;
  5105. }
  5106. }
  5107. <?php
  5108. /*
  5109. * This file is part of the Prophecy.
  5110. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5111. * Marcello Duarte <marcello.duarte@gmail.com>
  5112. *
  5113. * For the full copyright and license information, please view the LICENSE
  5114. * file that was distributed with this source code.
  5115. */
  5116. namespace Prophecy\Exception\Doubler;
  5117. class ReturnByReferenceException extends DoubleException
  5118. {
  5119. private $classname;
  5120. private $methodName;
  5121. /**
  5122. * @param string $message
  5123. * @param string $classname
  5124. * @param string $methodName
  5125. */
  5126. public function __construct($message, $classname, $methodName)
  5127. {
  5128. parent::__construct($message);
  5129. $this->classname = $classname;
  5130. $this->methodName = $methodName;
  5131. }
  5132. public function getClassname()
  5133. {
  5134. return $this->classname;
  5135. }
  5136. public function getMethodName()
  5137. {
  5138. return $this->methodName;
  5139. }
  5140. }
  5141. <?php
  5142. /*
  5143. * This file is part of the Prophecy.
  5144. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5145. * Marcello Duarte <marcello.duarte@gmail.com>
  5146. *
  5147. * For the full copyright and license information, please view the LICENSE
  5148. * file that was distributed with this source code.
  5149. */
  5150. namespace Prophecy\Exception\Doubler;
  5151. use Prophecy\Doubler\Generator\Node\ClassNode;
  5152. class ClassCreatorException extends \RuntimeException implements DoublerException
  5153. {
  5154. private $node;
  5155. public function __construct($message, ClassNode $node)
  5156. {
  5157. parent::__construct($message);
  5158. $this->node = $node;
  5159. }
  5160. public function getClassNode()
  5161. {
  5162. return $this->node;
  5163. }
  5164. }
  5165. <?php
  5166. /*
  5167. * This file is part of the Prophecy.
  5168. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5169. * Marcello Duarte <marcello.duarte@gmail.com>
  5170. *
  5171. * For the full copyright and license information, please view the LICENSE
  5172. * file that was distributed with this source code.
  5173. */
  5174. namespace Prophecy\Exception\Doubler;
  5175. class ClassNotFoundException extends DoubleException
  5176. {
  5177. private $classname;
  5178. /**
  5179. * @param string $message
  5180. * @param string $classname
  5181. */
  5182. public function __construct($message, $classname)
  5183. {
  5184. parent::__construct($message);
  5185. $this->classname = $classname;
  5186. }
  5187. public function getClassname()
  5188. {
  5189. return $this->classname;
  5190. }
  5191. }
  5192. <?php
  5193. /*
  5194. * This file is part of the Prophecy.
  5195. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5196. * Marcello Duarte <marcello.duarte@gmail.com>
  5197. *
  5198. * For the full copyright and license information, please view the LICENSE
  5199. * file that was distributed with this source code.
  5200. */
  5201. namespace Prophecy\Exception\Prediction;
  5202. use Prophecy\Prophecy\MethodProphecy;
  5203. use Prophecy\Exception\Prophecy\MethodProphecyException;
  5204. class UnexpectedCallsException extends MethodProphecyException implements PredictionException
  5205. {
  5206. private $calls = array();
  5207. public function __construct($message, MethodProphecy $methodProphecy, array $calls)
  5208. {
  5209. parent::__construct($message, $methodProphecy);
  5210. $this->calls = $calls;
  5211. }
  5212. public function getCalls()
  5213. {
  5214. return $this->calls;
  5215. }
  5216. }
  5217. <?php
  5218. /*
  5219. * This file is part of the Prophecy.
  5220. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5221. * Marcello Duarte <marcello.duarte@gmail.com>
  5222. *
  5223. * For the full copyright and license information, please view the LICENSE
  5224. * file that was distributed with this source code.
  5225. */
  5226. namespace Prophecy\Exception\Prediction;
  5227. use Prophecy\Exception\Exception;
  5228. interface PredictionException extends Exception
  5229. {
  5230. }
  5231. <?php
  5232. /*
  5233. * This file is part of the Prophecy.
  5234. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5235. * Marcello Duarte <marcello.duarte@gmail.com>
  5236. *
  5237. * For the full copyright and license information, please view the LICENSE
  5238. * file that was distributed with this source code.
  5239. */
  5240. namespace Prophecy\Exception\Prediction;
  5241. use RuntimeException;
  5242. /**
  5243. * Basic failed prediction exception.
  5244. * Use it for custom prediction failures.
  5245. *
  5246. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5247. */
  5248. class FailedPredictionException extends RuntimeException implements PredictionException
  5249. {
  5250. }
  5251. <?php
  5252. /*
  5253. * This file is part of the Prophecy.
  5254. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5255. * Marcello Duarte <marcello.duarte@gmail.com>
  5256. *
  5257. * For the full copyright and license information, please view the LICENSE
  5258. * file that was distributed with this source code.
  5259. */
  5260. namespace Prophecy\Exception\Prediction;
  5261. use Prophecy\Exception\Prophecy\MethodProphecyException;
  5262. class NoCallsException extends MethodProphecyException implements PredictionException
  5263. {
  5264. }
  5265. <?php
  5266. /*
  5267. * This file is part of the Prophecy.
  5268. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5269. * Marcello Duarte <marcello.duarte@gmail.com>
  5270. *
  5271. * For the full copyright and license information, please view the LICENSE
  5272. * file that was distributed with this source code.
  5273. */
  5274. namespace Prophecy\Exception\Prediction;
  5275. use Prophecy\Prophecy\ObjectProphecy;
  5276. class AggregateException extends \RuntimeException implements PredictionException
  5277. {
  5278. private $exceptions = array();
  5279. private $objectProphecy;
  5280. public function append(PredictionException $exception)
  5281. {
  5282. $message = $exception->getMessage();
  5283. $message = ' '.strtr($message, array("\n" => "\n "))."\n";
  5284. $this->message = rtrim($this->message.$message);
  5285. $this->exceptions[] = $exception;
  5286. }
  5287. /**
  5288. * @return PredictionException[]
  5289. */
  5290. public function getExceptions()
  5291. {
  5292. return $this->exceptions;
  5293. }
  5294. public function setObjectProphecy(ObjectProphecy $objectProphecy)
  5295. {
  5296. $this->objectProphecy = $objectProphecy;
  5297. }
  5298. /**
  5299. * @return ObjectProphecy
  5300. */
  5301. public function getObjectProphecy()
  5302. {
  5303. return $this->objectProphecy;
  5304. }
  5305. }
  5306. <?php
  5307. /*
  5308. * This file is part of the Prophecy.
  5309. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5310. * Marcello Duarte <marcello.duarte@gmail.com>
  5311. *
  5312. * For the full copyright and license information, please view the LICENSE
  5313. * file that was distributed with this source code.
  5314. */
  5315. namespace Prophecy\Exception\Prediction;
  5316. use Prophecy\Prophecy\MethodProphecy;
  5317. class UnexpectedCallsCountException extends UnexpectedCallsException
  5318. {
  5319. private $expectedCount;
  5320. public function __construct($message, MethodProphecy $methodProphecy, $count, array $calls)
  5321. {
  5322. parent::__construct($message, $methodProphecy, $calls);
  5323. $this->expectedCount = intval($count);
  5324. }
  5325. public function getExpectedCount()
  5326. {
  5327. return $this->expectedCount;
  5328. }
  5329. }
  5330. <?php
  5331. /*
  5332. * This file is part of the Prophecy.
  5333. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5334. * Marcello Duarte <marcello.duarte@gmail.com>
  5335. *
  5336. * For the full copyright and license information, please view the LICENSE
  5337. * file that was distributed with this source code.
  5338. */
  5339. namespace Prophecy\Exception\Call;
  5340. use Prophecy\Exception\Prophecy\ObjectProphecyException;
  5341. use Prophecy\Prophecy\ObjectProphecy;
  5342. class UnexpectedCallException extends ObjectProphecyException
  5343. {
  5344. private $methodName;
  5345. private $arguments;
  5346. public function __construct($message, ObjectProphecy $objectProphecy,
  5347. $methodName, array $arguments)
  5348. {
  5349. parent::__construct($message, $objectProphecy);
  5350. $this->methodName = $methodName;
  5351. $this->arguments = $arguments;
  5352. }
  5353. public function getMethodName()
  5354. {
  5355. return $this->methodName;
  5356. }
  5357. public function getArguments()
  5358. {
  5359. return $this->arguments;
  5360. }
  5361. }
  5362. <?php
  5363. /*
  5364. * This file is part of the Prophecy.
  5365. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5366. * Marcello Duarte <marcello.duarte@gmail.com>
  5367. *
  5368. * For the full copyright and license information, please view the LICENSE
  5369. * file that was distributed with this source code.
  5370. */
  5371. namespace Prophecy\Exception;
  5372. class InvalidArgumentException extends \InvalidArgumentException implements Exception
  5373. {
  5374. }
  5375. <?php
  5376. /*
  5377. * This file is part of the Prophecy.
  5378. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5379. * Marcello Duarte <marcello.duarte@gmail.com>
  5380. *
  5381. * For the full copyright and license information, please view the LICENSE
  5382. * file that was distributed with this source code.
  5383. */
  5384. namespace Prophecy\Doubler;
  5385. use ReflectionClass;
  5386. /**
  5387. * Cached class doubler.
  5388. * Prevents mirroring/creation of the same structure twice.
  5389. *
  5390. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5391. */
  5392. class CachedDoubler extends Doubler
  5393. {
  5394. private $classes = array();
  5395. /**
  5396. * {@inheritdoc}
  5397. */
  5398. public function registerClassPatch(ClassPatch\ClassPatchInterface $patch)
  5399. {
  5400. $this->classes[] = array();
  5401. parent::registerClassPatch($patch);
  5402. }
  5403. /**
  5404. * {@inheritdoc}
  5405. */
  5406. protected function createDoubleClass(ReflectionClass $class = null, array $interfaces)
  5407. {
  5408. $classId = $this->generateClassId($class, $interfaces);
  5409. if (isset($this->classes[$classId])) {
  5410. return $this->classes[$classId];
  5411. }
  5412. return $this->classes[$classId] = parent::createDoubleClass($class, $interfaces);
  5413. }
  5414. /**
  5415. * @param ReflectionClass $class
  5416. * @param ReflectionClass[] $interfaces
  5417. *
  5418. * @return string
  5419. */
  5420. private function generateClassId(ReflectionClass $class = null, array $interfaces)
  5421. {
  5422. $parts = array();
  5423. if (null !== $class) {
  5424. $parts[] = $class->getName();
  5425. }
  5426. foreach ($interfaces as $interface) {
  5427. $parts[] = $interface->getName();
  5428. }
  5429. sort($parts);
  5430. return md5(implode('', $parts));
  5431. }
  5432. }
  5433. <?php
  5434. /*
  5435. * This file is part of the Prophecy.
  5436. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5437. * Marcello Duarte <marcello.duarte@gmail.com>
  5438. *
  5439. * For the full copyright and license information, please view the LICENSE
  5440. * file that was distributed with this source code.
  5441. */
  5442. namespace Prophecy\Doubler;
  5443. /**
  5444. * Core double interface.
  5445. * All doubled classes will implement this one.
  5446. *
  5447. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5448. */
  5449. interface DoubleInterface
  5450. {
  5451. }
  5452. <?php
  5453. /*
  5454. * This file is part of the Prophecy.
  5455. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5456. * Marcello Duarte <marcello.duarte@gmail.com>
  5457. *
  5458. * For the full copyright and license information, please view the LICENSE
  5459. * file that was distributed with this source code.
  5460. */
  5461. namespace Prophecy\Doubler;
  5462. use Doctrine\Instantiator\Instantiator;
  5463. use Prophecy\Doubler\ClassPatch\ClassPatchInterface;
  5464. use Prophecy\Doubler\Generator\ClassMirror;
  5465. use Prophecy\Doubler\Generator\ClassCreator;
  5466. use Prophecy\Exception\InvalidArgumentException;
  5467. use ReflectionClass;
  5468. /**
  5469. * Cached class doubler.
  5470. * Prevents mirroring/creation of the same structure twice.
  5471. *
  5472. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5473. */
  5474. class Doubler
  5475. {
  5476. private $mirror;
  5477. private $creator;
  5478. private $namer;
  5479. /**
  5480. * @var ClassPatchInterface[]
  5481. */
  5482. private $patches = array();
  5483. /**
  5484. * @var \Doctrine\Instantiator\Instantiator
  5485. */
  5486. private $instantiator;
  5487. /**
  5488. * Initializes doubler.
  5489. *
  5490. * @param ClassMirror $mirror
  5491. * @param ClassCreator $creator
  5492. * @param NameGenerator $namer
  5493. */
  5494. public function __construct(ClassMirror $mirror = null, ClassCreator $creator = null,
  5495. NameGenerator $namer = null)
  5496. {
  5497. $this->mirror = $mirror ?: new ClassMirror;
  5498. $this->creator = $creator ?: new ClassCreator;
  5499. $this->namer = $namer ?: new NameGenerator;
  5500. }
  5501. /**
  5502. * Returns list of registered class patches.
  5503. *
  5504. * @return ClassPatchInterface[]
  5505. */
  5506. public function getClassPatches()
  5507. {
  5508. return $this->patches;
  5509. }
  5510. /**
  5511. * Registers new class patch.
  5512. *
  5513. * @param ClassPatchInterface $patch
  5514. */
  5515. public function registerClassPatch(ClassPatchInterface $patch)
  5516. {
  5517. $this->patches[] = $patch;
  5518. @usort($this->patches, function (ClassPatchInterface $patch1, ClassPatchInterface $patch2) {
  5519. return $patch2->getPriority() - $patch1->getPriority();
  5520. });
  5521. }
  5522. /**
  5523. * Creates double from specific class or/and list of interfaces.
  5524. *
  5525. * @param ReflectionClass $class
  5526. * @param ReflectionClass[] $interfaces Array of ReflectionClass instances
  5527. * @param array $args Constructor arguments
  5528. *
  5529. * @return DoubleInterface
  5530. *
  5531. * @throws \Prophecy\Exception\InvalidArgumentException
  5532. */
  5533. public function double(ReflectionClass $class = null, array $interfaces, array $args = null)
  5534. {
  5535. foreach ($interfaces as $interface) {
  5536. if (!$interface instanceof ReflectionClass) {
  5537. throw new InvalidArgumentException(sprintf(
  5538. "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n".
  5539. "a second argument to `Doubler::double(...)`, but got %s.",
  5540. is_object($interface) ? get_class($interface).' class' : gettype($interface)
  5541. ));
  5542. }
  5543. }
  5544. $classname = $this->createDoubleClass($class, $interfaces);
  5545. $reflection = new ReflectionClass($classname);
  5546. if (null !== $args) {
  5547. return $reflection->newInstanceArgs($args);
  5548. }
  5549. if ((null === $constructor = $reflection->getConstructor())
  5550. || ($constructor->isPublic() && !$constructor->isFinal())) {
  5551. return $reflection->newInstance();
  5552. }
  5553. if (!$this->instantiator) {
  5554. $this->instantiator = new Instantiator();
  5555. }
  5556. return $this->instantiator->instantiate($classname);
  5557. }
  5558. /**
  5559. * Creates double class and returns its FQN.
  5560. *
  5561. * @param ReflectionClass $class
  5562. * @param ReflectionClass[] $interfaces
  5563. *
  5564. * @return string
  5565. */
  5566. protected function createDoubleClass(ReflectionClass $class = null, array $interfaces)
  5567. {
  5568. $name = $this->namer->name($class, $interfaces);
  5569. $node = $this->mirror->reflect($class, $interfaces);
  5570. foreach ($this->patches as $patch) {
  5571. if ($patch->supports($node)) {
  5572. $patch->apply($node);
  5573. }
  5574. }
  5575. $this->creator->create($name, $node);
  5576. return $name;
  5577. }
  5578. }
  5579. <?php
  5580. /*
  5581. * This file is part of the Prophecy.
  5582. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5583. * Marcello Duarte <marcello.duarte@gmail.com>
  5584. *
  5585. * For the full copyright and license information, please view the LICENSE
  5586. * file that was distributed with this source code.
  5587. */
  5588. namespace Prophecy\Doubler\Generator;
  5589. /**
  5590. * Class code creator.
  5591. * Generates PHP code for specific class node tree.
  5592. *
  5593. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5594. */
  5595. class ClassCodeGenerator
  5596. {
  5597. /**
  5598. * Generates PHP code for class node.
  5599. *
  5600. * @param string $classname
  5601. * @param Node\ClassNode $class
  5602. *
  5603. * @return string
  5604. */
  5605. public function generate($classname, Node\ClassNode $class)
  5606. {
  5607. $parts = explode('\\', $classname);
  5608. $classname = array_pop($parts);
  5609. $namespace = implode('\\', $parts);
  5610. $code = sprintf("class %s extends \%s implements %s {\n",
  5611. $classname, $class->getParentClass(), implode(', ',
  5612. array_map(function ($interface) {return '\\'.$interface;}, $class->getInterfaces())
  5613. )
  5614. );
  5615. foreach ($class->getProperties() as $name => $visibility) {
  5616. $code .= sprintf("%s \$%s;\n", $visibility, $name);
  5617. }
  5618. $code .= "\n";
  5619. foreach ($class->getMethods() as $method) {
  5620. $code .= $this->generateMethod($method)."\n";
  5621. }
  5622. $code .= "\n}";
  5623. return sprintf("namespace %s {\n%s\n}", $namespace, $code);
  5624. }
  5625. private function generateMethod(Node\MethodNode $method)
  5626. {
  5627. $php = sprintf("%s %s function %s%s(%s) {\n",
  5628. $method->getVisibility(),
  5629. $method->isStatic() ? 'static' : '',
  5630. $method->returnsReference() ? '&':'',
  5631. $method->getName(),
  5632. implode(', ', $this->generateArguments($method->getArguments()))
  5633. );
  5634. $php .= $method->getCode()."\n";
  5635. return $php.'}';
  5636. }
  5637. private function generateArguments(array $arguments)
  5638. {
  5639. return array_map(function (Node\ArgumentNode $argument) {
  5640. $php = '';
  5641. if ($hint = $argument->getTypeHint()) {
  5642. if ('array' === $hint || 'callable' === $hint) {
  5643. $php .= $hint;
  5644. } else {
  5645. $php .= '\\'.$hint;
  5646. }
  5647. }
  5648. $php .= ' '.($argument->isPassedByReference() ? '&' : '').'$'.$argument->getName();
  5649. if ($argument->isOptional()) {
  5650. $php .= ' = '.var_export($argument->getDefault(), true);
  5651. }
  5652. return $php;
  5653. }, $arguments);
  5654. }
  5655. }
  5656. <?php
  5657. /*
  5658. * This file is part of the Prophecy.
  5659. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5660. * Marcello Duarte <marcello.duarte@gmail.com>
  5661. *
  5662. * For the full copyright and license information, please view the LICENSE
  5663. * file that was distributed with this source code.
  5664. */
  5665. namespace Prophecy\Doubler\Generator;
  5666. use Prophecy\Exception\Doubler\ClassCreatorException;
  5667. /**
  5668. * Class creator.
  5669. * Creates specific class in current environment.
  5670. *
  5671. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5672. */
  5673. class ClassCreator
  5674. {
  5675. private $generator;
  5676. /**
  5677. * Initializes creator.
  5678. *
  5679. * @param ClassCodeGenerator $generator
  5680. */
  5681. public function __construct(ClassCodeGenerator $generator = null)
  5682. {
  5683. $this->generator = $generator ?: new ClassCodeGenerator;
  5684. }
  5685. /**
  5686. * Creates class.
  5687. *
  5688. * @param string $classname
  5689. * @param Node\ClassNode $class
  5690. *
  5691. * @return mixed
  5692. *
  5693. * @throws \Prophecy\Exception\Doubler\ClassCreatorException
  5694. */
  5695. public function create($classname, Node\ClassNode $class)
  5696. {
  5697. $code = $this->generator->generate($classname, $class);
  5698. $return = eval($code);
  5699. if (!class_exists($classname, false)) {
  5700. if (count($class->getInterfaces())) {
  5701. throw new ClassCreatorException(sprintf(
  5702. 'Could not double `%s` and implement interfaces: [%s].',
  5703. $class->getParentClass(), implode(', ', $class->getInterfaces())
  5704. ), $class);
  5705. }
  5706. throw new ClassCreatorException(
  5707. sprintf('Could not double `%s`.', $class->getParentClass()),
  5708. $class
  5709. );
  5710. }
  5711. return $return;
  5712. }
  5713. }
  5714. <?php
  5715. /*
  5716. * This file is part of the Prophecy.
  5717. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5718. * Marcello Duarte <marcello.duarte@gmail.com>
  5719. *
  5720. * For the full copyright and license information, please view the LICENSE
  5721. * file that was distributed with this source code.
  5722. */
  5723. namespace Prophecy\Doubler\Generator;
  5724. /**
  5725. * Reflection interface.
  5726. * All reflected classes implement this interface.
  5727. *
  5728. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5729. */
  5730. interface ReflectionInterface
  5731. {
  5732. }
  5733. <?php
  5734. /*
  5735. * This file is part of the Prophecy.
  5736. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5737. * Marcello Duarte <marcello.duarte@gmail.com>
  5738. *
  5739. * For the full copyright and license information, please view the LICENSE
  5740. * file that was distributed with this source code.
  5741. */
  5742. namespace Prophecy\Doubler\Generator;
  5743. use Prophecy\Exception\InvalidArgumentException;
  5744. use Prophecy\Exception\Doubler\ClassMirrorException;
  5745. use ReflectionClass;
  5746. use ReflectionMethod;
  5747. use ReflectionParameter;
  5748. /**
  5749. * Class mirror.
  5750. * Core doubler class. Mirrors specific class and/or interfaces into class node tree.
  5751. *
  5752. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5753. */
  5754. class ClassMirror
  5755. {
  5756. private static $reflectableMethods = array(
  5757. '__construct',
  5758. '__destruct',
  5759. '__sleep',
  5760. '__wakeup',
  5761. '__toString',
  5762. '__call',
  5763. );
  5764. /**
  5765. * Reflects provided arguments into class node.
  5766. *
  5767. * @param ReflectionClass $class
  5768. * @param ReflectionClass[] $interfaces
  5769. *
  5770. * @return Node\ClassNode
  5771. *
  5772. * @throws \Prophecy\Exception\InvalidArgumentException
  5773. */
  5774. public function reflect(ReflectionClass $class = null, array $interfaces)
  5775. {
  5776. $node = new Node\ClassNode;
  5777. if (null !== $class) {
  5778. if (true === $class->isInterface()) {
  5779. throw new InvalidArgumentException(sprintf(
  5780. "Could not reflect %s as a class, because it\n".
  5781. "is interface - use the second argument instead.",
  5782. $class->getName()
  5783. ));
  5784. }
  5785. $this->reflectClassToNode($class, $node);
  5786. }
  5787. foreach ($interfaces as $interface) {
  5788. if (!$interface instanceof ReflectionClass) {
  5789. throw new InvalidArgumentException(sprintf(
  5790. "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n".
  5791. "a second argument to `ClassMirror::reflect(...)`, but got %s.",
  5792. is_object($interface) ? get_class($interface).' class' : gettype($interface)
  5793. ));
  5794. }
  5795. if (false === $interface->isInterface()) {
  5796. throw new InvalidArgumentException(sprintf(
  5797. "Could not reflect %s as an interface, because it\n".
  5798. "is class - use the first argument instead.",
  5799. $interface->getName()
  5800. ));
  5801. }
  5802. $this->reflectInterfaceToNode($interface, $node);
  5803. }
  5804. $node->addInterface('Prophecy\Doubler\Generator\ReflectionInterface');
  5805. return $node;
  5806. }
  5807. private function reflectClassToNode(ReflectionClass $class, Node\ClassNode $node)
  5808. {
  5809. if (true === $class->isFinal()) {
  5810. throw new ClassMirrorException(sprintf(
  5811. 'Could not reflect class %s as it is marked final.', $class->getName()
  5812. ), $class);
  5813. }
  5814. $node->setParentClass($class->getName());
  5815. foreach ($class->getMethods(ReflectionMethod::IS_ABSTRACT) as $method) {
  5816. if (false === $method->isProtected()) {
  5817. continue;
  5818. }
  5819. $this->reflectMethodToNode($method, $node);
  5820. }
  5821. foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
  5822. if (0 === strpos($method->getName(), '_')
  5823. && !in_array($method->getName(), self::$reflectableMethods)) {
  5824. continue;
  5825. }
  5826. if (true === $method->isFinal()) {
  5827. continue;
  5828. }
  5829. $this->reflectMethodToNode($method, $node);
  5830. }
  5831. }
  5832. private function reflectInterfaceToNode(ReflectionClass $interface, Node\ClassNode $node)
  5833. {
  5834. $node->addInterface($interface->getName());
  5835. foreach ($interface->getMethods() as $method) {
  5836. $this->reflectMethodToNode($method, $node);
  5837. }
  5838. }
  5839. private function reflectMethodToNode(ReflectionMethod $method, Node\ClassNode $classNode)
  5840. {
  5841. $node = new Node\MethodNode($method->getName());
  5842. if (true === $method->isProtected()) {
  5843. $node->setVisibility('protected');
  5844. }
  5845. if (true === $method->isStatic()) {
  5846. $node->setStatic();
  5847. }
  5848. if (true === $method->returnsReference()) {
  5849. $node->setReturnsReference();
  5850. }
  5851. if (is_array($params = $method->getParameters()) && count($params)) {
  5852. foreach ($params as $param) {
  5853. $this->reflectArgumentToNode($param, $node);
  5854. }
  5855. }
  5856. $classNode->addMethod($node);
  5857. }
  5858. private function reflectArgumentToNode(ReflectionParameter $parameter, Node\MethodNode $methodNode)
  5859. {
  5860. $name = $parameter->getName() == '...' ? '__dot_dot_dot__' : $parameter->getName();
  5861. $node = new Node\ArgumentNode($name);
  5862. $typeHint = $this->getTypeHint($parameter);
  5863. $node->setTypeHint($typeHint);
  5864. if (true === $parameter->isDefaultValueAvailable()) {
  5865. $node->setDefault($parameter->getDefaultValue());
  5866. } elseif (true === $parameter->isOptional()
  5867. || (true === $parameter->allowsNull() && $typeHint)) {
  5868. $node->setDefault(null);
  5869. }
  5870. if (true === $parameter->isPassedByReference()) {
  5871. $node->setAsPassedByReference();
  5872. }
  5873. $methodNode->addArgument($node);
  5874. }
  5875. private function getTypeHint(ReflectionParameter $parameter)
  5876. {
  5877. if (null !== $className = $this->getParameterClassName($parameter)) {
  5878. return $className;
  5879. }
  5880. if (true === $parameter->isArray()) {
  5881. return 'array';
  5882. }
  5883. if (version_compare(PHP_VERSION, '5.4', '>=') && true === $parameter->isCallable()) {
  5884. return 'callable';
  5885. }
  5886. return null;
  5887. }
  5888. private function getParameterClassName(ReflectionParameter $parameter)
  5889. {
  5890. try {
  5891. return $parameter->getClass() ? $parameter->getClass()->getName() : null;
  5892. } catch (\ReflectionException $e) {
  5893. preg_match('/\[\s\<\w+?>\s([\w,\\\]+)/s', $parameter, $matches);
  5894. return isset($matches[1]) ? $matches[1] : null;
  5895. }
  5896. }
  5897. }
  5898. <?php
  5899. /*
  5900. * This file is part of the Prophecy.
  5901. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5902. * Marcello Duarte <marcello.duarte@gmail.com>
  5903. *
  5904. * For the full copyright and license information, please view the LICENSE
  5905. * file that was distributed with this source code.
  5906. */
  5907. namespace Prophecy\Doubler\Generator\Node;
  5908. /**
  5909. * Argument node.
  5910. *
  5911. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5912. */
  5913. class ArgumentNode
  5914. {
  5915. private $name;
  5916. private $typeHint;
  5917. private $default;
  5918. private $optional = false;
  5919. private $byReference = false;
  5920. /**
  5921. * @param string $name
  5922. */
  5923. public function __construct($name)
  5924. {
  5925. $this->name = $name;
  5926. }
  5927. public function getName()
  5928. {
  5929. return $this->name;
  5930. }
  5931. public function getTypeHint()
  5932. {
  5933. return $this->typeHint;
  5934. }
  5935. public function setTypeHint($typeHint = null)
  5936. {
  5937. $this->typeHint = $typeHint;
  5938. }
  5939. public function getDefault()
  5940. {
  5941. return $this->default;
  5942. }
  5943. public function setDefault($default = null)
  5944. {
  5945. $this->optional = true;
  5946. $this->default = $default;
  5947. }
  5948. public function isOptional()
  5949. {
  5950. return $this->optional;
  5951. }
  5952. public function setAsPassedByReference($byReference = true)
  5953. {
  5954. $this->byReference = $byReference;
  5955. }
  5956. public function isPassedByReference()
  5957. {
  5958. return $this->byReference;
  5959. }
  5960. }
  5961. <?php
  5962. /*
  5963. * This file is part of the Prophecy.
  5964. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5965. * Marcello Duarte <marcello.duarte@gmail.com>
  5966. *
  5967. * For the full copyright and license information, please view the LICENSE
  5968. * file that was distributed with this source code.
  5969. */
  5970. namespace Prophecy\Doubler\Generator\Node;
  5971. use Prophecy\Exception\InvalidArgumentException;
  5972. /**
  5973. * Method node.
  5974. *
  5975. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5976. */
  5977. class MethodNode
  5978. {
  5979. private $name;
  5980. private $code;
  5981. private $visibility = 'public';
  5982. private $static = false;
  5983. private $returnsReference = false;
  5984. /**
  5985. * @var ArgumentNode[]
  5986. */
  5987. private $arguments = array();
  5988. /**
  5989. * @param string $name
  5990. * @param string $code
  5991. */
  5992. public function __construct($name, $code = null)
  5993. {
  5994. $this->name = $name;
  5995. $this->code = $code;
  5996. }
  5997. public function getVisibility()
  5998. {
  5999. return $this->visibility;
  6000. }
  6001. /**
  6002. * @param string $visibility
  6003. */
  6004. public function setVisibility($visibility)
  6005. {
  6006. $visibility = strtolower($visibility);
  6007. if (!in_array($visibility, array('public', 'private', 'protected'))) {
  6008. throw new InvalidArgumentException(sprintf(
  6009. '`%s` method visibility is not supported.', $visibility
  6010. ));
  6011. }
  6012. $this->visibility = $visibility;
  6013. }
  6014. public function isStatic()
  6015. {
  6016. return $this->static;
  6017. }
  6018. public function setStatic($static = true)
  6019. {
  6020. $this->static = (bool) $static;
  6021. }
  6022. public function returnsReference()
  6023. {
  6024. return $this->returnsReference;
  6025. }
  6026. public function setReturnsReference()
  6027. {
  6028. $this->returnsReference = true;
  6029. }
  6030. public function getName()
  6031. {
  6032. return $this->name;
  6033. }
  6034. public function addArgument(ArgumentNode $argument)
  6035. {
  6036. $this->arguments[] = $argument;
  6037. }
  6038. /**
  6039. * @return ArgumentNode[]
  6040. */
  6041. public function getArguments()
  6042. {
  6043. return $this->arguments;
  6044. }
  6045. /**
  6046. * @param string $code
  6047. */
  6048. public function setCode($code)
  6049. {
  6050. $this->code = $code;
  6051. }
  6052. public function getCode()
  6053. {
  6054. if ($this->returnsReference)
  6055. {
  6056. return "throw new \Prophecy\Exception\Doubler\ReturnByReferenceException('Returning by reference not supported', get_class(\$this), '{$this->name}');";
  6057. }
  6058. return (string) $this->code;
  6059. }
  6060. public function useParentCode()
  6061. {
  6062. $this->code = sprintf(
  6063. 'return parent::%s(%s);', $this->getName(), implode(', ',
  6064. array_map(function (ArgumentNode $arg) { return '$'.$arg->getName(); }, $this->arguments)
  6065. )
  6066. );
  6067. }
  6068. }
  6069. <?php
  6070. /*
  6071. * This file is part of the Prophecy.
  6072. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6073. * Marcello Duarte <marcello.duarte@gmail.com>
  6074. *
  6075. * For the full copyright and license information, please view the LICENSE
  6076. * file that was distributed with this source code.
  6077. */
  6078. namespace Prophecy\Doubler\Generator\Node;
  6079. use Prophecy\Exception\InvalidArgumentException;
  6080. /**
  6081. * Class node.
  6082. *
  6083. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6084. */
  6085. class ClassNode
  6086. {
  6087. private $parentClass = 'stdClass';
  6088. private $interfaces = array();
  6089. private $properties = array();
  6090. /**
  6091. * @var MethodNode[]
  6092. */
  6093. private $methods = array();
  6094. public function getParentClass()
  6095. {
  6096. return $this->parentClass;
  6097. }
  6098. /**
  6099. * @param string $class
  6100. */
  6101. public function setParentClass($class)
  6102. {
  6103. $this->parentClass = $class ?: 'stdClass';
  6104. }
  6105. /**
  6106. * @return string[]
  6107. */
  6108. public function getInterfaces()
  6109. {
  6110. return $this->interfaces;
  6111. }
  6112. /**
  6113. * @param string $interface
  6114. */
  6115. public function addInterface($interface)
  6116. {
  6117. if ($this->hasInterface($interface)) {
  6118. return;
  6119. }
  6120. array_unshift($this->interfaces, $interface);
  6121. }
  6122. /**
  6123. * @param string $interface
  6124. *
  6125. * @return bool
  6126. */
  6127. public function hasInterface($interface)
  6128. {
  6129. return in_array($interface, $this->interfaces);
  6130. }
  6131. public function getProperties()
  6132. {
  6133. return $this->properties;
  6134. }
  6135. public function addProperty($name, $visibility = 'public')
  6136. {
  6137. $visibility = strtolower($visibility);
  6138. if (!in_array($visibility, array('public', 'private', 'protected'))) {
  6139. throw new InvalidArgumentException(sprintf(
  6140. '`%s` property visibility is not supported.', $visibility
  6141. ));
  6142. }
  6143. $this->properties[$name] = $visibility;
  6144. }
  6145. /**
  6146. * @return MethodNode[]
  6147. */
  6148. public function getMethods()
  6149. {
  6150. return $this->methods;
  6151. }
  6152. public function addMethod(MethodNode $method)
  6153. {
  6154. $this->methods[$method->getName()] = $method;
  6155. }
  6156. public function removeMethod($name)
  6157. {
  6158. unset($this->methods[$name]);
  6159. }
  6160. /**
  6161. * @param string $name
  6162. *
  6163. * @return MethodNode|null
  6164. */
  6165. public function getMethod($name)
  6166. {
  6167. return $this->hasMethod($name) ? $this->methods[$name] : null;
  6168. }
  6169. /**
  6170. * @param string $name
  6171. *
  6172. * @return bool
  6173. */
  6174. public function hasMethod($name)
  6175. {
  6176. return isset($this->methods[$name]);
  6177. }
  6178. }
  6179. <?php
  6180. /*
  6181. * This file is part of the Prophecy.
  6182. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6183. * Marcello Duarte <marcello.duarte@gmail.com>
  6184. *
  6185. * For the full copyright and license information, please view the LICENSE
  6186. * file that was distributed with this source code.
  6187. */
  6188. namespace Prophecy\Doubler;
  6189. use Prophecy\Exception\Doubler\DoubleException;
  6190. use Prophecy\Exception\Doubler\ClassNotFoundException;
  6191. use Prophecy\Exception\Doubler\InterfaceNotFoundException;
  6192. use ReflectionClass;
  6193. /**
  6194. * Lazy double.
  6195. * Gives simple interface to describe double before creating it.
  6196. *
  6197. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6198. */
  6199. class LazyDouble
  6200. {
  6201. private $doubler;
  6202. private $class;
  6203. private $interfaces = array();
  6204. private $arguments = null;
  6205. private $double;
  6206. /**
  6207. * Initializes lazy double.
  6208. *
  6209. * @param Doubler $doubler
  6210. */
  6211. public function __construct(Doubler $doubler)
  6212. {
  6213. $this->doubler = $doubler;
  6214. }
  6215. /**
  6216. * Tells doubler to use specific class as parent one for double.
  6217. *
  6218. * @param string|ReflectionClass $class
  6219. *
  6220. * @throws \Prophecy\Exception\Doubler\ClassNotFoundException
  6221. * @throws \Prophecy\Exception\Doubler\DoubleException
  6222. */
  6223. public function setParentClass($class)
  6224. {
  6225. if (null !== $this->double) {
  6226. throw new DoubleException('Can not extend class with already instantiated double.');
  6227. }
  6228. if (!$class instanceof ReflectionClass) {
  6229. if (!class_exists($class)) {
  6230. throw new ClassNotFoundException(sprintf('Class %s not found.', $class), $class);
  6231. }
  6232. $class = new ReflectionClass($class);
  6233. }
  6234. $this->class = $class;
  6235. }
  6236. /**
  6237. * Tells doubler to implement specific interface with double.
  6238. *
  6239. * @param string|ReflectionClass $interface
  6240. *
  6241. * @throws \Prophecy\Exception\Doubler\InterfaceNotFoundException
  6242. * @throws \Prophecy\Exception\Doubler\DoubleException
  6243. */
  6244. public function addInterface($interface)
  6245. {
  6246. if (null !== $this->double) {
  6247. throw new DoubleException(
  6248. 'Can not implement interface with already instantiated double.'
  6249. );
  6250. }
  6251. if (!$interface instanceof ReflectionClass) {
  6252. if (!interface_exists($interface)) {
  6253. throw new InterfaceNotFoundException(
  6254. sprintf('Interface %s not found.', $interface),
  6255. $interface
  6256. );
  6257. }
  6258. $interface = new ReflectionClass($interface);
  6259. }
  6260. $this->interfaces[] = $interface;
  6261. }
  6262. /**
  6263. * Sets constructor arguments.
  6264. *
  6265. * @param array $arguments
  6266. */
  6267. public function setArguments(array $arguments = null)
  6268. {
  6269. $this->arguments = $arguments;
  6270. }
  6271. /**
  6272. * Creates double instance or returns already created one.
  6273. *
  6274. * @return DoubleInterface
  6275. */
  6276. public function getInstance()
  6277. {
  6278. if (null === $this->double) {
  6279. if (null !== $this->arguments) {
  6280. return $this->double = $this->doubler->double(
  6281. $this->class, $this->interfaces, $this->arguments
  6282. );
  6283. }
  6284. $this->double = $this->doubler->double($this->class, $this->interfaces);
  6285. }
  6286. return $this->double;
  6287. }
  6288. }
  6289. <?php
  6290. /*
  6291. * This file is part of the Prophecy.
  6292. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6293. * Marcello Duarte <marcello.duarte@gmail.com>
  6294. *
  6295. * For the full copyright and license information, please view the LICENSE
  6296. * file that was distributed with this source code.
  6297. */
  6298. namespace Prophecy\Doubler\ClassPatch;
  6299. use Prophecy\Doubler\Generator\Node\ClassNode;
  6300. /**
  6301. * Remove method functionality from the double which will clash with php keywords.
  6302. *
  6303. * @author Milan Magudia <milan@magudia.com>
  6304. */
  6305. class KeywordPatch implements ClassPatchInterface
  6306. {
  6307. /**
  6308. * Support any class
  6309. *
  6310. * @param ClassNode $node
  6311. *
  6312. * @return boolean
  6313. */
  6314. public function supports(ClassNode $node)
  6315. {
  6316. return true;
  6317. }
  6318. /**
  6319. * Remove methods that clash with php keywords
  6320. *
  6321. * @param ClassNode $node
  6322. */
  6323. public function apply(ClassNode $node)
  6324. {
  6325. $methodNames = array_keys($node->getMethods());
  6326. $methodsToRemove = array_intersect($methodNames, $this->getKeywords());
  6327. foreach ($methodsToRemove as $methodName) {
  6328. $node->removeMethod($methodName);
  6329. }
  6330. }
  6331. /**
  6332. * Returns patch priority, which determines when patch will be applied.
  6333. *
  6334. * @return int Priority number (higher - earlier)
  6335. */
  6336. public function getPriority() {
  6337. return 49;
  6338. }
  6339. /**
  6340. * Returns array of php keywords.
  6341. *
  6342. * @return array
  6343. */
  6344. private function getKeywords() {
  6345. return array(
  6346. '__halt_compiler',
  6347. 'abstract',
  6348. 'and',
  6349. 'array',
  6350. 'as',
  6351. 'break',
  6352. 'callable',
  6353. 'case',
  6354. 'catch',
  6355. 'class',
  6356. 'clone',
  6357. 'const',
  6358. 'continue',
  6359. 'declare',
  6360. 'default',
  6361. 'die',
  6362. 'do',
  6363. 'echo',
  6364. 'else',
  6365. 'elseif',
  6366. 'empty',
  6367. 'enddeclare',
  6368. 'endfor',
  6369. 'endforeach',
  6370. 'endif',
  6371. 'endswitch',
  6372. 'endwhile',
  6373. 'eval',
  6374. 'exit',
  6375. 'extends',
  6376. 'final',
  6377. 'finally',
  6378. 'for',
  6379. 'foreach',
  6380. 'function',
  6381. 'global',
  6382. 'goto',
  6383. 'if',
  6384. 'implements',
  6385. 'include',
  6386. 'include_once',
  6387. 'instanceof',
  6388. 'insteadof',
  6389. 'interface',
  6390. 'isset',
  6391. 'list',
  6392. 'namespace',
  6393. 'new',
  6394. 'or',
  6395. 'print',
  6396. 'private',
  6397. 'protected',
  6398. 'public',
  6399. 'require',
  6400. 'require_once',
  6401. 'return',
  6402. 'static',
  6403. 'switch',
  6404. 'throw',
  6405. 'trait',
  6406. 'try',
  6407. 'unset',
  6408. 'use',
  6409. 'var',
  6410. 'while',
  6411. 'xor',
  6412. 'yield',
  6413. );
  6414. }
  6415. }
  6416. <?php
  6417. /*
  6418. * This file is part of the Prophecy.
  6419. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6420. * Marcello Duarte <marcello.duarte@gmail.com>
  6421. *
  6422. * For the full copyright and license information, please view the LICENSE
  6423. * file that was distributed with this source code.
  6424. */
  6425. namespace Prophecy\Doubler\ClassPatch;
  6426. use Prophecy\Doubler\Generator\Node\ClassNode;
  6427. use Prophecy\Doubler\Generator\Node\MethodNode;
  6428. use Prophecy\Doubler\Generator\Node\ArgumentNode;
  6429. /**
  6430. * Add Prophecy functionality to the double.
  6431. * This is a core class patch for Prophecy.
  6432. *
  6433. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6434. */
  6435. class ProphecySubjectPatch implements ClassPatchInterface
  6436. {
  6437. /**
  6438. * Always returns true.
  6439. *
  6440. * @param ClassNode $node
  6441. *
  6442. * @return bool
  6443. */
  6444. public function supports(ClassNode $node)
  6445. {
  6446. return true;
  6447. }
  6448. /**
  6449. * Apply Prophecy functionality to class node.
  6450. *
  6451. * @param ClassNode $node
  6452. */
  6453. public function apply(ClassNode $node)
  6454. {
  6455. $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface');
  6456. $node->addProperty('objectProphecy', 'private');
  6457. foreach ($node->getMethods() as $name => $method) {
  6458. if ('__construct' === strtolower($name)) {
  6459. continue;
  6460. }
  6461. $method->setCode(
  6462. 'return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());'
  6463. );
  6464. }
  6465. $prophecySetter = new MethodNode('setProphecy');
  6466. $prophecyArgument = new ArgumentNode('prophecy');
  6467. $prophecyArgument->setTypeHint('Prophecy\Prophecy\ProphecyInterface');
  6468. $prophecySetter->addArgument($prophecyArgument);
  6469. $prophecySetter->setCode('$this->objectProphecy = $prophecy;');
  6470. $prophecyGetter = new MethodNode('getProphecy');
  6471. $prophecyGetter->setCode('return $this->objectProphecy;');
  6472. if ($node->hasMethod('__call')) {
  6473. $__call = $node->getMethod('__call');
  6474. } else {
  6475. $__call = new MethodNode('__call');
  6476. $__call->addArgument(new ArgumentNode('name'));
  6477. $__call->addArgument(new ArgumentNode('arguments'));
  6478. $node->addMethod($__call);
  6479. }
  6480. $__call->setCode(<<<PHP
  6481. throw new \Prophecy\Exception\Doubler\MethodNotFoundException(
  6482. sprintf('Method `%s::%s()` not found.', get_class(\$this), func_get_arg(0)),
  6483. \$this->getProphecy(), func_get_arg(0)
  6484. );
  6485. PHP
  6486. );
  6487. $node->addMethod($prophecySetter);
  6488. $node->addMethod($prophecyGetter);
  6489. }
  6490. /**
  6491. * Returns patch priority, which determines when patch will be applied.
  6492. *
  6493. * @return int Priority number (higher - earlier)
  6494. */
  6495. public function getPriority()
  6496. {
  6497. return 0;
  6498. }
  6499. }
  6500. <?php
  6501. /*
  6502. * This file is part of the Prophecy.
  6503. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6504. * Marcello Duarte <marcello.duarte@gmail.com>
  6505. *
  6506. * For the full copyright and license information, please view the LICENSE
  6507. * file that was distributed with this source code.
  6508. */
  6509. namespace Prophecy\Doubler\ClassPatch;
  6510. use phpDocumentor\Reflection\DocBlock;
  6511. use Prophecy\Doubler\Generator\Node\ClassNode;
  6512. use Prophecy\Doubler\Generator\Node\MethodNode;
  6513. /**
  6514. * Discover Magical API using "@method" PHPDoc format.
  6515. *
  6516. * @author Thomas Tourlourat <thomas@tourlourat.com>
  6517. */
  6518. class MagicCallPatch implements ClassPatchInterface
  6519. {
  6520. /**
  6521. * Support any class
  6522. *
  6523. * @param ClassNode $node
  6524. *
  6525. * @return boolean
  6526. */
  6527. public function supports(ClassNode $node)
  6528. {
  6529. return true;
  6530. }
  6531. /**
  6532. * Discover Magical API
  6533. *
  6534. * @param ClassNode $node
  6535. */
  6536. public function apply(ClassNode $node)
  6537. {
  6538. $parentClass = $node->getParentClass();
  6539. $reflectionClass = new \ReflectionClass($parentClass);
  6540. $phpdoc = new DocBlock($reflectionClass->getDocComment());
  6541. $tagList = $phpdoc->getTagsByName('method');
  6542. foreach($tagList as $tag) {
  6543. $methodName = $tag->getMethodName();
  6544. if (!$reflectionClass->hasMethod($methodName)) {
  6545. $methodNode = new MethodNode($tag->getMethodName());
  6546. $methodNode->setStatic($tag->isStatic());
  6547. $node->addMethod($methodNode);
  6548. }
  6549. }
  6550. }
  6551. /**
  6552. * Returns patch priority, which determines when patch will be applied.
  6553. *
  6554. * @return integer Priority number (higher - earlier)
  6555. */
  6556. public function getPriority()
  6557. {
  6558. return 50;
  6559. }
  6560. }
  6561. <?php
  6562. /*
  6563. * This file is part of the Prophecy.
  6564. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6565. * Marcello Duarte <marcello.duarte@gmail.com>
  6566. *
  6567. * For the full copyright and license information, please view the LICENSE
  6568. * file that was distributed with this source code.
  6569. */
  6570. namespace Prophecy\Doubler\ClassPatch;
  6571. use Prophecy\Doubler\Generator\Node\ClassNode;
  6572. use Prophecy\Doubler\Generator\Node\MethodNode;
  6573. /**
  6574. * Traversable interface patch.
  6575. * Forces classes that implement interfaces, that extend Traversable to also implement Iterator.
  6576. *
  6577. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6578. */
  6579. class TraversablePatch implements ClassPatchInterface
  6580. {
  6581. /**
  6582. * Supports nodetree, that implement Traversable, but not Iterator or IteratorAggregate.
  6583. *
  6584. * @param ClassNode $node
  6585. *
  6586. * @return bool
  6587. */
  6588. public function supports(ClassNode $node)
  6589. {
  6590. if (in_array('Iterator', $node->getInterfaces())) {
  6591. return false;
  6592. }
  6593. if (in_array('IteratorAggregate', $node->getInterfaces())) {
  6594. return false;
  6595. }
  6596. foreach ($node->getInterfaces() as $interface) {
  6597. if ('Traversable' !== $interface && !is_subclass_of($interface, 'Traversable')) {
  6598. continue;
  6599. }
  6600. if ('Iterator' === $interface || is_subclass_of($interface, 'Iterator')) {
  6601. continue;
  6602. }
  6603. if ('IteratorAggregate' === $interface || is_subclass_of($interface, 'IteratorAggregate')) {
  6604. continue;
  6605. }
  6606. return true;
  6607. }
  6608. return false;
  6609. }
  6610. /**
  6611. * Forces class to implement Iterator interface.
  6612. *
  6613. * @param ClassNode $node
  6614. */
  6615. public function apply(ClassNode $node)
  6616. {
  6617. $node->addInterface('Iterator');
  6618. $node->addMethod(new MethodNode('current'));
  6619. $node->addMethod(new MethodNode('key'));
  6620. $node->addMethod(new MethodNode('next'));
  6621. $node->addMethod(new MethodNode('rewind'));
  6622. $node->addMethod(new MethodNode('valid'));
  6623. }
  6624. /**
  6625. * Returns patch priority, which determines when patch will be applied.
  6626. *
  6627. * @return int Priority number (higher - earlier)
  6628. */
  6629. public function getPriority()
  6630. {
  6631. return 100;
  6632. }
  6633. }
  6634. <?php
  6635. /*
  6636. * This file is part of the Prophecy.
  6637. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6638. * Marcello Duarte <marcello.duarte@gmail.com>
  6639. *
  6640. * For the full copyright and license information, please view the LICENSE
  6641. * file that was distributed with this source code.
  6642. */
  6643. namespace Prophecy\Doubler\ClassPatch;
  6644. use Prophecy\Doubler\Generator\Node\ClassNode;
  6645. use Prophecy\Doubler\Generator\Node\MethodNode;
  6646. /**
  6647. * SplFileInfo patch.
  6648. * Makes SplFileInfo and derivative classes usable with Prophecy.
  6649. *
  6650. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6651. */
  6652. class SplFileInfoPatch implements ClassPatchInterface
  6653. {
  6654. /**
  6655. * Supports everything that extends SplFileInfo.
  6656. *
  6657. * @param ClassNode $node
  6658. *
  6659. * @return bool
  6660. */
  6661. public function supports(ClassNode $node)
  6662. {
  6663. if (null === $node->getParentClass()) {
  6664. return false;
  6665. }
  6666. return 'SplFileInfo' === $node->getParentClass()
  6667. || is_subclass_of($node->getParentClass(), 'SplFileInfo')
  6668. ;
  6669. }
  6670. /**
  6671. * Updated constructor code to call parent one with dummy file argument.
  6672. *
  6673. * @param ClassNode $node
  6674. */
  6675. public function apply(ClassNode $node)
  6676. {
  6677. if ($node->hasMethod('__construct')) {
  6678. $constructor = $node->getMethod('__construct');
  6679. } else {
  6680. $constructor = new MethodNode('__construct');
  6681. $node->addMethod($constructor);
  6682. }
  6683. if ($this->nodeIsDirectoryIterator($node)) {
  6684. $constructor->setCode('return parent::__construct("' . __DIR__ . '");');
  6685. return;
  6686. }
  6687. $constructor->useParentCode();
  6688. }
  6689. /**
  6690. * Returns patch priority, which determines when patch will be applied.
  6691. *
  6692. * @return int Priority number (higher - earlier)
  6693. */
  6694. public function getPriority()
  6695. {
  6696. return 50;
  6697. }
  6698. /**
  6699. * @param ClassNode $node
  6700. * @return boolean
  6701. */
  6702. private function nodeIsDirectoryIterator(ClassNode $node)
  6703. {
  6704. $parent = $node->getParentClass();
  6705. return 'DirectoryIterator' === $parent
  6706. || is_subclass_of($parent, 'DirectoryIterator');
  6707. }
  6708. }
  6709. <?php
  6710. /*
  6711. * This file is part of the Prophecy.
  6712. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6713. * Marcello Duarte <marcello.duarte@gmail.com>
  6714. *
  6715. * For the full copyright and license information, please view the LICENSE
  6716. * file that was distributed with this source code.
  6717. */
  6718. namespace Prophecy\Doubler\ClassPatch;
  6719. use Prophecy\Doubler\Generator\Node\ClassNode;
  6720. use Prophecy\Doubler\Generator\Node\MethodNode;
  6721. /**
  6722. * Disable constructor.
  6723. * Makes all constructor arguments optional.
  6724. *
  6725. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6726. */
  6727. class DisableConstructorPatch implements ClassPatchInterface
  6728. {
  6729. /**
  6730. * Checks if class has `__construct` method.
  6731. *
  6732. * @param ClassNode $node
  6733. *
  6734. * @return bool
  6735. */
  6736. public function supports(ClassNode $node)
  6737. {
  6738. return true;
  6739. }
  6740. /**
  6741. * Makes all class constructor arguments optional.
  6742. *
  6743. * @param ClassNode $node
  6744. */
  6745. public function apply(ClassNode $node)
  6746. {
  6747. if (!$node->hasMethod('__construct')) {
  6748. $node->addMethod(new MethodNode('__construct', ''));
  6749. return;
  6750. }
  6751. $constructor = $node->getMethod('__construct');
  6752. foreach ($constructor->getArguments() as $argument) {
  6753. $argument->setDefault(null);
  6754. }
  6755. $constructor->setCode(<<<PHP
  6756. if (0 < func_num_args()) {
  6757. call_user_func_array(array('parent', '__construct'), func_get_args());
  6758. }
  6759. PHP
  6760. );
  6761. }
  6762. /**
  6763. * Returns patch priority, which determines when patch will be applied.
  6764. *
  6765. * @return int Priority number (higher - earlier)
  6766. */
  6767. public function getPriority()
  6768. {
  6769. return 100;
  6770. }
  6771. }
  6772. <?php
  6773. /*
  6774. * This file is part of the Prophecy.
  6775. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6776. * Marcello Duarte <marcello.duarte@gmail.com>
  6777. *
  6778. * For the full copyright and license information, please view the LICENSE
  6779. * file that was distributed with this source code.
  6780. */
  6781. namespace Prophecy\Doubler\ClassPatch;
  6782. use Prophecy\Doubler\Generator\Node\ClassNode;
  6783. /**
  6784. * Exception patch for HHVM to remove the stubs from special methods
  6785. *
  6786. * @author Christophe Coevoet <stof@notk.org>
  6787. */
  6788. class HhvmExceptionPatch implements ClassPatchInterface
  6789. {
  6790. /**
  6791. * Supports exceptions on HHVM.
  6792. *
  6793. * @param ClassNode $node
  6794. *
  6795. * @return bool
  6796. */
  6797. public function supports(ClassNode $node)
  6798. {
  6799. if (!defined('HHVM_VERSION')) {
  6800. return false;
  6801. }
  6802. return 'Exception' === $node->getParentClass() || is_subclass_of($node->getParentClass(), 'Exception');
  6803. }
  6804. /**
  6805. * Removes special exception static methods from the doubled methods.
  6806. *
  6807. * @param ClassNode $node
  6808. *
  6809. * @return void
  6810. */
  6811. public function apply(ClassNode $node)
  6812. {
  6813. if ($node->hasMethod('setTraceOptions')) {
  6814. $node->getMethod('setTraceOptions')->useParentCode();
  6815. }
  6816. if ($node->hasMethod('getTraceOptions')) {
  6817. $node->getMethod('getTraceOptions')->useParentCode();
  6818. }
  6819. }
  6820. /**
  6821. * {@inheritdoc}
  6822. */
  6823. public function getPriority()
  6824. {
  6825. return -50;
  6826. }
  6827. }
  6828. <?php
  6829. /*
  6830. * This file is part of the Prophecy.
  6831. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6832. * Marcello Duarte <marcello.duarte@gmail.com>
  6833. *
  6834. * For the full copyright and license information, please view the LICENSE
  6835. * file that was distributed with this source code.
  6836. */
  6837. namespace Prophecy\Doubler\ClassPatch;
  6838. use Prophecy\Doubler\Generator\Node\ClassNode;
  6839. /**
  6840. * ReflectionClass::newInstance patch.
  6841. * Makes first argument of newInstance optional, since it works but signature is misleading
  6842. *
  6843. * @author Florian Klein <florian.klein@free.fr>
  6844. */
  6845. class ReflectionClassNewInstancePatch implements ClassPatchInterface
  6846. {
  6847. /**
  6848. * Supports ReflectionClass
  6849. *
  6850. * @param ClassNode $node
  6851. *
  6852. * @return bool
  6853. */
  6854. public function supports(ClassNode $node)
  6855. {
  6856. return 'ReflectionClass' === $node->getParentClass();
  6857. }
  6858. /**
  6859. * Updates newInstance's first argument to make it optional
  6860. *
  6861. * @param ClassNode $node
  6862. */
  6863. public function apply(ClassNode $node)
  6864. {
  6865. foreach ($node->getMethod('newInstance')->getArguments() as $argument) {
  6866. $argument->setDefault(null);
  6867. }
  6868. }
  6869. /**
  6870. * Returns patch priority, which determines when patch will be applied.
  6871. *
  6872. * @return int Priority number (higher = earlier)
  6873. */
  6874. public function getPriority()
  6875. {
  6876. return 50;
  6877. }
  6878. }
  6879. <?php
  6880. /*
  6881. * This file is part of the Prophecy.
  6882. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6883. * Marcello Duarte <marcello.duarte@gmail.com>
  6884. *
  6885. * For the full copyright and license information, please view the LICENSE
  6886. * file that was distributed with this source code.
  6887. */
  6888. namespace Prophecy\Doubler\ClassPatch;
  6889. use Prophecy\Doubler\Generator\Node\ClassNode;
  6890. /**
  6891. * Class patch interface.
  6892. * Class patches extend doubles functionality or help
  6893. * Prophecy to avoid some internal PHP bugs.
  6894. *
  6895. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6896. */
  6897. interface ClassPatchInterface
  6898. {
  6899. /**
  6900. * Checks if patch supports specific class node.
  6901. *
  6902. * @param ClassNode $node
  6903. *
  6904. * @return bool
  6905. */
  6906. public function supports(ClassNode $node);
  6907. /**
  6908. * Applies patch to the specific class node.
  6909. *
  6910. * @param ClassNode $node
  6911. * @return void
  6912. */
  6913. public function apply(ClassNode $node);
  6914. /**
  6915. * Returns patch priority, which determines when patch will be applied.
  6916. *
  6917. * @return int Priority number (higher - earlier)
  6918. */
  6919. public function getPriority();
  6920. }
  6921. <?php
  6922. /*
  6923. * This file is part of the Prophecy.
  6924. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6925. * Marcello Duarte <marcello.duarte@gmail.com>
  6926. *
  6927. * For the full copyright and license information, please view the LICENSE
  6928. * file that was distributed with this source code.
  6929. */
  6930. namespace Prophecy\Doubler;
  6931. use ReflectionClass;
  6932. /**
  6933. * Name generator.
  6934. * Generates classname for double.
  6935. *
  6936. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6937. */
  6938. class NameGenerator
  6939. {
  6940. private static $counter = 1;
  6941. /**
  6942. * Generates name.
  6943. *
  6944. * @param ReflectionClass $class
  6945. * @param ReflectionClass[] $interfaces
  6946. *
  6947. * @return string
  6948. */
  6949. public function name(ReflectionClass $class = null, array $interfaces)
  6950. {
  6951. $parts = array();
  6952. if (null !== $class) {
  6953. $parts[] = $class->getName();
  6954. } else {
  6955. foreach ($interfaces as $interface) {
  6956. $parts[] = $interface->getShortName();
  6957. }
  6958. }
  6959. if (!count($parts)) {
  6960. $parts[] = 'stdClass';
  6961. }
  6962. return sprintf('Double\%s\P%d', implode('\\', $parts), self::$counter++);
  6963. }
  6964. }
  6965. <?php
  6966. /*
  6967. * This file is part of the Prophecy.
  6968. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6969. * Marcello Duarte <marcello.duarte@gmail.com>
  6970. *
  6971. * For the full copyright and license information, please view the LICENSE
  6972. * file that was distributed with this source code.
  6973. */
  6974. namespace Prophecy\Prediction;
  6975. use Prophecy\Call\Call;
  6976. use Prophecy\Prophecy\ObjectProphecy;
  6977. use Prophecy\Prophecy\MethodProphecy;
  6978. use Prophecy\Argument\ArgumentsWildcard;
  6979. use Prophecy\Argument\Token\AnyValuesToken;
  6980. use Prophecy\Util\StringUtil;
  6981. use Prophecy\Exception\Prediction\UnexpectedCallsCountException;
  6982. /**
  6983. * Prediction interface.
  6984. * Predictions are logical test blocks, tied to `should...` keyword.
  6985. *
  6986. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6987. */
  6988. class CallTimesPrediction implements PredictionInterface
  6989. {
  6990. private $times;
  6991. private $util;
  6992. /**
  6993. * Initializes prediction.
  6994. *
  6995. * @param int $times
  6996. * @param StringUtil $util
  6997. */
  6998. public function __construct($times, StringUtil $util = null)
  6999. {
  7000. $this->times = intval($times);
  7001. $this->util = $util ?: new StringUtil;
  7002. }
  7003. /**
  7004. * Tests that there was exact amount of calls made.
  7005. *
  7006. * @param Call[] $calls
  7007. * @param ObjectProphecy $object
  7008. * @param MethodProphecy $method
  7009. *
  7010. * @throws \Prophecy\Exception\Prediction\UnexpectedCallsCountException
  7011. */
  7012. public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
  7013. {
  7014. if ($this->times == count($calls)) {
  7015. return;
  7016. }
  7017. $methodCalls = $object->findProphecyMethodCalls(
  7018. $method->getMethodName(),
  7019. new ArgumentsWildcard(array(new AnyValuesToken))
  7020. );
  7021. if (count($calls)) {
  7022. $message = sprintf(
  7023. "Expected exactly %d calls that match:\n".
  7024. " %s->%s(%s)\n".
  7025. "but %d were made:\n%s",
  7026. $this->times,
  7027. get_class($object->reveal()),
  7028. $method->getMethodName(),
  7029. $method->getArgumentsWildcard(),
  7030. count($calls),
  7031. $this->util->stringifyCalls($calls)
  7032. );
  7033. } elseif (count($methodCalls)) {
  7034. $message = sprintf(
  7035. "Expected exactly %d calls that match:\n".
  7036. " %s->%s(%s)\n".
  7037. "but none were made.\n".
  7038. "Recorded `%s(...)` calls:\n%s",
  7039. $this->times,
  7040. get_class($object->reveal()),
  7041. $method->getMethodName(),
  7042. $method->getArgumentsWildcard(),
  7043. $method->getMethodName(),
  7044. $this->util->stringifyCalls($methodCalls)
  7045. );
  7046. } else {
  7047. $message = sprintf(
  7048. "Expected exactly %d calls that match:\n".
  7049. " %s->%s(%s)\n".
  7050. "but none were made.",
  7051. $this->times,
  7052. get_class($object->reveal()),
  7053. $method->getMethodName(),
  7054. $method->getArgumentsWildcard()
  7055. );
  7056. }
  7057. throw new UnexpectedCallsCountException($message, $method, $this->times, $calls);
  7058. }
  7059. }
  7060. <?php
  7061. /*
  7062. * This file is part of the Prophecy.
  7063. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7064. * Marcello Duarte <marcello.duarte@gmail.com>
  7065. *
  7066. * For the full copyright and license information, please view the LICENSE
  7067. * file that was distributed with this source code.
  7068. */
  7069. namespace Prophecy\Prediction;
  7070. use Prophecy\Call\Call;
  7071. use Prophecy\Prophecy\ObjectProphecy;
  7072. use Prophecy\Prophecy\MethodProphecy;
  7073. use Prophecy\Util\StringUtil;
  7074. use Prophecy\Exception\Prediction\UnexpectedCallsException;
  7075. /**
  7076. * No calls prediction.
  7077. *
  7078. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7079. */
  7080. class NoCallsPrediction implements PredictionInterface
  7081. {
  7082. private $util;
  7083. /**
  7084. * Initializes prediction.
  7085. *
  7086. * @param null|StringUtil $util
  7087. */
  7088. public function __construct(StringUtil $util = null)
  7089. {
  7090. $this->util = $util ?: new StringUtil;
  7091. }
  7092. /**
  7093. * Tests that there were no calls made.
  7094. *
  7095. * @param Call[] $calls
  7096. * @param ObjectProphecy $object
  7097. * @param MethodProphecy $method
  7098. *
  7099. * @throws \Prophecy\Exception\Prediction\UnexpectedCallsException
  7100. */
  7101. public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
  7102. {
  7103. if (!count($calls)) {
  7104. return;
  7105. }
  7106. $verb = count($calls) === 1 ? 'was' : 'were';
  7107. throw new UnexpectedCallsException(sprintf(
  7108. "No calls expected that match:\n".
  7109. " %s->%s(%s)\n".
  7110. "but %d %s made:\n%s",
  7111. get_class($object->reveal()),
  7112. $method->getMethodName(),
  7113. $method->getArgumentsWildcard(),
  7114. count($calls),
  7115. $verb,
  7116. $this->util->stringifyCalls($calls)
  7117. ), $method, $calls);
  7118. }
  7119. }
  7120. <?php
  7121. /*
  7122. * This file is part of the Prophecy.
  7123. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7124. * Marcello Duarte <marcello.duarte@gmail.com>
  7125. *
  7126. * For the full copyright and license information, please view the LICENSE
  7127. * file that was distributed with this source code.
  7128. */
  7129. namespace Prophecy\Prediction;
  7130. use Prophecy\Call\Call;
  7131. use Prophecy\Prophecy\ObjectProphecy;
  7132. use Prophecy\Prophecy\MethodProphecy;
  7133. /**
  7134. * Prediction interface.
  7135. * Predictions are logical test blocks, tied to `should...` keyword.
  7136. *
  7137. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7138. */
  7139. interface PredictionInterface
  7140. {
  7141. /**
  7142. * Tests that double fulfilled prediction.
  7143. *
  7144. * @param Call[] $calls
  7145. * @param ObjectProphecy $object
  7146. * @param MethodProphecy $method
  7147. *
  7148. * @throws object
  7149. * @return void
  7150. */
  7151. public function check(array $calls, ObjectProphecy $object, MethodProphecy $method);
  7152. }
  7153. <?php
  7154. /*
  7155. * This file is part of the Prophecy.
  7156. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7157. * Marcello Duarte <marcello.duarte@gmail.com>
  7158. *
  7159. * For the full copyright and license information, please view the LICENSE
  7160. * file that was distributed with this source code.
  7161. */
  7162. namespace Prophecy\Prediction;
  7163. use Prophecy\Call\Call;
  7164. use Prophecy\Prophecy\ObjectProphecy;
  7165. use Prophecy\Prophecy\MethodProphecy;
  7166. use Prophecy\Exception\InvalidArgumentException;
  7167. use Closure;
  7168. /**
  7169. * Callback prediction.
  7170. *
  7171. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7172. */
  7173. class CallbackPrediction implements PredictionInterface
  7174. {
  7175. private $callback;
  7176. /**
  7177. * Initializes callback prediction.
  7178. *
  7179. * @param callable $callback Custom callback
  7180. *
  7181. * @throws \Prophecy\Exception\InvalidArgumentException
  7182. */
  7183. public function __construct($callback)
  7184. {
  7185. if (!is_callable($callback)) {
  7186. throw new InvalidArgumentException(sprintf(
  7187. 'Callable expected as an argument to CallbackPrediction, but got %s.',
  7188. gettype($callback)
  7189. ));
  7190. }
  7191. $this->callback = $callback;
  7192. }
  7193. /**
  7194. * Executes preset callback.
  7195. *
  7196. * @param Call[] $calls
  7197. * @param ObjectProphecy $object
  7198. * @param MethodProphecy $method
  7199. */
  7200. public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
  7201. {
  7202. $callback = $this->callback;
  7203. if ($callback instanceof Closure && method_exists('Closure', 'bind')) {
  7204. $callback = Closure::bind($callback, $object);
  7205. }
  7206. call_user_func($callback, $calls, $object, $method);
  7207. }
  7208. }
  7209. <?php
  7210. /*
  7211. * This file is part of the Prophecy.
  7212. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7213. * Marcello Duarte <marcello.duarte@gmail.com>
  7214. *
  7215. * For the full copyright and license information, please view the LICENSE
  7216. * file that was distributed with this source code.
  7217. */
  7218. namespace Prophecy\Prediction;
  7219. use Prophecy\Call\Call;
  7220. use Prophecy\Prophecy\ObjectProphecy;
  7221. use Prophecy\Prophecy\MethodProphecy;
  7222. use Prophecy\Argument\ArgumentsWildcard;
  7223. use Prophecy\Argument\Token\AnyValuesToken;
  7224. use Prophecy\Util\StringUtil;
  7225. use Prophecy\Exception\Prediction\NoCallsException;
  7226. /**
  7227. * Call prediction.
  7228. *
  7229. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7230. */
  7231. class CallPrediction implements PredictionInterface
  7232. {
  7233. private $util;
  7234. /**
  7235. * Initializes prediction.
  7236. *
  7237. * @param StringUtil $util
  7238. */
  7239. public function __construct(StringUtil $util = null)
  7240. {
  7241. $this->util = $util ?: new StringUtil;
  7242. }
  7243. /**
  7244. * Tests that there was at least one call.
  7245. *
  7246. * @param Call[] $calls
  7247. * @param ObjectProphecy $object
  7248. * @param MethodProphecy $method
  7249. *
  7250. * @throws \Prophecy\Exception\Prediction\NoCallsException
  7251. */
  7252. public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
  7253. {
  7254. if (count($calls)) {
  7255. return;
  7256. }
  7257. $methodCalls = $object->findProphecyMethodCalls(
  7258. $method->getMethodName(),
  7259. new ArgumentsWildcard(array(new AnyValuesToken))
  7260. );
  7261. if (count($methodCalls)) {
  7262. throw new NoCallsException(sprintf(
  7263. "No calls have been made that match:\n".
  7264. " %s->%s(%s)\n".
  7265. "but expected at least one.\n".
  7266. "Recorded `%s(...)` calls:\n%s",
  7267. get_class($object->reveal()),
  7268. $method->getMethodName(),
  7269. $method->getArgumentsWildcard(),
  7270. $method->getMethodName(),
  7271. $this->util->stringifyCalls($methodCalls)
  7272. ), $method);
  7273. }
  7274. throw new NoCallsException(sprintf(
  7275. "No calls have been made that match:\n".
  7276. " %s->%s(%s)\n".
  7277. "but expected at least one.",
  7278. get_class($object->reveal()),
  7279. $method->getMethodName(),
  7280. $method->getArgumentsWildcard()
  7281. ), $method);
  7282. }
  7283. }
  7284. <?php
  7285. /*
  7286. * This file is part of the Prophecy.
  7287. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7288. * Marcello Duarte <marcello.duarte@gmail.com>
  7289. *
  7290. * For the full copyright and license information, please view the LICENSE
  7291. * file that was distributed with this source code.
  7292. */
  7293. namespace Prophecy\Call;
  7294. use Exception;
  7295. /**
  7296. * Call object.
  7297. *
  7298. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7299. */
  7300. class Call
  7301. {
  7302. private $methodName;
  7303. private $arguments;
  7304. private $returnValue;
  7305. private $exception;
  7306. private $file;
  7307. private $line;
  7308. /**
  7309. * Initializes call.
  7310. *
  7311. * @param string $methodName
  7312. * @param array $arguments
  7313. * @param mixed $returnValue
  7314. * @param Exception $exception
  7315. * @param null|string $file
  7316. * @param null|int $line
  7317. */
  7318. public function __construct($methodName, array $arguments, $returnValue,
  7319. Exception $exception = null, $file, $line)
  7320. {
  7321. $this->methodName = $methodName;
  7322. $this->arguments = $arguments;
  7323. $this->returnValue = $returnValue;
  7324. $this->exception = $exception;
  7325. if ($file) {
  7326. $this->file = $file;
  7327. $this->line = intval($line);
  7328. }
  7329. }
  7330. /**
  7331. * Returns called method name.
  7332. *
  7333. * @return string
  7334. */
  7335. public function getMethodName()
  7336. {
  7337. return $this->methodName;
  7338. }
  7339. /**
  7340. * Returns called method arguments.
  7341. *
  7342. * @return array
  7343. */
  7344. public function getArguments()
  7345. {
  7346. return $this->arguments;
  7347. }
  7348. /**
  7349. * Returns called method return value.
  7350. *
  7351. * @return null|mixed
  7352. */
  7353. public function getReturnValue()
  7354. {
  7355. return $this->returnValue;
  7356. }
  7357. /**
  7358. * Returns exception that call thrown.
  7359. *
  7360. * @return null|Exception
  7361. */
  7362. public function getException()
  7363. {
  7364. return $this->exception;
  7365. }
  7366. /**
  7367. * Returns callee filename.
  7368. *
  7369. * @return string
  7370. */
  7371. public function getFile()
  7372. {
  7373. return $this->file;
  7374. }
  7375. /**
  7376. * Returns callee line number.
  7377. *
  7378. * @return int
  7379. */
  7380. public function getLine()
  7381. {
  7382. return $this->line;
  7383. }
  7384. /**
  7385. * Returns short notation for callee place.
  7386. *
  7387. * @return string
  7388. */
  7389. public function getCallPlace()
  7390. {
  7391. if (null === $this->file) {
  7392. return 'unknown';
  7393. }
  7394. return sprintf('%s:%d', $this->file, $this->line);
  7395. }
  7396. }
  7397. <?php
  7398. /*
  7399. * This file is part of the Prophecy.
  7400. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7401. * Marcello Duarte <marcello.duarte@gmail.com>
  7402. *
  7403. * For the full copyright and license information, please view the LICENSE
  7404. * file that was distributed with this source code.
  7405. */
  7406. namespace Prophecy\Call;
  7407. use Prophecy\Prophecy\MethodProphecy;
  7408. use Prophecy\Prophecy\ObjectProphecy;
  7409. use Prophecy\Argument\ArgumentsWildcard;
  7410. use Prophecy\Util\StringUtil;
  7411. use Prophecy\Exception\Call\UnexpectedCallException;
  7412. /**
  7413. * Calls receiver & manager.
  7414. *
  7415. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7416. */
  7417. class CallCenter
  7418. {
  7419. private $util;
  7420. /**
  7421. * @var Call[]
  7422. */
  7423. private $recordedCalls = array();
  7424. /**
  7425. * Initializes call center.
  7426. *
  7427. * @param StringUtil $util
  7428. */
  7429. public function __construct(StringUtil $util = null)
  7430. {
  7431. $this->util = $util ?: new StringUtil;
  7432. }
  7433. /**
  7434. * Makes and records specific method call for object prophecy.
  7435. *
  7436. * @param ObjectProphecy $prophecy
  7437. * @param string $methodName
  7438. * @param array $arguments
  7439. *
  7440. * @return mixed Returns null if no promise for prophecy found or promise return value.
  7441. *
  7442. * @throws \Prophecy\Exception\Call\UnexpectedCallException If no appropriate method prophecy found
  7443. */
  7444. public function makeCall(ObjectProphecy $prophecy, $methodName, array $arguments)
  7445. {
  7446. $backtrace = debug_backtrace();
  7447. $file = $line = null;
  7448. if (isset($backtrace[2]) && isset($backtrace[2]['file'])) {
  7449. $file = $backtrace[2]['file'];
  7450. $line = $backtrace[2]['line'];
  7451. }
  7452. // If no method prophecies defined, then it's a dummy, so we'll just return null
  7453. if ('__destruct' === $methodName || 0 == count($prophecy->getMethodProphecies())) {
  7454. $this->recordedCalls[] = new Call($methodName, $arguments, null, null, $file, $line);
  7455. return null;
  7456. }
  7457. // There are method prophecies, so it's a fake/stub. Searching prophecy for this call
  7458. $matches = array();
  7459. foreach ($prophecy->getMethodProphecies($methodName) as $methodProphecy) {
  7460. if (0 < $score = $methodProphecy->getArgumentsWildcard()->scoreArguments($arguments)) {
  7461. $matches[] = array($score, $methodProphecy);
  7462. }
  7463. }
  7464. // If fake/stub doesn't have method prophecy for this call - throw exception
  7465. if (!count($matches)) {
  7466. throw $this->createUnexpectedCallException($prophecy, $methodName, $arguments);
  7467. }
  7468. // Sort matches by their score value
  7469. @usort($matches, function ($match1, $match2) { return $match2[0] - $match1[0]; });
  7470. // If Highest rated method prophecy has a promise - execute it or return null instead
  7471. $returnValue = null;
  7472. $exception = null;
  7473. if ($promise = $matches[0][1]->getPromise()) {
  7474. try {
  7475. $returnValue = $promise->execute($arguments, $prophecy, $matches[0][1]);
  7476. } catch (\Exception $e) {
  7477. $exception = $e;
  7478. }
  7479. }
  7480. $this->recordedCalls[] = new Call(
  7481. $methodName, $arguments, $returnValue, $exception, $file, $line
  7482. );
  7483. if (null !== $exception) {
  7484. throw $exception;
  7485. }
  7486. return $returnValue;
  7487. }
  7488. /**
  7489. * Searches for calls by method name & arguments wildcard.
  7490. *
  7491. * @param string $methodName
  7492. * @param ArgumentsWildcard $wildcard
  7493. *
  7494. * @return Call[]
  7495. */
  7496. public function findCalls($methodName, ArgumentsWildcard $wildcard)
  7497. {
  7498. return array_values(
  7499. array_filter($this->recordedCalls, function (Call $call) use ($methodName, $wildcard) {
  7500. return $methodName === $call->getMethodName()
  7501. && 0 < $wildcard->scoreArguments($call->getArguments())
  7502. ;
  7503. })
  7504. );
  7505. }
  7506. private function createUnexpectedCallException(ObjectProphecy $prophecy, $methodName,
  7507. array $arguments)
  7508. {
  7509. $classname = get_class($prophecy->reveal());
  7510. $argstring = implode(', ', array_map(array($this->util, 'stringify'), $arguments));
  7511. $expected = implode("\n", array_map(function (MethodProphecy $methodProphecy) {
  7512. return sprintf(' - %s(%s)',
  7513. $methodProphecy->getMethodName(),
  7514. $methodProphecy->getArgumentsWildcard()
  7515. );
  7516. }, call_user_func_array('array_merge', $prophecy->getMethodProphecies())));
  7517. return new UnexpectedCallException(
  7518. sprintf(
  7519. "Method call:\n".
  7520. " - %s(%s)\n".
  7521. "on %s was not expected, expected calls were:\n%s",
  7522. $methodName, $argstring, $classname, $expected
  7523. ),
  7524. $prophecy, $methodName, $arguments
  7525. );
  7526. }
  7527. }
  7528. <?php
  7529. /*
  7530. * This file is part of the Prophecy.
  7531. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7532. * Marcello Duarte <marcello.duarte@gmail.com>
  7533. *
  7534. * For the full copyright and license information, please view the LICENSE
  7535. * file that was distributed with this source code.
  7536. */
  7537. namespace Prophecy\Promise;
  7538. use Doctrine\Instantiator\Instantiator;
  7539. use Prophecy\Prophecy\ObjectProphecy;
  7540. use Prophecy\Prophecy\MethodProphecy;
  7541. use Prophecy\Exception\InvalidArgumentException;
  7542. use ReflectionClass;
  7543. /**
  7544. * Throw promise.
  7545. *
  7546. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7547. */
  7548. class ThrowPromise implements PromiseInterface
  7549. {
  7550. private $exception;
  7551. /**
  7552. * @var \Doctrine\Instantiator\Instantiator
  7553. */
  7554. private $instantiator;
  7555. /**
  7556. * Initializes promise.
  7557. *
  7558. * @param string|\Exception $exception Exception class name or instance
  7559. *
  7560. * @throws \Prophecy\Exception\InvalidArgumentException
  7561. */
  7562. public function __construct($exception)
  7563. {
  7564. if (is_string($exception)) {
  7565. if (!class_exists($exception)
  7566. && 'Exception' !== $exception
  7567. && !is_subclass_of($exception, 'Exception')) {
  7568. throw new InvalidArgumentException(sprintf(
  7569. 'Exception class or instance expected as argument to ThrowPromise, but got %s.',
  7570. gettype($exception)
  7571. ));
  7572. }
  7573. } elseif (!$exception instanceof \Exception) {
  7574. throw new InvalidArgumentException(sprintf(
  7575. 'Exception class or instance expected as argument to ThrowPromise, but got %s.',
  7576. gettype($exception)
  7577. ));
  7578. }
  7579. $this->exception = $exception;
  7580. }
  7581. /**
  7582. * Throws predefined exception.
  7583. *
  7584. * @param array $args
  7585. * @param ObjectProphecy $object
  7586. * @param MethodProphecy $method
  7587. *
  7588. * @throws object
  7589. */
  7590. public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
  7591. {
  7592. if (is_string($this->exception)) {
  7593. $classname = $this->exception;
  7594. $reflection = new ReflectionClass($classname);
  7595. $constructor = $reflection->getConstructor();
  7596. if ($constructor->isPublic() && 0 == $constructor->getNumberOfRequiredParameters()) {
  7597. throw $reflection->newInstance();
  7598. }
  7599. if (!$this->instantiator) {
  7600. $this->instantiator = new Instantiator();
  7601. }
  7602. throw $this->instantiator->instantiate($classname);
  7603. }
  7604. throw $this->exception;
  7605. }
  7606. }
  7607. <?php
  7608. /*
  7609. * This file is part of the Prophecy.
  7610. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7611. * Marcello Duarte <marcello.duarte@gmail.com>
  7612. *
  7613. * For the full copyright and license information, please view the LICENSE
  7614. * file that was distributed with this source code.
  7615. */
  7616. namespace Prophecy\Promise;
  7617. use Prophecy\Exception\InvalidArgumentException;
  7618. use Prophecy\Prophecy\ObjectProphecy;
  7619. use Prophecy\Prophecy\MethodProphecy;
  7620. /**
  7621. * Return argument promise.
  7622. *
  7623. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7624. */
  7625. class ReturnArgumentPromise implements PromiseInterface
  7626. {
  7627. /**
  7628. * @var int
  7629. */
  7630. private $index;
  7631. /**
  7632. * Initializes callback promise.
  7633. *
  7634. * @param int $index The zero-indexed number of the argument to return
  7635. *
  7636. * @throws \Prophecy\Exception\InvalidArgumentException
  7637. */
  7638. public function __construct($index = 0)
  7639. {
  7640. if (!is_int($index) || $index < 0) {
  7641. throw new InvalidArgumentException(
  7642. 'Zero-based index expected as argument to ReturnArgumentPromise, but got %s.',
  7643. $index
  7644. );
  7645. }
  7646. $this->index = $index;
  7647. }
  7648. /**
  7649. * Returns nth argument if has one, null otherwise.
  7650. *
  7651. * @param array $args
  7652. * @param ObjectProphecy $object
  7653. * @param MethodProphecy $method
  7654. *
  7655. * @return null|mixed
  7656. */
  7657. public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
  7658. {
  7659. return count($args) > $this->index ? $args[$this->index] : null;
  7660. }
  7661. }
  7662. <?php
  7663. /*
  7664. * This file is part of the Prophecy.
  7665. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7666. * Marcello Duarte <marcello.duarte@gmail.com>
  7667. *
  7668. * For the full copyright and license information, please view the LICENSE
  7669. * file that was distributed with this source code.
  7670. */
  7671. namespace Prophecy\Promise;
  7672. use Prophecy\Prophecy\ObjectProphecy;
  7673. use Prophecy\Prophecy\MethodProphecy;
  7674. /**
  7675. * Return promise.
  7676. *
  7677. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7678. */
  7679. class ReturnPromise implements PromiseInterface
  7680. {
  7681. private $returnValues = array();
  7682. /**
  7683. * Initializes promise.
  7684. *
  7685. * @param array $returnValues Array of values
  7686. */
  7687. public function __construct(array $returnValues)
  7688. {
  7689. $this->returnValues = $returnValues;
  7690. }
  7691. /**
  7692. * Returns saved values one by one until last one, then continuously returns last value.
  7693. *
  7694. * @param array $args
  7695. * @param ObjectProphecy $object
  7696. * @param MethodProphecy $method
  7697. *
  7698. * @return mixed
  7699. */
  7700. public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
  7701. {
  7702. $value = array_shift($this->returnValues);
  7703. if (!count($this->returnValues)) {
  7704. $this->returnValues[] = $value;
  7705. }
  7706. return $value;
  7707. }
  7708. }
  7709. <?php
  7710. /*
  7711. * This file is part of the Prophecy.
  7712. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7713. * Marcello Duarte <marcello.duarte@gmail.com>
  7714. *
  7715. * For the full copyright and license information, please view the LICENSE
  7716. * file that was distributed with this source code.
  7717. */
  7718. namespace Prophecy\Promise;
  7719. use Prophecy\Prophecy\ObjectProphecy;
  7720. use Prophecy\Prophecy\MethodProphecy;
  7721. use Prophecy\Exception\InvalidArgumentException;
  7722. use Closure;
  7723. /**
  7724. * Callback promise.
  7725. *
  7726. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7727. */
  7728. class CallbackPromise implements PromiseInterface
  7729. {
  7730. private $callback;
  7731. /**
  7732. * Initializes callback promise.
  7733. *
  7734. * @param callable $callback Custom callback
  7735. *
  7736. * @throws \Prophecy\Exception\InvalidArgumentException
  7737. */
  7738. public function __construct($callback)
  7739. {
  7740. if (!is_callable($callback)) {
  7741. throw new InvalidArgumentException(sprintf(
  7742. 'Callable expected as an argument to CallbackPromise, but got %s.',
  7743. gettype($callback)
  7744. ));
  7745. }
  7746. $this->callback = $callback;
  7747. }
  7748. /**
  7749. * Evaluates promise callback.
  7750. *
  7751. * @param array $args
  7752. * @param ObjectProphecy $object
  7753. * @param MethodProphecy $method
  7754. *
  7755. * @return mixed
  7756. */
  7757. public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
  7758. {
  7759. $callback = $this->callback;
  7760. if ($callback instanceof Closure && method_exists('Closure', 'bind')) {
  7761. $callback = Closure::bind($callback, $object);
  7762. }
  7763. return call_user_func($callback, $args, $object, $method);
  7764. }
  7765. }
  7766. <?php
  7767. /*
  7768. * This file is part of the Prophecy.
  7769. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7770. * Marcello Duarte <marcello.duarte@gmail.com>
  7771. *
  7772. * For the full copyright and license information, please view the LICENSE
  7773. * file that was distributed with this source code.
  7774. */
  7775. namespace Prophecy\Promise;
  7776. use Prophecy\Prophecy\ObjectProphecy;
  7777. use Prophecy\Prophecy\MethodProphecy;
  7778. /**
  7779. * Promise interface.
  7780. * Promises are logical blocks, tied to `will...` keyword.
  7781. *
  7782. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7783. */
  7784. interface PromiseInterface
  7785. {
  7786. /**
  7787. * Evaluates promise.
  7788. *
  7789. * @param array $args
  7790. * @param ObjectProphecy $object
  7791. * @param MethodProphecy $method
  7792. *
  7793. * @return mixed
  7794. */
  7795. public function execute(array $args, ObjectProphecy $object, MethodProphecy $method);
  7796. }
  7797. <?php
  7798. /*
  7799. * This file is part of the Prophecy.
  7800. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7801. * Marcello Duarte <marcello.duarte@gmail.com>
  7802. *
  7803. * For the full copyright and license information, please view the LICENSE
  7804. * file that was distributed with this source code.
  7805. */
  7806. namespace Prophecy\Argument;
  7807. /**
  7808. * Arguments wildcarding.
  7809. *
  7810. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7811. */
  7812. class ArgumentsWildcard
  7813. {
  7814. /**
  7815. * @var Token\TokenInterface[]
  7816. */
  7817. private $tokens = array();
  7818. private $string;
  7819. /**
  7820. * Initializes wildcard.
  7821. *
  7822. * @param array $arguments Array of argument tokens or values
  7823. */
  7824. public function __construct(array $arguments)
  7825. {
  7826. foreach ($arguments as $argument) {
  7827. if (!$argument instanceof Token\TokenInterface) {
  7828. $argument = new Token\ExactValueToken($argument);
  7829. }
  7830. $this->tokens[] = $argument;
  7831. }
  7832. }
  7833. /**
  7834. * Calculates wildcard match score for provided arguments.
  7835. *
  7836. * @param array $arguments
  7837. *
  7838. * @return false|int False OR integer score (higher - better)
  7839. */
  7840. public function scoreArguments(array $arguments)
  7841. {
  7842. if (0 == count($arguments) && 0 == count($this->tokens)) {
  7843. return 1;
  7844. }
  7845. $arguments = array_values($arguments);
  7846. $totalScore = 0;
  7847. foreach ($this->tokens as $i => $token) {
  7848. $argument = isset($arguments[$i]) ? $arguments[$i] : null;
  7849. if (1 >= $score = $token->scoreArgument($argument)) {
  7850. return false;
  7851. }
  7852. $totalScore += $score;
  7853. if (true === $token->isLast()) {
  7854. return $totalScore;
  7855. }
  7856. }
  7857. if (count($arguments) > count($this->tokens)) {
  7858. return false;
  7859. }
  7860. return $totalScore;
  7861. }
  7862. /**
  7863. * Returns string representation for wildcard.
  7864. *
  7865. * @return string
  7866. */
  7867. public function __toString()
  7868. {
  7869. if (null === $this->string) {
  7870. $this->string = implode(', ', array_map(function ($token) {
  7871. return (string) $token;
  7872. }, $this->tokens));
  7873. }
  7874. return $this->string;
  7875. }
  7876. /**
  7877. * @return array
  7878. */
  7879. public function getTokens()
  7880. {
  7881. return $this->tokens;
  7882. }
  7883. }
  7884. <?php
  7885. /*
  7886. * This file is part of the Prophecy.
  7887. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7888. * Marcello Duarte <marcello.duarte@gmail.com>
  7889. *
  7890. * For the full copyright and license information, please view the LICENSE
  7891. * file that was distributed with this source code.
  7892. */
  7893. namespace Prophecy\Argument\Token;
  7894. /**
  7895. * Any single value token.
  7896. *
  7897. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7898. */
  7899. class AnyValueToken implements TokenInterface
  7900. {
  7901. /**
  7902. * Always scores 3 for any argument.
  7903. *
  7904. * @param $argument
  7905. *
  7906. * @return int
  7907. */
  7908. public function scoreArgument($argument)
  7909. {
  7910. return 3;
  7911. }
  7912. /**
  7913. * Returns false.
  7914. *
  7915. * @return bool
  7916. */
  7917. public function isLast()
  7918. {
  7919. return false;
  7920. }
  7921. /**
  7922. * Returns string representation for token.
  7923. *
  7924. * @return string
  7925. */
  7926. public function __toString()
  7927. {
  7928. return '*';
  7929. }
  7930. }
  7931. <?php
  7932. /*
  7933. * This file is part of the Prophecy.
  7934. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7935. * Marcello Duarte <marcello.duarte@gmail.com>
  7936. *
  7937. * For the full copyright and license information, please view the LICENSE
  7938. * file that was distributed with this source code.
  7939. */
  7940. namespace Prophecy\Argument\Token;
  7941. /**
  7942. * Array every entry token.
  7943. *
  7944. * @author Adrien Brault <adrien.brault@gmail.com>
  7945. */
  7946. class ArrayEveryEntryToken implements TokenInterface
  7947. {
  7948. /**
  7949. * @var TokenInterface
  7950. */
  7951. private $value;
  7952. /**
  7953. * @param mixed $value exact value or token
  7954. */
  7955. public function __construct($value)
  7956. {
  7957. if (!$value instanceof TokenInterface) {
  7958. $value = new ExactValueToken($value);
  7959. }
  7960. $this->value = $value;
  7961. }
  7962. /**
  7963. * {@inheritdoc}
  7964. */
  7965. public function scoreArgument($argument)
  7966. {
  7967. if (!$argument instanceof \Traversable && !is_array($argument)) {
  7968. return false;
  7969. }
  7970. $scores = array();
  7971. foreach ($argument as $key => $argumentEntry) {
  7972. $scores[] = $this->value->scoreArgument($argumentEntry);
  7973. }
  7974. if (empty($scores) || in_array(false, $scores, true)) {
  7975. return false;
  7976. }
  7977. return array_sum($scores) / count($scores);
  7978. }
  7979. /**
  7980. * {@inheritdoc}
  7981. */
  7982. public function isLast()
  7983. {
  7984. return false;
  7985. }
  7986. /**
  7987. * {@inheritdoc}
  7988. */
  7989. public function __toString()
  7990. {
  7991. return sprintf('[%s, ..., %s]', $this->value, $this->value);
  7992. }
  7993. /**
  7994. * @return TokenInterface
  7995. */
  7996. public function getValue()
  7997. {
  7998. return $this->value;
  7999. }
  8000. }
  8001. <?php
  8002. /*
  8003. * This file is part of the Prophecy.
  8004. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8005. * Marcello Duarte <marcello.duarte@gmail.com>
  8006. *
  8007. * For the full copyright and license information, please view the LICENSE
  8008. * file that was distributed with this source code.
  8009. */
  8010. namespace Prophecy\Argument\Token;
  8011. /**
  8012. * Logical AND token.
  8013. *
  8014. * @author Boris Mikhaylov <kaguxmail@gmail.com>
  8015. */
  8016. class LogicalAndToken implements TokenInterface
  8017. {
  8018. private $tokens = array();
  8019. /**
  8020. * @param array $arguments exact values or tokens
  8021. */
  8022. public function __construct(array $arguments)
  8023. {
  8024. foreach ($arguments as $argument) {
  8025. if (!$argument instanceof TokenInterface) {
  8026. $argument = new ExactValueToken($argument);
  8027. }
  8028. $this->tokens[] = $argument;
  8029. }
  8030. }
  8031. /**
  8032. * Scores maximum score from scores returned by tokens for this argument if all of them score.
  8033. *
  8034. * @param $argument
  8035. *
  8036. * @return bool|int
  8037. */
  8038. public function scoreArgument($argument)
  8039. {
  8040. if (0 === count($this->tokens)) {
  8041. return false;
  8042. }
  8043. $maxScore = 0;
  8044. foreach ($this->tokens as $token) {
  8045. $score = $token->scoreArgument($argument);
  8046. if (false === $score) {
  8047. return false;
  8048. }
  8049. $maxScore = max($score, $maxScore);
  8050. }
  8051. return $maxScore;
  8052. }
  8053. /**
  8054. * Returns false.
  8055. *
  8056. * @return boolean
  8057. */
  8058. public function isLast()
  8059. {
  8060. return false;
  8061. }
  8062. /**
  8063. * Returns string representation for token.
  8064. *
  8065. * @return string
  8066. */
  8067. public function __toString()
  8068. {
  8069. return sprintf('bool(%s)', implode(' AND ', $this->tokens));
  8070. }
  8071. }
  8072. <?php
  8073. /*
  8074. * This file is part of the Prophecy.
  8075. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8076. * Marcello Duarte <marcello.duarte@gmail.com>
  8077. *
  8078. * For the full copyright and license information, please view the LICENSE
  8079. * file that was distributed with this source code.
  8080. */
  8081. namespace Prophecy\Argument\Token;
  8082. /**
  8083. * Argument token interface.
  8084. *
  8085. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8086. */
  8087. interface TokenInterface
  8088. {
  8089. /**
  8090. * Calculates token match score for provided argument.
  8091. *
  8092. * @param $argument
  8093. *
  8094. * @return bool|int
  8095. */
  8096. public function scoreArgument($argument);
  8097. /**
  8098. * Returns true if this token prevents check of other tokens (is last one).
  8099. *
  8100. * @return bool|int
  8101. */
  8102. public function isLast();
  8103. /**
  8104. * Returns string representation for token.
  8105. *
  8106. * @return string
  8107. */
  8108. public function __toString();
  8109. }
  8110. <?php
  8111. /*
  8112. * This file is part of the Prophecy.
  8113. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8114. * Marcello Duarte <marcello.duarte@gmail.com>
  8115. *
  8116. * For the full copyright and license information, please view the LICENSE
  8117. * file that was distributed with this source code.
  8118. */
  8119. namespace Prophecy\Argument\Token;
  8120. use Prophecy\Exception\InvalidArgumentException;
  8121. /**
  8122. * Array entry token.
  8123. *
  8124. * @author Boris Mikhaylov <kaguxmail@gmail.com>
  8125. */
  8126. class ArrayEntryToken implements TokenInterface
  8127. {
  8128. /** @var \Prophecy\Argument\Token\TokenInterface */
  8129. private $key;
  8130. /** @var \Prophecy\Argument\Token\TokenInterface */
  8131. private $value;
  8132. /**
  8133. * @param mixed $key exact value or token
  8134. * @param mixed $value exact value or token
  8135. */
  8136. public function __construct($key, $value)
  8137. {
  8138. $this->key = $this->wrapIntoExactValueToken($key);
  8139. $this->value = $this->wrapIntoExactValueToken($value);
  8140. }
  8141. /**
  8142. * Scores half of combined scores from key and value tokens for same entry. Capped at 8.
  8143. * If argument implements \ArrayAccess without \Traversable, then key token is restricted to ExactValueToken.
  8144. *
  8145. * @param array|\ArrayAccess|\Traversable $argument
  8146. *
  8147. * @throws \Prophecy\Exception\InvalidArgumentException
  8148. * @return bool|int
  8149. */
  8150. public function scoreArgument($argument)
  8151. {
  8152. if ($argument instanceof \Traversable) {
  8153. $argument = iterator_to_array($argument);
  8154. }
  8155. if ($argument instanceof \ArrayAccess) {
  8156. $argument = $this->convertArrayAccessToEntry($argument);
  8157. }
  8158. if (!is_array($argument) || empty($argument)) {
  8159. return false;
  8160. }
  8161. $keyScores = array_map(array($this->key,'scoreArgument'), array_keys($argument));
  8162. $valueScores = array_map(array($this->value,'scoreArgument'), $argument);
  8163. $scoreEntry = function ($value, $key) {
  8164. return $value && $key ? min(8, ($key + $value) / 2) : false;
  8165. };
  8166. return max(array_map($scoreEntry, $valueScores, $keyScores));
  8167. }
  8168. /**
  8169. * Returns false.
  8170. *
  8171. * @return boolean
  8172. */
  8173. public function isLast()
  8174. {
  8175. return false;
  8176. }
  8177. /**
  8178. * Returns string representation for token.
  8179. *
  8180. * @return string
  8181. */
  8182. public function __toString()
  8183. {
  8184. return sprintf('[..., %s => %s, ...]', $this->key, $this->value);
  8185. }
  8186. /**
  8187. * Returns key
  8188. *
  8189. * @return TokenInterface
  8190. */
  8191. public function getKey()
  8192. {
  8193. return $this->key;
  8194. }
  8195. /**
  8196. * Returns value
  8197. *
  8198. * @return TokenInterface
  8199. */
  8200. public function getValue()
  8201. {
  8202. return $this->value;
  8203. }
  8204. /**
  8205. * Wraps non token $value into ExactValueToken
  8206. *
  8207. * @param $value
  8208. * @return TokenInterface
  8209. */
  8210. private function wrapIntoExactValueToken($value)
  8211. {
  8212. return $value instanceof TokenInterface ? $value : new ExactValueToken($value);
  8213. }
  8214. /**
  8215. * Converts instance of \ArrayAccess to key => value array entry
  8216. *
  8217. * @param \ArrayAccess $object
  8218. *
  8219. * @return array|null
  8220. * @throws \Prophecy\Exception\InvalidArgumentException
  8221. */
  8222. private function convertArrayAccessToEntry(\ArrayAccess $object)
  8223. {
  8224. if (!$this->key instanceof ExactValueToken) {
  8225. throw new InvalidArgumentException(sprintf(
  8226. 'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL.
  8227. 'But you used `%s`.',
  8228. $this->key
  8229. ));
  8230. }
  8231. $key = $this->key->getValue();
  8232. return $object->offsetExists($key) ? array($key => $object[$key]) : array();
  8233. }
  8234. }
  8235. <?php
  8236. /*
  8237. * This file is part of the Prophecy.
  8238. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8239. * Marcello Duarte <marcello.duarte@gmail.com>
  8240. *
  8241. * For the full copyright and license information, please view the LICENSE
  8242. * file that was distributed with this source code.
  8243. */
  8244. namespace Prophecy\Argument\Token;
  8245. /**
  8246. * Array elements count token.
  8247. *
  8248. * @author Boris Mikhaylov <kaguxmail@gmail.com>
  8249. */
  8250. class ArrayCountToken implements TokenInterface
  8251. {
  8252. private $count;
  8253. /**
  8254. * @param integer $value
  8255. */
  8256. public function __construct($value)
  8257. {
  8258. $this->count = $value;
  8259. }
  8260. /**
  8261. * Scores 6 when argument has preset number of elements.
  8262. *
  8263. * @param $argument
  8264. *
  8265. * @return bool|int
  8266. */
  8267. public function scoreArgument($argument)
  8268. {
  8269. return $this->isCountable($argument) && $this->hasProperCount($argument) ? 6 : false;
  8270. }
  8271. /**
  8272. * Returns false.
  8273. *
  8274. * @return boolean
  8275. */
  8276. public function isLast()
  8277. {
  8278. return false;
  8279. }
  8280. /**
  8281. * Returns string representation for token.
  8282. *
  8283. * @return string
  8284. */
  8285. public function __toString()
  8286. {
  8287. return sprintf('count(%s)', $this->count);
  8288. }
  8289. /**
  8290. * Returns true if object is either array or instance of \Countable
  8291. *
  8292. * @param $argument
  8293. * @return bool
  8294. */
  8295. private function isCountable($argument)
  8296. {
  8297. return (is_array($argument) || $argument instanceof \Countable);
  8298. }
  8299. /**
  8300. * Returns true if $argument has expected number of elements
  8301. *
  8302. * @param array|\Countable $argument
  8303. *
  8304. * @return bool
  8305. */
  8306. private function hasProperCount($argument)
  8307. {
  8308. return $this->count === count($argument);
  8309. }
  8310. }
  8311. <?php
  8312. /*
  8313. * This file is part of the Prophecy.
  8314. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8315. * Marcello Duarte <marcello.duarte@gmail.com>
  8316. *
  8317. * For the full copyright and license information, please view the LICENSE
  8318. * file that was distributed with this source code.
  8319. */
  8320. namespace Prophecy\Argument\Token;
  8321. /**
  8322. * Any values token.
  8323. *
  8324. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8325. */
  8326. class AnyValuesToken implements TokenInterface
  8327. {
  8328. /**
  8329. * Always scores 2 for any argument.
  8330. *
  8331. * @param $argument
  8332. *
  8333. * @return int
  8334. */
  8335. public function scoreArgument($argument)
  8336. {
  8337. return 2;
  8338. }
  8339. /**
  8340. * Returns true to stop wildcard from processing other tokens.
  8341. *
  8342. * @return bool
  8343. */
  8344. public function isLast()
  8345. {
  8346. return true;
  8347. }
  8348. /**
  8349. * Returns string representation for token.
  8350. *
  8351. * @return string
  8352. */
  8353. public function __toString()
  8354. {
  8355. return '* [, ...]';
  8356. }
  8357. }
  8358. <?php
  8359. /*
  8360. * This file is part of the Prophecy.
  8361. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8362. * Marcello Duarte <marcello.duarte@gmail.com>
  8363. *
  8364. * For the full copyright and license information, please view the LICENSE
  8365. * file that was distributed with this source code.
  8366. */
  8367. namespace Prophecy\Argument\Token;
  8368. /**
  8369. * String contains token.
  8370. *
  8371. * @author Peter Mitchell <pete@peterjmit.com>
  8372. */
  8373. class StringContainsToken implements TokenInterface
  8374. {
  8375. private $value;
  8376. /**
  8377. * Initializes token.
  8378. *
  8379. * @param string $value
  8380. */
  8381. public function __construct($value)
  8382. {
  8383. $this->value = $value;
  8384. }
  8385. public function scoreArgument($argument)
  8386. {
  8387. return strpos($argument, $this->value) !== false ? 6 : false;
  8388. }
  8389. /**
  8390. * Returns preset value against which token checks arguments.
  8391. *
  8392. * @return mixed
  8393. */
  8394. public function getValue()
  8395. {
  8396. return $this->value;
  8397. }
  8398. /**
  8399. * Returns false.
  8400. *
  8401. * @return bool
  8402. */
  8403. public function isLast()
  8404. {
  8405. return false;
  8406. }
  8407. /**
  8408. * Returns string representation for token.
  8409. *
  8410. * @return string
  8411. */
  8412. public function __toString()
  8413. {
  8414. return sprintf('contains("%s")', $this->value);
  8415. }
  8416. }
  8417. <?php
  8418. /*
  8419. * This file is part of the Prophecy.
  8420. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8421. * Marcello Duarte <marcello.duarte@gmail.com>
  8422. *
  8423. * For the full copyright and license information, please view the LICENSE
  8424. * file that was distributed with this source code.
  8425. */
  8426. namespace Prophecy\Argument\Token;
  8427. use SebastianBergmann\Comparator\ComparisonFailure;
  8428. use Prophecy\Comparator\Factory as ComparatorFactory;
  8429. use Prophecy\Util\StringUtil;
  8430. /**
  8431. * Exact value token.
  8432. *
  8433. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8434. */
  8435. class ExactValueToken implements TokenInterface
  8436. {
  8437. private $value;
  8438. private $string;
  8439. private $util;
  8440. private $comparatorFactory;
  8441. /**
  8442. * Initializes token.
  8443. *
  8444. * @param mixed $value
  8445. * @param StringUtil $util
  8446. * @param ComparatorFactory $comparatorFactory
  8447. */
  8448. public function __construct($value, StringUtil $util = null, ComparatorFactory $comparatorFactory = null)
  8449. {
  8450. $this->value = $value;
  8451. $this->util = $util ?: new StringUtil();
  8452. $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance();
  8453. }
  8454. /**
  8455. * Scores 10 if argument matches preset value.
  8456. *
  8457. * @param $argument
  8458. *
  8459. * @return bool|int
  8460. */
  8461. public function scoreArgument($argument)
  8462. {
  8463. if (is_object($argument) && is_object($this->value)) {
  8464. $comparator = $this->comparatorFactory->getComparatorFor(
  8465. $argument, $this->value
  8466. );
  8467. try {
  8468. $comparator->assertEquals($argument, $this->value);
  8469. return 10;
  8470. } catch (ComparisonFailure $failure) {}
  8471. }
  8472. // If either one is an object it should be castable to a string
  8473. if (is_object($argument) xor is_object($this->value)) {
  8474. if (is_object($argument) && !method_exists($argument, '__toString')) {
  8475. return false;
  8476. }
  8477. if (is_object($this->value) && !method_exists($this->value, '__toString')) {
  8478. return false;
  8479. }
  8480. } elseif (is_numeric($argument) && is_numeric($this->value)) {
  8481. // noop
  8482. } elseif (gettype($argument) !== gettype($this->value)) {
  8483. return false;
  8484. }
  8485. return $argument == $this->value ? 10 : false;
  8486. }
  8487. /**
  8488. * Returns preset value against which token checks arguments.
  8489. *
  8490. * @return mixed
  8491. */
  8492. public function getValue()
  8493. {
  8494. return $this->value;
  8495. }
  8496. /**
  8497. * Returns false.
  8498. *
  8499. * @return bool
  8500. */
  8501. public function isLast()
  8502. {
  8503. return false;
  8504. }
  8505. /**
  8506. * Returns string representation for token.
  8507. *
  8508. * @return string
  8509. */
  8510. public function __toString()
  8511. {
  8512. if (null === $this->string) {
  8513. $this->string = sprintf('exact(%s)', $this->util->stringify($this->value));
  8514. }
  8515. return $this->string;
  8516. }
  8517. }
  8518. <?php
  8519. /*
  8520. * This file is part of the Prophecy.
  8521. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8522. * Marcello Duarte <marcello.duarte@gmail.com>
  8523. *
  8524. * For the full copyright and license information, please view the LICENSE
  8525. * file that was distributed with this source code.
  8526. */
  8527. namespace Prophecy\Argument\Token;
  8528. use SebastianBergmann\Comparator\ComparisonFailure;
  8529. use Prophecy\Comparator\Factory as ComparatorFactory;
  8530. use Prophecy\Util\StringUtil;
  8531. /**
  8532. * Object state-checker token.
  8533. *
  8534. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8535. */
  8536. class ObjectStateToken implements TokenInterface
  8537. {
  8538. private $name;
  8539. private $value;
  8540. private $util;
  8541. private $comparatorFactory;
  8542. /**
  8543. * Initializes token.
  8544. *
  8545. * @param string $methodName
  8546. * @param mixed $value Expected return value
  8547. * @param null|StringUtil $util
  8548. * @param ComparatorFactory $comparatorFactory
  8549. */
  8550. public function __construct(
  8551. $methodName,
  8552. $value,
  8553. StringUtil $util = null,
  8554. ComparatorFactory $comparatorFactory = null
  8555. ) {
  8556. $this->name = $methodName;
  8557. $this->value = $value;
  8558. $this->util = $util ?: new StringUtil;
  8559. $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance();
  8560. }
  8561. /**
  8562. * Scores 8 if argument is an object, which method returns expected value.
  8563. *
  8564. * @param mixed $argument
  8565. *
  8566. * @return bool|int
  8567. */
  8568. public function scoreArgument($argument)
  8569. {
  8570. if (is_object($argument) && method_exists($argument, $this->name)) {
  8571. $actual = call_user_func(array($argument, $this->name));
  8572. $comparator = $this->comparatorFactory->getComparatorFor(
  8573. $actual, $this->value
  8574. );
  8575. try {
  8576. $comparator->assertEquals($actual, $this->value);
  8577. return 8;
  8578. } catch (ComparisonFailure $failure) {
  8579. return false;
  8580. }
  8581. }
  8582. if (is_object($argument) && property_exists($argument, $this->name)) {
  8583. return $argument->{$this->name} === $this->value ? 8 : false;
  8584. }
  8585. return false;
  8586. }
  8587. /**
  8588. * Returns false.
  8589. *
  8590. * @return bool
  8591. */
  8592. public function isLast()
  8593. {
  8594. return false;
  8595. }
  8596. /**
  8597. * Returns string representation for token.
  8598. *
  8599. * @return string
  8600. */
  8601. public function __toString()
  8602. {
  8603. return sprintf('state(%s(), %s)',
  8604. $this->name,
  8605. $this->util->stringify($this->value)
  8606. );
  8607. }
  8608. }
  8609. <?php
  8610. /*
  8611. * This file is part of the Prophecy.
  8612. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8613. * Marcello Duarte <marcello.duarte@gmail.com>
  8614. *
  8615. * For the full copyright and license information, please view the LICENSE
  8616. * file that was distributed with this source code.
  8617. */
  8618. namespace Prophecy\Argument\Token;
  8619. use Prophecy\Exception\InvalidArgumentException;
  8620. /**
  8621. * Callback-verified token.
  8622. *
  8623. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8624. */
  8625. class CallbackToken implements TokenInterface
  8626. {
  8627. private $callback;
  8628. /**
  8629. * Initializes token.
  8630. *
  8631. * @param callable $callback
  8632. *
  8633. * @throws \Prophecy\Exception\InvalidArgumentException
  8634. */
  8635. public function __construct($callback)
  8636. {
  8637. if (!is_callable($callback)) {
  8638. throw new InvalidArgumentException(sprintf(
  8639. 'Callable expected as an argument to CallbackToken, but got %s.',
  8640. gettype($callback)
  8641. ));
  8642. }
  8643. $this->callback = $callback;
  8644. }
  8645. /**
  8646. * Scores 7 if callback returns true, false otherwise.
  8647. *
  8648. * @param $argument
  8649. *
  8650. * @return bool|int
  8651. */
  8652. public function scoreArgument($argument)
  8653. {
  8654. return call_user_func($this->callback, $argument) ? 7 : false;
  8655. }
  8656. /**
  8657. * Returns false.
  8658. *
  8659. * @return bool
  8660. */
  8661. public function isLast()
  8662. {
  8663. return false;
  8664. }
  8665. /**
  8666. * Returns string representation for token.
  8667. *
  8668. * @return string
  8669. */
  8670. public function __toString()
  8671. {
  8672. return 'callback()';
  8673. }
  8674. }
  8675. <?php
  8676. /*
  8677. * This file is part of the Prophecy.
  8678. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8679. * Marcello Duarte <marcello.duarte@gmail.com>
  8680. *
  8681. * For the full copyright and license information, please view the LICENSE
  8682. * file that was distributed with this source code.
  8683. */
  8684. namespace Prophecy\Argument\Token;
  8685. use Prophecy\Util\StringUtil;
  8686. /**
  8687. * Identical value token.
  8688. *
  8689. * @author Florian Voutzinos <florian@voutzinos.com>
  8690. */
  8691. class IdenticalValueToken implements TokenInterface
  8692. {
  8693. private $value;
  8694. private $string;
  8695. private $util;
  8696. /**
  8697. * Initializes token.
  8698. *
  8699. * @param mixed $value
  8700. * @param StringUtil $util
  8701. */
  8702. public function __construct($value, StringUtil $util = null)
  8703. {
  8704. $this->value = $value;
  8705. $this->util = $util ?: new StringUtil();
  8706. }
  8707. /**
  8708. * Scores 11 if argument matches preset value.
  8709. *
  8710. * @param $argument
  8711. *
  8712. * @return bool|int
  8713. */
  8714. public function scoreArgument($argument)
  8715. {
  8716. return $argument === $this->value ? 11 : false;
  8717. }
  8718. /**
  8719. * Returns false.
  8720. *
  8721. * @return bool
  8722. */
  8723. public function isLast()
  8724. {
  8725. return false;
  8726. }
  8727. /**
  8728. * Returns string representation for token.
  8729. *
  8730. * @return string
  8731. */
  8732. public function __toString()
  8733. {
  8734. if (null === $this->string) {
  8735. $this->string = sprintf('identical(%s)', $this->util->stringify($this->value));
  8736. }
  8737. return $this->string;
  8738. }
  8739. }
  8740. <?php
  8741. /*
  8742. * This file is part of the Prophecy.
  8743. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8744. * Marcello Duarte <marcello.duarte@gmail.com>
  8745. *
  8746. * For the full copyright and license information, please view the LICENSE
  8747. * file that was distributed with this source code.
  8748. */
  8749. namespace Prophecy\Argument\Token;
  8750. /**
  8751. * Logical NOT token.
  8752. *
  8753. * @author Boris Mikhaylov <kaguxmail@gmail.com>
  8754. */
  8755. class LogicalNotToken implements TokenInterface
  8756. {
  8757. /** @var \Prophecy\Argument\Token\TokenInterface */
  8758. private $token;
  8759. /**
  8760. * @param mixed $value exact value or token
  8761. */
  8762. public function __construct($value)
  8763. {
  8764. $this->token = $value instanceof TokenInterface? $value : new ExactValueToken($value);
  8765. }
  8766. /**
  8767. * Scores 4 when preset token does not match the argument.
  8768. *
  8769. * @param $argument
  8770. *
  8771. * @return bool|int
  8772. */
  8773. public function scoreArgument($argument)
  8774. {
  8775. return false === $this->token->scoreArgument($argument) ? 4 : false;
  8776. }
  8777. /**
  8778. * Returns true if preset token is last.
  8779. *
  8780. * @return bool|int
  8781. */
  8782. public function isLast()
  8783. {
  8784. return $this->token->isLast();
  8785. }
  8786. /**
  8787. * Returns originating token.
  8788. *
  8789. * @return TokenInterface
  8790. */
  8791. public function getOriginatingToken()
  8792. {
  8793. return $this->token;
  8794. }
  8795. /**
  8796. * Returns string representation for token.
  8797. *
  8798. * @return string
  8799. */
  8800. public function __toString()
  8801. {
  8802. return sprintf('not(%s)', $this->token);
  8803. }
  8804. }
  8805. <?php
  8806. /*
  8807. * This file is part of the Prophecy.
  8808. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8809. * Marcello Duarte <marcello.duarte@gmail.com>
  8810. *
  8811. * For the full copyright and license information, please view the LICENSE
  8812. * file that was distributed with this source code.
  8813. */
  8814. namespace Prophecy\Argument\Token;
  8815. use Prophecy\Exception\InvalidArgumentException;
  8816. /**
  8817. * Value type token.
  8818. *
  8819. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8820. */
  8821. class TypeToken implements TokenInterface
  8822. {
  8823. private $type;
  8824. /**
  8825. * @param string $type
  8826. */
  8827. public function __construct($type)
  8828. {
  8829. $checker = "is_{$type}";
  8830. if (!function_exists($checker) && !interface_exists($type) && !class_exists($type)) {
  8831. throw new InvalidArgumentException(sprintf(
  8832. 'Type or class name expected as an argument to TypeToken, but got %s.', $type
  8833. ));
  8834. }
  8835. $this->type = $type;
  8836. }
  8837. /**
  8838. * Scores 5 if argument has the same type this token was constructed with.
  8839. *
  8840. * @param $argument
  8841. *
  8842. * @return bool|int
  8843. */
  8844. public function scoreArgument($argument)
  8845. {
  8846. $checker = "is_{$this->type}";
  8847. if (function_exists($checker)) {
  8848. return call_user_func($checker, $argument) ? 5 : false;
  8849. }
  8850. return $argument instanceof $this->type ? 5 : false;
  8851. }
  8852. /**
  8853. * Returns false.
  8854. *
  8855. * @return bool
  8856. */
  8857. public function isLast()
  8858. {
  8859. return false;
  8860. }
  8861. /**
  8862. * Returns string representation for token.
  8863. *
  8864. * @return string
  8865. */
  8866. public function __toString()
  8867. {
  8868. return sprintf('type(%s)', $this->type);
  8869. }
  8870. }
  8871. <?php
  8872. namespace Prophecy\Util;
  8873. use Prophecy\Prophecy\ProphecyInterface;
  8874. use SplObjectStorage;
  8875. /*
  8876. * This file is part of the Prophecy.
  8877. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8878. * Marcello Duarte <marcello.duarte@gmail.com>
  8879. *
  8880. * For the full copyright and license information, please view the LICENSE
  8881. * file that was distributed with this source code.
  8882. */
  8883. /**
  8884. * Exporting utility.
  8885. *
  8886. * This class is derived from the PHPUnit testing framework.
  8887. *
  8888. * @author Sebastiaan Stok <s.stok@rollerscapes.net
  8889. * @author Sebastian Bergmann <sebastian@phpunit.de>
  8890. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License>
  8891. */
  8892. class ExportUtil
  8893. {
  8894. /**
  8895. * Exports a value into a string.
  8896. *
  8897. * The output of this method is similar to the output of print_r(), but
  8898. * improved in various aspects:
  8899. *
  8900. * - NULL is rendered as "null" (instead of "")
  8901. * - true is rendered as "true" (instead of "1")
  8902. * - FALSE is rendered as "false" (instead of "")
  8903. * - Strings are always quoted with single quotes
  8904. * - Carriage returns and newlines are normalized to \n
  8905. * - Recursion and repeated rendering is treated properly
  8906. *
  8907. * @param mixed $value The value to export
  8908. * @param integer $indentation The indentation level of the 2nd+ line
  8909. *
  8910. * @return string
  8911. */
  8912. public static function export($value, $indentation = 0)
  8913. {
  8914. return static::recursiveExport($value, $indentation);
  8915. }
  8916. /**
  8917. * Converts an object to an array containing all of its private, protected
  8918. * and public properties.
  8919. *
  8920. * @param object $object
  8921. *
  8922. * @return array
  8923. */
  8924. public static function toArray($object)
  8925. {
  8926. $array = array();
  8927. foreach ((array) $object as $key => $value) {
  8928. // properties are transformed to keys in the following way:
  8929. // private $property => "\0Classname\0property"
  8930. // protected $property => "\0*\0property"
  8931. // public $property => "property"
  8932. if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) {
  8933. $key = $matches[1];
  8934. }
  8935. $array[$key] = $value;
  8936. }
  8937. // Some internal classes like SplObjectStorage don't work with the
  8938. // above (fast) mechanism nor with reflection
  8939. // Format the output similarly to print_r() in this case
  8940. if ($object instanceof SplObjectStorage) {
  8941. foreach ($object as $key => $value) {
  8942. $array[spl_object_hash($value)] = array(
  8943. 'obj' => $value,
  8944. 'inf' => $object->getInfo(),
  8945. );
  8946. }
  8947. }
  8948. return $array;
  8949. }
  8950. /**
  8951. * Recursive implementation of export.
  8952. *
  8953. * @param mixed $value The value to export
  8954. * @param integer $indentation The indentation level of the 2nd+ line
  8955. * @param array $processedObjects Contains all objects that were already
  8956. * rendered
  8957. *
  8958. * @return string
  8959. */
  8960. protected static function recursiveExport($value, $indentation, &$processedObjects = array())
  8961. {
  8962. if ($value === null) {
  8963. return 'null';
  8964. }
  8965. if ($value === true) {
  8966. return 'true';
  8967. }
  8968. if ($value === false) {
  8969. return 'false';
  8970. }
  8971. if (is_string($value)) {
  8972. // Match for most non printable chars somewhat taking multibyte chars into account
  8973. if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) {
  8974. return 'Binary String: 0x' . bin2hex($value);
  8975. }
  8976. return "'" . str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) . "'";
  8977. }
  8978. $origValue = $value;
  8979. if (is_object($value)) {
  8980. if ($value instanceof ProphecyInterface) {
  8981. return sprintf('%s Object (*Prophecy*)', get_class($value));
  8982. } elseif (in_array($value, $processedObjects, true)) {
  8983. return sprintf('%s Object (*RECURSION*)', get_class($value));
  8984. }
  8985. $processedObjects[] = $value;
  8986. // Convert object to array
  8987. $value = self::toArray($value);
  8988. }
  8989. if (is_array($value)) {
  8990. $whitespace = str_repeat(' ', $indentation);
  8991. // There seems to be no other way to check arrays for recursion
  8992. // http://www.php.net/manual/en/language.types.array.php#73936
  8993. preg_match_all('/\n \[(\w+)\] => Array\s+\*RECURSION\*/', print_r($value, true), $matches);
  8994. $recursiveKeys = array_unique($matches[1]);
  8995. // Convert to valid array keys
  8996. // Numeric integer strings are automatically converted to integers
  8997. // by PHP
  8998. foreach ($recursiveKeys as $key => $recursiveKey) {
  8999. if ((string) (integer) $recursiveKey === $recursiveKey) {
  9000. $recursiveKeys[$key] = (integer) $recursiveKey;
  9001. }
  9002. }
  9003. $content = '';
  9004. foreach ($value as $key => $val) {
  9005. if (in_array($key, $recursiveKeys, true)) {
  9006. $val = 'Array (*RECURSION*)';
  9007. } else {
  9008. $val = self::recursiveExport($val, $indentation + 1, $processedObjects);
  9009. }
  9010. $content .= $whitespace . ' ' . self::export($key) . ' => ' . $val . "\n";
  9011. }
  9012. if (strlen($content) > 0) {
  9013. $content = "\n" . $content . $whitespace;
  9014. }
  9015. return sprintf(
  9016. "%s (%s)",
  9017. is_object($origValue) ? sprintf('%s:%s', get_class($origValue), spl_object_hash($origValue)) . ' Object' : 'Array', $content
  9018. );
  9019. }
  9020. if (is_double($value) && (double)(integer) $value === $value) {
  9021. return $value . '.0';
  9022. }
  9023. return (string) $value;
  9024. }
  9025. }
  9026. <?php
  9027. /*
  9028. * This file is part of the Prophecy.
  9029. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  9030. * Marcello Duarte <marcello.duarte@gmail.com>
  9031. *
  9032. * For the full copyright and license information, please view the LICENSE
  9033. * file that was distributed with this source code.
  9034. */
  9035. namespace Prophecy\Util;
  9036. use Prophecy\Call\Call;
  9037. /**
  9038. * String utility.
  9039. *
  9040. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  9041. */
  9042. class StringUtil
  9043. {
  9044. /**
  9045. * Stringifies any provided value.
  9046. *
  9047. * @param mixed $value
  9048. * @param boolean $exportObject
  9049. *
  9050. * @return string
  9051. */
  9052. public function stringify($value, $exportObject = true)
  9053. {
  9054. if (is_array($value)) {
  9055. if (range(0, count($value) - 1) === array_keys($value)) {
  9056. return '['.implode(', ', array_map(array($this, __FUNCTION__), $value)).']';
  9057. }
  9058. $stringify = array($this, __FUNCTION__);
  9059. return '['.implode(', ', array_map(function ($item, $key) use ($stringify) {
  9060. return (is_integer($key) ? $key : '"'.$key.'"').
  9061. ' => '.call_user_func($stringify, $item);
  9062. }, $value, array_keys($value))).']';
  9063. }
  9064. if (is_resource($value)) {
  9065. return get_resource_type($value).':'.$value;
  9066. }
  9067. if (is_object($value)) {
  9068. return $exportObject ? ExportUtil::export($value) : sprintf('%s:%s', get_class($value), spl_object_hash($value));
  9069. }
  9070. if (true === $value || false === $value) {
  9071. return $value ? 'true' : 'false';
  9072. }
  9073. if (is_string($value)) {
  9074. $str = sprintf('"%s"', str_replace("\n", '\\n', $value));
  9075. if (50 <= strlen($str)) {
  9076. return substr($str, 0, 50).'"...';
  9077. }
  9078. return $str;
  9079. }
  9080. if (null === $value) {
  9081. return 'null';
  9082. }
  9083. return (string) $value;
  9084. }
  9085. /**
  9086. * Stringifies provided array of calls.
  9087. *
  9088. * @param Call[] $calls Array of Call instances
  9089. *
  9090. * @return string
  9091. */
  9092. public function stringifyCalls(array $calls)
  9093. {
  9094. $self = $this;
  9095. return implode(PHP_EOL, array_map(function (Call $call) use ($self) {
  9096. return sprintf(' - %s(%s) @ %s',
  9097. $call->getMethodName(),
  9098. implode(', ', array_map(array($self, 'stringify'), $call->getArguments())),
  9099. str_replace(GETCWD().DIRECTORY_SEPARATOR, '', $call->getCallPlace())
  9100. );
  9101. }, $calls));
  9102. }
  9103. }
  9104. Exporter
  9105. Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  9106. All rights reserved.
  9107. Redistribution and use in source and binary forms, with or without
  9108. modification, are permitted provided that the following conditions
  9109. are met:
  9110. * Redistributions of source code must retain the above copyright
  9111. notice, this list of conditions and the following disclaimer.
  9112. * Redistributions in binary form must reproduce the above copyright
  9113. notice, this list of conditions and the following disclaimer in
  9114. the documentation and/or other materials provided with the
  9115. distribution.
  9116. * Neither the name of Sebastian Bergmann nor the names of his
  9117. contributors may be used to endorse or promote products derived
  9118. from this software without specific prior written permission.
  9119. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  9120. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  9121. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  9122. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  9123. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  9124. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  9125. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  9126. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  9127. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  9128. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  9129. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  9130. POSSIBILITY OF SUCH DAMAGE.
  9131. <?php
  9132. /*
  9133. * This file is part of the Exporter package.
  9134. *
  9135. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9136. *
  9137. * For the full copyright and license information, please view the LICENSE
  9138. * file that was distributed with this source code.
  9139. */
  9140. namespace SebastianBergmann\Exporter;
  9141. use SebastianBergmann\RecursionContext\Context;
  9142. /**
  9143. * A nifty utility for visualizing PHP variables.
  9144. *
  9145. * <code>
  9146. * <?php
  9147. * use SebastianBergmann\Exporter\Exporter;
  9148. *
  9149. * $exporter = new Exporter;
  9150. * print $exporter->export(new Exception);
  9151. * </code>
  9152. *
  9153. * @package Exporter
  9154. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9155. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9156. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9157. * @link https://github.com/sebastianbergmann/exporter
  9158. */
  9159. class Exporter
  9160. {
  9161. /**
  9162. * Exports a value as a string
  9163. *
  9164. * The output of this method is similar to the output of print_r(), but
  9165. * improved in various aspects:
  9166. *
  9167. * - NULL is rendered as "null" (instead of "")
  9168. * - TRUE is rendered as "true" (instead of "1")
  9169. * - FALSE is rendered as "false" (instead of "")
  9170. * - Strings are always quoted with single quotes
  9171. * - Carriage returns and newlines are normalized to \n
  9172. * - Recursion and repeated rendering is treated properly
  9173. *
  9174. * @param mixed $value
  9175. * @param integer $indentation The indentation level of the 2nd+ line
  9176. * @return string
  9177. */
  9178. public function export($value, $indentation = 0)
  9179. {
  9180. return $this->recursiveExport($value, $indentation);
  9181. }
  9182. /**
  9183. * @param mixed $data
  9184. * @param Context $context
  9185. * @return string
  9186. */
  9187. public function shortenedRecursiveExport(&$data, Context $context = null)
  9188. {
  9189. $result = array();
  9190. $exporter = new Exporter();
  9191. if (!$context) {
  9192. $context = new Context;
  9193. }
  9194. $context->add($data);
  9195. foreach ($data as $key => $value) {
  9196. if (is_array($value)) {
  9197. if ($context->contains($data[$key]) !== false) {
  9198. $result[] = '*RECURSION*';
  9199. }
  9200. else {
  9201. $result[] = sprintf(
  9202. 'array(%s)',
  9203. $this->shortenedRecursiveExport($data[$key], $context)
  9204. );
  9205. }
  9206. }
  9207. else {
  9208. $result[] = $exporter->shortenedExport($value);
  9209. }
  9210. }
  9211. return join(', ', $result);
  9212. }
  9213. /**
  9214. * Exports a value into a single-line string
  9215. *
  9216. * The output of this method is similar to the output of
  9217. * SebastianBergmann\Exporter\Exporter::export. This method guarantees
  9218. * thought that the result contains now newlines.
  9219. *
  9220. * Newlines are replaced by the visible string '\n'. Contents of arrays
  9221. * and objects (if any) are replaced by '...'.
  9222. *
  9223. * @param mixed $value
  9224. * @return string
  9225. * @see SebastianBergmann\Exporter\Exporter::export
  9226. */
  9227. public function shortenedExport($value)
  9228. {
  9229. if (is_string($value)) {
  9230. $string = $this->export($value);
  9231. if (strlen($string) > 40) {
  9232. $string = substr($string, 0, 30) . '...' . substr($string, -7);
  9233. }
  9234. return str_replace("\n", '\n', $string);
  9235. }
  9236. if (is_object($value)) {
  9237. return sprintf(
  9238. '%s Object (%s)',
  9239. get_class($value),
  9240. count($this->toArray($value)) > 0 ? '...' : ''
  9241. );
  9242. }
  9243. if (is_array($value)) {
  9244. return sprintf(
  9245. 'Array (%s)',
  9246. count($value) > 0 ? '...' : ''
  9247. );
  9248. }
  9249. return $this->export($value);
  9250. }
  9251. /**
  9252. * Converts an object to an array containing all of its private, protected
  9253. * and public properties.
  9254. *
  9255. * @param mixed $value
  9256. * @return array
  9257. */
  9258. public function toArray($value)
  9259. {
  9260. if (!is_object($value)) {
  9261. return (array)$value;
  9262. }
  9263. $array = array();
  9264. foreach ((array)$value as $key => $val) {
  9265. // properties are transformed to keys in the following way:
  9266. // private $property => "\0Classname\0property"
  9267. // protected $property => "\0*\0property"
  9268. // public $property => "property"
  9269. if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) {
  9270. $key = $matches[1];
  9271. }
  9272. // See https://github.com/php/php-src/commit/5721132
  9273. if ($key === "\0gcdata") {
  9274. continue;
  9275. }
  9276. $array[$key] = $val;
  9277. }
  9278. // Some internal classes like SplObjectStorage don't work with the
  9279. // above (fast) mechanism nor with reflection in Zend.
  9280. // Format the output similarly to print_r() in this case
  9281. if ($value instanceof \SplObjectStorage) {
  9282. // However, the fast method does work in HHVM, and exposes the
  9283. // internal implementation. Hide it again.
  9284. if (property_exists('\SplObjectStorage', '__storage')) {
  9285. unset($array['__storage']);
  9286. } elseif (property_exists('\SplObjectStorage', 'storage')) {
  9287. unset($array['storage']);
  9288. }
  9289. if (property_exists('\SplObjectStorage', '__key')) {
  9290. unset($array['__key']);
  9291. }
  9292. foreach ($value as $key => $val) {
  9293. $array[spl_object_hash($val)] = array(
  9294. 'obj' => $val,
  9295. 'inf' => $value->getInfo(),
  9296. );
  9297. }
  9298. }
  9299. return $array;
  9300. }
  9301. /**
  9302. * Recursive implementation of export
  9303. *
  9304. * @param mixed $value The value to export
  9305. * @param integer $indentation The indentation level of the 2nd+ line
  9306. * @param \SebastianBergmann\RecursionContext\Context $processed Previously processed objects
  9307. * @return string
  9308. * @see SebastianBergmann\Exporter\Exporter::export
  9309. */
  9310. protected function recursiveExport(&$value, $indentation, $processed = null)
  9311. {
  9312. if ($value === null) {
  9313. return 'null';
  9314. }
  9315. if ($value === true) {
  9316. return 'true';
  9317. }
  9318. if ($value === false) {
  9319. return 'false';
  9320. }
  9321. if (is_float($value) && floatval(intval($value)) === $value) {
  9322. return "$value.0";
  9323. }
  9324. if (is_resource($value)) {
  9325. return sprintf(
  9326. 'resource(%d) of type (%s)',
  9327. $value,
  9328. get_resource_type($value)
  9329. );
  9330. }
  9331. if (is_string($value)) {
  9332. // Match for most non printable chars somewhat taking multibyte chars into account
  9333. if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) {
  9334. return 'Binary String: 0x' . bin2hex($value);
  9335. }
  9336. return "'" .
  9337. str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) .
  9338. "'";
  9339. }
  9340. $whitespace = str_repeat(' ', 4 * $indentation);
  9341. if (!$processed) {
  9342. $processed = new Context;
  9343. }
  9344. if (is_array($value)) {
  9345. if (($key = $processed->contains($value)) !== false) {
  9346. return 'Array &' . $key;
  9347. }
  9348. $key = $processed->add($value);
  9349. $values = '';
  9350. if (count($value) > 0) {
  9351. foreach ($value as $k => $v) {
  9352. $values .= sprintf(
  9353. '%s %s => %s' . "\n",
  9354. $whitespace,
  9355. $this->recursiveExport($k, $indentation),
  9356. $this->recursiveExport($value[$k], $indentation + 1, $processed)
  9357. );
  9358. }
  9359. $values = "\n" . $values . $whitespace;
  9360. }
  9361. return sprintf('Array &%s (%s)', $key, $values);
  9362. }
  9363. if (is_object($value)) {
  9364. $class = get_class($value);
  9365. if ($hash = $processed->contains($value)) {
  9366. return sprintf('%s Object &%s', $class, $hash);
  9367. }
  9368. $hash = $processed->add($value);
  9369. $values = '';
  9370. $array = $this->toArray($value);
  9371. if (count($array) > 0) {
  9372. foreach ($array as $k => $v) {
  9373. $values .= sprintf(
  9374. '%s %s => %s' . "\n",
  9375. $whitespace,
  9376. $this->recursiveExport($k, $indentation),
  9377. $this->recursiveExport($v, $indentation + 1, $processed)
  9378. );
  9379. }
  9380. $values = "\n" . $values . $whitespace;
  9381. }
  9382. return sprintf('%s Object &%s (%s)', $class, $hash, $values);
  9383. }
  9384. return var_export($value, true);
  9385. }
  9386. }
  9387. File_Iterator
  9388. Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  9389. All rights reserved.
  9390. Redistribution and use in source and binary forms, with or without
  9391. modification, are permitted provided that the following conditions
  9392. are met:
  9393. * Redistributions of source code must retain the above copyright
  9394. notice, this list of conditions and the following disclaimer.
  9395. * Redistributions in binary form must reproduce the above copyright
  9396. notice, this list of conditions and the following disclaimer in
  9397. the documentation and/or other materials provided with the
  9398. distribution.
  9399. * Neither the name of Sebastian Bergmann nor the names of his
  9400. contributors may be used to endorse or promote products derived
  9401. from this software without specific prior written permission.
  9402. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  9403. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  9404. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  9405. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  9406. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  9407. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  9408. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  9409. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  9410. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  9411. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  9412. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  9413. POSSIBILITY OF SUCH DAMAGE.
  9414. <?php
  9415. /*
  9416. * This file is part of the File_Iterator package.
  9417. *
  9418. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9419. *
  9420. * For the full copyright and license information, please view the LICENSE
  9421. * file that was distributed with this source code.
  9422. */
  9423. /**
  9424. * FilterIterator implementation that filters files based on prefix(es) and/or
  9425. * suffix(es). Hidden files and files from hidden directories are also filtered.
  9426. *
  9427. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9428. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9429. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9430. * @version Release: @package_version@
  9431. * @link http://github.com/sebastianbergmann/php-file-iterator/tree
  9432. * @since Class available since Release 1.0.0
  9433. */
  9434. class File_Iterator extends FilterIterator
  9435. {
  9436. const PREFIX = 0;
  9437. const SUFFIX = 1;
  9438. /**
  9439. * @var array
  9440. */
  9441. protected $suffixes = array();
  9442. /**
  9443. * @var array
  9444. */
  9445. protected $prefixes = array();
  9446. /**
  9447. * @var array
  9448. */
  9449. protected $exclude = array();
  9450. /**
  9451. * @var string
  9452. */
  9453. protected $basepath;
  9454. /**
  9455. * @param Iterator $iterator
  9456. * @param array $suffixes
  9457. * @param array $prefixes
  9458. * @param array $exclude
  9459. * @param string $basepath
  9460. */
  9461. public function __construct(Iterator $iterator, array $suffixes = array(), array $prefixes = array(), array $exclude = array(), $basepath = NULL)
  9462. {
  9463. $exclude = array_filter(array_map('realpath', $exclude));
  9464. if ($basepath !== NULL) {
  9465. $basepath = realpath($basepath);
  9466. }
  9467. if ($basepath === FALSE) {
  9468. $basepath = NULL;
  9469. } else {
  9470. foreach ($exclude as &$_exclude) {
  9471. $_exclude = str_replace($basepath, '', $_exclude);
  9472. }
  9473. }
  9474. $this->prefixes = $prefixes;
  9475. $this->suffixes = $suffixes;
  9476. $this->exclude = $exclude;
  9477. $this->basepath = $basepath;
  9478. parent::__construct($iterator);
  9479. }
  9480. /**
  9481. * @return boolean
  9482. */
  9483. public function accept()
  9484. {
  9485. $current = $this->getInnerIterator()->current();
  9486. $filename = $current->getFilename();
  9487. $realpath = $current->getRealPath();
  9488. if ($this->basepath !== NULL) {
  9489. $realpath = str_replace($this->basepath, '', $realpath);
  9490. }
  9491. // Filter files in hidden directories.
  9492. if (preg_match('=/\.[^/]*/=', $realpath)) {
  9493. return FALSE;
  9494. }
  9495. return $this->acceptPath($realpath) &&
  9496. $this->acceptPrefix($filename) &&
  9497. $this->acceptSuffix($filename);
  9498. }
  9499. /**
  9500. * @param string $path
  9501. * @return boolean
  9502. * @since Method available since Release 1.1.0
  9503. */
  9504. protected function acceptPath($path)
  9505. {
  9506. foreach ($this->exclude as $exclude) {
  9507. if (strpos($path, $exclude) === 0) {
  9508. return FALSE;
  9509. }
  9510. }
  9511. return TRUE;
  9512. }
  9513. /**
  9514. * @param string $filename
  9515. * @return boolean
  9516. * @since Method available since Release 1.1.0
  9517. */
  9518. protected function acceptPrefix($filename)
  9519. {
  9520. return $this->acceptSubString($filename, $this->prefixes, self::PREFIX);
  9521. }
  9522. /**
  9523. * @param string $filename
  9524. * @return boolean
  9525. * @since Method available since Release 1.1.0
  9526. */
  9527. protected function acceptSuffix($filename)
  9528. {
  9529. return $this->acceptSubString($filename, $this->suffixes, self::SUFFIX);
  9530. }
  9531. /**
  9532. * @param string $filename
  9533. * @param array $subString
  9534. * @param integer $type
  9535. * @return boolean
  9536. * @since Method available since Release 1.1.0
  9537. */
  9538. protected function acceptSubString($filename, array $subStrings, $type)
  9539. {
  9540. if (empty($subStrings)) {
  9541. return TRUE;
  9542. }
  9543. $matched = FALSE;
  9544. foreach ($subStrings as $string) {
  9545. if (($type == self::PREFIX && strpos($filename, $string) === 0) ||
  9546. ($type == self::SUFFIX &&
  9547. substr($filename, -1 * strlen($string)) == $string)) {
  9548. $matched = TRUE;
  9549. break;
  9550. }
  9551. }
  9552. return $matched;
  9553. }
  9554. }
  9555. <?php
  9556. /*
  9557. * This file is part of the File_Iterator package.
  9558. *
  9559. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9560. *
  9561. * For the full copyright and license information, please view the LICENSE
  9562. * file that was distributed with this source code.
  9563. */
  9564. /**
  9565. * Façade implementation that uses File_Iterator_Factory to create a
  9566. * File_Iterator that operates on an AppendIterator that contains an
  9567. * RecursiveDirectoryIterator for each given path. The list of unique
  9568. * files is returned as an array.
  9569. *
  9570. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9571. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9572. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9573. * @version Release: @package_version@
  9574. * @link http://github.com/sebastianbergmann/php-file-iterator/tree
  9575. * @since Class available since Release 1.3.0
  9576. */
  9577. class File_Iterator_Facade
  9578. {
  9579. /**
  9580. * @param array|string $paths
  9581. * @param array|string $suffixes
  9582. * @param array|string $prefixes
  9583. * @param array $exclude
  9584. * @param boolean $commonPath
  9585. * @return array
  9586. */
  9587. public function getFilesAsArray($paths, $suffixes = '', $prefixes = '', array $exclude = array(), $commonPath = FALSE)
  9588. {
  9589. if (is_string($paths)) {
  9590. $paths = array($paths);
  9591. }
  9592. $factory = new File_Iterator_Factory;
  9593. $iterator = $factory->getFileIterator(
  9594. $paths, $suffixes, $prefixes, $exclude
  9595. );
  9596. $files = array();
  9597. foreach ($iterator as $file) {
  9598. $file = $file->getRealPath();
  9599. if ($file) {
  9600. $files[] = $file;
  9601. }
  9602. }
  9603. foreach ($paths as $path) {
  9604. if (is_file($path)) {
  9605. $files[] = realpath($path);
  9606. }
  9607. }
  9608. $files = array_unique($files);
  9609. sort($files);
  9610. if ($commonPath) {
  9611. return array(
  9612. 'commonPath' => $this->getCommonPath($files),
  9613. 'files' => $files
  9614. );
  9615. } else {
  9616. return $files;
  9617. }
  9618. }
  9619. /**
  9620. * Returns the common path of a set of files.
  9621. *
  9622. * @param array $files
  9623. * @return string
  9624. */
  9625. protected function getCommonPath(array $files)
  9626. {
  9627. $count = count($files);
  9628. if ($count == 0) {
  9629. return '';
  9630. }
  9631. if ($count == 1) {
  9632. return dirname($files[0]) . DIRECTORY_SEPARATOR;
  9633. }
  9634. $_files = array();
  9635. foreach ($files as $file) {
  9636. $_files[] = $_fileParts = explode(DIRECTORY_SEPARATOR, $file);
  9637. if (empty($_fileParts[0])) {
  9638. $_fileParts[0] = DIRECTORY_SEPARATOR;
  9639. }
  9640. }
  9641. $common = '';
  9642. $done = FALSE;
  9643. $j = 0;
  9644. $count--;
  9645. while (!$done) {
  9646. for ($i = 0; $i < $count; $i++) {
  9647. if ($_files[$i][$j] != $_files[$i+1][$j]) {
  9648. $done = TRUE;
  9649. break;
  9650. }
  9651. }
  9652. if (!$done) {
  9653. $common .= $_files[0][$j];
  9654. if ($j > 0) {
  9655. $common .= DIRECTORY_SEPARATOR;
  9656. }
  9657. }
  9658. $j++;
  9659. }
  9660. return DIRECTORY_SEPARATOR . $common;
  9661. }
  9662. }
  9663. <?php
  9664. /*
  9665. * This file is part of the File_Iterator package.
  9666. *
  9667. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9668. *
  9669. * For the full copyright and license information, please view the LICENSE
  9670. * file that was distributed with this source code.
  9671. */
  9672. /**
  9673. * Factory Method implementation that creates a File_Iterator that operates on
  9674. * an AppendIterator that contains an RecursiveDirectoryIterator for each given
  9675. * path.
  9676. *
  9677. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9678. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9679. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9680. * @version Release: @package_version@
  9681. * @link http://github.com/sebastianbergmann/php-file-iterator/tree
  9682. * @since Class available since Release 1.1.0
  9683. */
  9684. class File_Iterator_Factory
  9685. {
  9686. /**
  9687. * @param array|string $paths
  9688. * @param array|string $suffixes
  9689. * @param array|string $prefixes
  9690. * @param array $exclude
  9691. * @return AppendIterator
  9692. */
  9693. public function getFileIterator($paths, $suffixes = '', $prefixes = '', array $exclude = array())
  9694. {
  9695. if (is_string($paths)) {
  9696. $paths = array($paths);
  9697. }
  9698. $paths = $this->getPathsAfterResolvingWildcards($paths);
  9699. $exclude = $this->getPathsAfterResolvingWildcards($exclude);
  9700. if (is_string($prefixes)) {
  9701. if ($prefixes != '') {
  9702. $prefixes = array($prefixes);
  9703. } else {
  9704. $prefixes = array();
  9705. }
  9706. }
  9707. if (is_string($suffixes)) {
  9708. if ($suffixes != '') {
  9709. $suffixes = array($suffixes);
  9710. } else {
  9711. $suffixes = array();
  9712. }
  9713. }
  9714. $iterator = new AppendIterator;
  9715. foreach ($paths as $path) {
  9716. if (is_dir($path)) {
  9717. $iterator->append(
  9718. new File_Iterator(
  9719. new RecursiveIteratorIterator(
  9720. new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::FOLLOW_SYMLINKS)
  9721. ),
  9722. $suffixes,
  9723. $prefixes,
  9724. $exclude,
  9725. $path
  9726. )
  9727. );
  9728. }
  9729. }
  9730. return $iterator;
  9731. }
  9732. /**
  9733. * @param array $paths
  9734. * @return array
  9735. */
  9736. protected function getPathsAfterResolvingWildcards(array $paths)
  9737. {
  9738. $_paths = array();
  9739. foreach ($paths as $path) {
  9740. if ($locals = glob($path, GLOB_ONLYDIR)) {
  9741. $_paths = array_merge($_paths, $locals);
  9742. } else {
  9743. $_paths[] = $path;
  9744. }
  9745. }
  9746. return $_paths;
  9747. }
  9748. }
  9749. phpunit/phpunit: 4.7.0
  9750. doctrine/instantiator: 1.0.4
  9751. phpdocumentor/reflection-docblock: 2.0.4
  9752. phpspec/prophecy: v1.4.1
  9753. phpunit/dbunit: 1.3.2
  9754. phpunit/php-code-coverage: 2.1.3
  9755. phpunit/php-file-iterator: 1.4.0
  9756. phpunit/php-invoker: 1.1.3
  9757. phpunit/php-text-template: 1.2.0
  9758. phpunit/php-timer: 1.0.5
  9759. phpunit/php-token-stream: 1.4.1
  9760. phpunit/phpunit-mock-objects: 2.3.3
  9761. phpunit/phpunit-selenium: 1.4.2
  9762. sebastian/comparator: 1.1.1
  9763. sebastian/diff: 1.3.0
  9764. sebastian/environment: 1.2.2
  9765. sebastian/exporter: 1.2.0
  9766. sebastian/global-state: 1.0.0
  9767. sebastian/recursion-context: 1.0.0
  9768. sebastian/version: 1.0.5
  9769. symfony/yaml: v2.7.0
  9770. <?php
  9771. /*
  9772. * This file is part of the Recursion Context package.
  9773. *
  9774. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9775. *
  9776. * For the full copyright and license information, please view the LICENSE
  9777. * file that was distributed with this source code.
  9778. */
  9779. namespace SebastianBergmann\RecursionContext;
  9780. /**
  9781. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9782. * @author Adam Harvey <aharvey@php.net>
  9783. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9784. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9785. * @link https://github.com/sebastianbergmann/recursion-context
  9786. */
  9787. interface Exception
  9788. {
  9789. }
  9790. Recursion Context
  9791. Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  9792. All rights reserved.
  9793. Redistribution and use in source and binary forms, with or without
  9794. modification, are permitted provided that the following conditions
  9795. are met:
  9796. * Redistributions of source code must retain the above copyright
  9797. notice, this list of conditions and the following disclaimer.
  9798. * Redistributions in binary form must reproduce the above copyright
  9799. notice, this list of conditions and the following disclaimer in
  9800. the documentation and/or other materials provided with the
  9801. distribution.
  9802. * Neither the name of Sebastian Bergmann nor the names of his
  9803. contributors may be used to endorse or promote products derived
  9804. from this software without specific prior written permission.
  9805. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  9806. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  9807. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  9808. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  9809. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  9810. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  9811. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  9812. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  9813. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  9814. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  9815. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  9816. POSSIBILITY OF SUCH DAMAGE.
  9817. <?php
  9818. /*
  9819. * This file is part of the Recursion Context package.
  9820. *
  9821. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9822. *
  9823. * For the full copyright and license information, please view the LICENSE
  9824. * file that was distributed with this source code.
  9825. */
  9826. namespace SebastianBergmann\RecursionContext;
  9827. /**
  9828. * A context containing previously processed arrays and objects
  9829. * when recursively processing a value.
  9830. *
  9831. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9832. * @author Adam Harvey <aharvey@php.net>
  9833. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9834. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9835. * @link https://github.com/sebastianbergmann/recursion-context
  9836. */
  9837. final class Context
  9838. {
  9839. /**
  9840. * @var array[]
  9841. */
  9842. private $arrays;
  9843. /**
  9844. * @var \SplObjectStorage
  9845. */
  9846. private $objects;
  9847. /**
  9848. * Initialises the context
  9849. */
  9850. public function __construct()
  9851. {
  9852. $this->arrays = array();
  9853. $this->objects = new \SplObjectStorage;
  9854. }
  9855. /**
  9856. * Adds a value to the context.
  9857. *
  9858. * @param array|object $value The value to add.
  9859. * @return integer|string The ID of the stored value, either as
  9860. * a string or integer.
  9861. * @throws InvalidArgumentException Thrown if $value is not an array or
  9862. * object
  9863. */
  9864. public function add(&$value)
  9865. {
  9866. if (is_array($value)) {
  9867. return $this->addArray($value);
  9868. }
  9869. else if (is_object($value)) {
  9870. return $this->addObject($value);
  9871. }
  9872. throw new InvalidArgumentException(
  9873. 'Only arrays and objects are supported'
  9874. );
  9875. }
  9876. /**
  9877. * Checks if the given value exists within the context.
  9878. *
  9879. * @param array|object $value The value to check.
  9880. * @return integer|string|false The string or integer ID of the stored
  9881. * value if it has already been seen, or
  9882. * false if the value is not stored.
  9883. * @throws InvalidArgumentException Thrown if $value is not an array or
  9884. * object
  9885. */
  9886. public function contains(&$value)
  9887. {
  9888. if (is_array($value)) {
  9889. return $this->containsArray($value);
  9890. }
  9891. else if (is_object($value)) {
  9892. return $this->containsObject($value);
  9893. }
  9894. throw new InvalidArgumentException(
  9895. 'Only arrays and objects are supported'
  9896. );
  9897. }
  9898. /**
  9899. * @param array $array
  9900. * @return bool|int
  9901. */
  9902. private function addArray(array &$array)
  9903. {
  9904. $key = $this->containsArray($array);
  9905. if ($key !== false) {
  9906. return $key;
  9907. }
  9908. $this->arrays[] = &$array;
  9909. return count($this->arrays) - 1;
  9910. }
  9911. /**
  9912. * @param object $object
  9913. * @return string
  9914. */
  9915. private function addObject($object)
  9916. {
  9917. if (!$this->objects->contains($object)) {
  9918. $this->objects->attach($object);
  9919. }
  9920. return spl_object_hash($object);
  9921. }
  9922. /**
  9923. * @param array $array
  9924. * @return integer|false
  9925. */
  9926. private function containsArray(array &$array)
  9927. {
  9928. $keys = array_keys($this->arrays, $array, true);
  9929. $hash = '_Key_' . hash('sha512', microtime(true));
  9930. foreach ($keys as $key) {
  9931. $this->arrays[$key][$hash] = $hash;
  9932. if (isset($array[$hash]) && $array[$hash] === $hash) {
  9933. unset($this->arrays[$key][$hash]);
  9934. return $key;
  9935. }
  9936. unset($this->arrays[$key][$hash]);
  9937. }
  9938. return false;
  9939. }
  9940. /**
  9941. * @param object $value
  9942. * @return string|false
  9943. */
  9944. private function containsObject($value)
  9945. {
  9946. if ($this->objects->contains($value)) {
  9947. return spl_object_hash($value);
  9948. }
  9949. return false;
  9950. }
  9951. }
  9952. <?php
  9953. /*
  9954. * This file is part of the Recursion Context package.
  9955. *
  9956. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9957. *
  9958. * For the full copyright and license information, please view the LICENSE
  9959. * file that was distributed with this source code.
  9960. */
  9961. namespace SebastianBergmann\RecursionContext;
  9962. /**
  9963. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9964. * @author Adam Harvey <aharvey@php.net>
  9965. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9966. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9967. * @link https://github.com/sebastianbergmann/recursion-context
  9968. */
  9969. final class InvalidArgumentException extends \InvalidArgumentException implements Exception
  9970. {
  9971. }
  9972. <?php
  9973. /**
  9974. * PHPUnit
  9975. *
  9976. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  9977. * All rights reserved.
  9978. *
  9979. * Redistribution and use in source and binary forms, with or without
  9980. * modification, are permitted provided that the following conditions
  9981. * are met:
  9982. *
  9983. * * Redistributions of source code must retain the above copyright
  9984. * notice, this list of conditions and the following disclaimer.
  9985. *
  9986. * * Redistributions in binary form must reproduce the above copyright
  9987. * notice, this list of conditions and the following disclaimer in
  9988. * the documentation and/or other materials provided with the
  9989. * distribution.
  9990. *
  9991. * * Neither the name of Sebastian Bergmann nor the names of his
  9992. * contributors may be used to endorse or promote products derived
  9993. * from this software without specific prior written permission.
  9994. *
  9995. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  9996. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  9997. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  9998. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  9999. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  10000. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  10001. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  10002. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  10003. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  10004. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  10005. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  10006. * POSSIBILITY OF SUCH DAMAGE.
  10007. *
  10008. * @package PHPUnit_Selenium
  10009. * @author Sebastian Bergmann <sebastian@phpunit.de>
  10010. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  10011. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  10012. * @link http://www.phpunit.de/
  10013. * @since File available since Release 1.0.0
  10014. */
  10015. /**
  10016. * TestCase class that uses Selenium to provide
  10017. * the functionality required for web testing.
  10018. *
  10019. * @package PHPUnit_Selenium
  10020. * @author Sebastian Bergmann <sebastian@phpunit.de>
  10021. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  10022. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  10023. * @version Release: @package_version@
  10024. * @link http://www.phpunit.de/
  10025. * @since Class available since Release 1.0.0
  10026. *
  10027. * @method unknown addLocationStrategy()
  10028. * @method unknown addLocationStrategyAndWait()
  10029. * @method unknown addScript()
  10030. * @method unknown addScriptAndWait()
  10031. * @method unknown addSelection()
  10032. * @method unknown addSelectionAndWait()
  10033. * @method unknown allowNativeXpath()
  10034. * @method unknown allowNativeXpathAndWait()
  10035. * @method unknown altKeyDown()
  10036. * @method unknown altKeyDownAndWait()
  10037. * @method unknown altKeyUp()
  10038. * @method unknown altKeyUpAndWait()
  10039. * @method unknown answerOnNextPrompt()
  10040. * @method unknown assignId()
  10041. * @method unknown assignIdAndWait()
  10042. * @method unknown assertAlert
  10043. * @method unknown assertAlertNotPresent
  10044. * @method unknown assertAlertPresent
  10045. * @method unknown assertAllButtons
  10046. * @method unknown assertAllFields
  10047. * @method unknown assertAllLinks
  10048. * @method unknown assertAllWindowIds
  10049. * @method unknown assertAllWindowNames
  10050. * @method unknown assertAllWindowTitles
  10051. * @method unknown assertAttribute
  10052. * @method unknown assertAttributeFromAllWindows
  10053. * @method unknown assertBodyText
  10054. * @method unknown assertChecked
  10055. * @method unknown assertConfirmation
  10056. * @method unknown assertConfirmationNotPresent
  10057. * @method unknown assertConfirmationPresent
  10058. * @method unknown assertCookie
  10059. * @method unknown assertCookieByName
  10060. * @method unknown assertCookieNotPresent
  10061. * @method unknown assertCookiePresent
  10062. * @method unknown assertCssCount
  10063. * @method unknown assertCursorPosition
  10064. * @method unknown assertEditable
  10065. * @method unknown assertElementHeight
  10066. * @method unknown assertElementIndex
  10067. * @method unknown assertElementNotPresent
  10068. * @method unknown assertElementPositionLeft
  10069. * @method unknown assertElementPositionTop
  10070. * @method unknown assertElementPresent
  10071. * @method unknown assertElementWidth
  10072. * @method unknown assertEval
  10073. * @method unknown assertExpression
  10074. * @method unknown assertHtmlSource
  10075. * @method unknown assertLocation
  10076. * @method unknown assertLogMessages
  10077. * @method unknown assertMouseSpeed
  10078. * @method unknown assertNotAlert
  10079. * @method unknown assertNotAllButtons
  10080. * @method unknown assertNotAllFields
  10081. * @method unknown assertNotAllLinks
  10082. * @method unknown assertNotAllWindowIds
  10083. * @method unknown assertNotAllWindowNames
  10084. * @method unknown assertNotAllWindowTitles
  10085. * @method unknown assertNotAttribute
  10086. * @method unknown assertNotAttributeFromAllWindows
  10087. * @method unknown assertNotBodyText
  10088. * @method unknown assertNotChecked
  10089. * @method unknown assertNotConfirmation
  10090. * @method unknown assertNotCookie
  10091. * @method unknown assertNotCookieByName
  10092. * @method unknown assertNotCssCount
  10093. * @method unknown assertNotCursorPosition
  10094. * @method unknown assertNotEditable
  10095. * @method unknown assertNotElementHeight
  10096. * @method unknown assertNotElementIndex
  10097. * @method unknown assertNotElementPositionLeft
  10098. * @method unknown assertNotElementPositionTop
  10099. * @method unknown assertNotElementWidth
  10100. * @method unknown assertNotEval
  10101. * @method unknown assertNotExpression
  10102. * @method unknown assertNotHtmlSource
  10103. * @method unknown assertNotLocation
  10104. * @method unknown assertNotLogMessages
  10105. * @method unknown assertNotMouseSpeed
  10106. * @method unknown assertNotOrdered
  10107. * @method unknown assertNotPrompt
  10108. * @method unknown assertNotSelectOptions
  10109. * @method unknown assertNotSelectedId
  10110. * @method unknown assertNotSelectedIds
  10111. * @method unknown assertNotSelectedIndex
  10112. * @method unknown assertNotSelectedIndexes
  10113. * @method unknown assertNotSelectedLabel
  10114. * @method unknown assertNotSelectedLabels
  10115. * @method unknown assertNotSelectedValue
  10116. * @method unknown assertNotSelectedValues
  10117. * @method unknown assertNotSomethingSelected
  10118. * @method unknown assertNotSpeed
  10119. * @method unknown assertNotSpeedAndWait
  10120. * @method unknown assertNotTable
  10121. * @method unknown assertNotText
  10122. * @method unknown assertNotTitle
  10123. * @method unknown assertNotValue
  10124. * @method unknown assertNotVisible
  10125. * @method unknown assertNotWhetherThisFrameMatchFrameExpression
  10126. * @method unknown assertNotWhetherThisWindowMatchWindowExpression
  10127. * @method unknown assertNotXpathCount
  10128. * @method unknown assertOrdered
  10129. * @method unknown assertPrompt
  10130. * @method unknown assertPromptNotPresent
  10131. * @method unknown assertPromptPresent
  10132. * @method unknown assertSelectOptions
  10133. * @method unknown assertSelectedId
  10134. * @method unknown assertSelectedIds
  10135. * @method unknown assertSelectedIndex
  10136. * @method unknown assertSelectedIndexes
  10137. * @method unknown assertSelectedLabel
  10138. * @method unknown assertSelectedLabels
  10139. * @method unknown assertSelectedValue
  10140. * @method unknown assertSelectedValues
  10141. * @method unknown assertSomethingSelected
  10142. * @method unknown assertSpeed
  10143. * @method unknown assertSpeedAndWait
  10144. * @method unknown assertTable
  10145. * @method unknown assertText
  10146. * @method unknown assertTextNotPresent
  10147. * @method unknown assertTextPresent
  10148. * @method unknown assertTitle
  10149. * @method unknown assertValue
  10150. * @method unknown assertVisible
  10151. * @method unknown assertWhetherThisFrameMatchFrameExpression
  10152. * @method unknown assertWhetherThisWindowMatchWindowExpression
  10153. * @method unknown assertXpathCount
  10154. * @method unknown attachFile()
  10155. * @method unknown break()
  10156. * @method unknown captureEntirePageScreenshot()
  10157. * @method unknown captureEntirePageScreenshotAndWait()
  10158. * @method unknown captureEntirePageScreenshotToStringAndWait()
  10159. * @method unknown captureScreenshotAndWait()
  10160. * @method unknown captureScreenshotToStringAndWait()
  10161. * @method unknown check()
  10162. * @method unknown checkAndWait()
  10163. * @method unknown chooseCancelOnNextConfirmation()
  10164. * @method unknown chooseCancelOnNextConfirmationAndWait()
  10165. * @method unknown chooseOkOnNextConfirmation()
  10166. * @method unknown chooseOkOnNextConfirmationAndWait()
  10167. * @method unknown click()
  10168. * @method unknown clickAndWait()
  10169. * @method unknown clickAt()
  10170. * @method unknown clickAtAndWait()
  10171. * @method unknown close()
  10172. * @method unknown contextMenu()
  10173. * @method unknown contextMenuAndWait()
  10174. * @method unknown contextMenuAt()
  10175. * @method unknown contextMenuAtAndWait()
  10176. * @method unknown controlKeyDown()
  10177. * @method unknown controlKeyDownAndWait()
  10178. * @method unknown controlKeyUp()
  10179. * @method unknown controlKeyUpAndWait()
  10180. * @method unknown createCookie()
  10181. * @method unknown createCookieAndWait()
  10182. * @method unknown deleteAllVisibleCookies()
  10183. * @method unknown deleteAllVisibleCookiesAndWait()
  10184. * @method unknown deleteCookie()
  10185. * @method unknown deleteCookieAndWait()
  10186. * @method unknown deselectPopUp()
  10187. * @method unknown deselectPopUpAndWait()
  10188. * @method unknown doubleClick()
  10189. * @method unknown doubleClickAndWait()
  10190. * @method unknown doubleClickAt()
  10191. * @method unknown doubleClickAtAndWait()
  10192. * @method unknown dragAndDrop()
  10193. * @method unknown dragAndDropAndWait()
  10194. * @method unknown dragAndDropToObject()
  10195. * @method unknown dragAndDropToObjectAndWait()
  10196. * @method unknown dragDrop()
  10197. * @method unknown dragDropAndWait()
  10198. * @method unknown echo()
  10199. * @method unknown fireEvent()
  10200. * @method unknown fireEventAndWait()
  10201. * @method unknown focus()
  10202. * @method unknown focusAndWait()
  10203. * @method string getAlert()
  10204. * @method array getAllButtons()
  10205. * @method array getAllFields()
  10206. * @method array getAllLinks()
  10207. * @method array getAllWindowIds()
  10208. * @method array getAllWindowNames()
  10209. * @method array getAllWindowTitles()
  10210. * @method string getAttribute()
  10211. * @method array getAttributeFromAllWindows()
  10212. * @method string getBodyText()
  10213. * @method string getConfirmation()
  10214. * @method string getCookie()
  10215. * @method string getCookieByName()
  10216. * @method integer getCursorPosition()
  10217. * @method integer getElementHeight()
  10218. * @method integer getElementIndex()
  10219. * @method integer getElementPositionLeft()
  10220. * @method integer getElementPositionTop()
  10221. * @method integer getElementWidth()
  10222. * @method string getEval()
  10223. * @method string getExpression()
  10224. * @method string getHtmlSource()
  10225. * @method string getLocation()
  10226. * @method string getLogMessages()
  10227. * @method integer getMouseSpeed()
  10228. * @method string getPrompt()
  10229. * @method array getSelectOptions()
  10230. * @method string getSelectedId()
  10231. * @method array getSelectedIds()
  10232. * @method string getSelectedIndex()
  10233. * @method array getSelectedIndexes()
  10234. * @method string getSelectedLabel()
  10235. * @method array getSelectedLabels()
  10236. * @method string getSelectedValue()
  10237. * @method array getSelectedValues()
  10238. * @method unknown getSpeed()
  10239. * @method unknown getSpeedAndWait()
  10240. * @method string getTable()
  10241. * @method string getText()
  10242. * @method string getTitle()
  10243. * @method string getValue()
  10244. * @method boolean getWhetherThisFrameMatchFrameExpression()
  10245. * @method boolean getWhetherThisWindowMatchWindowExpression()
  10246. * @method integer getXpathCount()
  10247. * @method unknown goBack()
  10248. * @method unknown goBackAndWait()
  10249. * @method unknown highlight()
  10250. * @method unknown highlightAndWait()
  10251. * @method unknown ignoreAttributesWithoutValue()
  10252. * @method unknown ignoreAttributesWithoutValueAndWait()
  10253. * @method boolean isAlertPresent()
  10254. * @method boolean isChecked()
  10255. * @method boolean isConfirmationPresent()
  10256. * @method boolean isCookiePresent()
  10257. * @method boolean isEditable()
  10258. * @method boolean isElementPresent()
  10259. * @method boolean isOrdered()
  10260. * @method boolean isPromptPresent()
  10261. * @method boolean isSomethingSelected()
  10262. * @method boolean isTextPresent()
  10263. * @method boolean isVisible()
  10264. * @method unknown keyDown()
  10265. * @method unknown keyDownAndWait()
  10266. * @method unknown keyDownNative()
  10267. * @method unknown keyDownNativeAndWait()
  10268. * @method unknown keyPress()
  10269. * @method unknown keyPressAndWait()
  10270. * @method unknown keyPressNative()
  10271. * @method unknown keyPressNativeAndWait()
  10272. * @method unknown keyUp()
  10273. * @method unknown keyUpAndWait()
  10274. * @method unknown keyUpNative()
  10275. * @method unknown keyUpNativeAndWait()
  10276. * @method unknown metaKeyDown()
  10277. * @method unknown metaKeyDownAndWait()
  10278. * @method unknown metaKeyUp()
  10279. * @method unknown metaKeyUpAndWait()
  10280. * @method unknown mouseDown()
  10281. * @method unknown mouseDownAndWait()
  10282. * @method unknown mouseDownAt()
  10283. * @method unknown mouseDownAtAndWait()
  10284. * @method unknown mouseMove()
  10285. * @method unknown mouseMoveAndWait()
  10286. * @method unknown mouseMoveAt()
  10287. * @method unknown mouseMoveAtAndWait()
  10288. * @method unknown mouseOut()
  10289. * @method unknown mouseOutAndWait()
  10290. * @method unknown mouseOver()
  10291. * @method unknown mouseOverAndWait()
  10292. * @method unknown mouseUp()
  10293. * @method unknown mouseUpAndWait()
  10294. * @method unknown mouseUpAt()
  10295. * @method unknown mouseUpAtAndWait()
  10296. * @method unknown mouseUpRight()
  10297. * @method unknown mouseUpRightAndWait()
  10298. * @method unknown mouseUpRightAt()
  10299. * @method unknown mouseUpRightAtAndWait()
  10300. * @method unknown open()
  10301. * @method unknown openWindow()
  10302. * @method unknown openWindowAndWait()
  10303. * @method unknown pause()
  10304. * @method unknown refresh()
  10305. * @method unknown refreshAndWait()
  10306. * @method unknown removeAllSelections()
  10307. * @method unknown removeAllSelectionsAndWait()
  10308. * @method unknown removeScript()
  10309. * @method unknown removeScriptAndWait()
  10310. * @method unknown removeSelection()
  10311. * @method unknown removeSelectionAndWait()
  10312. * @method unknown retrieveLastRemoteControlLogs()
  10313. * @method unknown rollup()
  10314. * @method unknown rollupAndWait()
  10315. * @method unknown runScript()
  10316. * @method unknown runScriptAndWait()
  10317. * @method unknown select()
  10318. * @method unknown selectAndWait()
  10319. * @method unknown selectFrame()
  10320. * @method unknown selectPopUp()
  10321. * @method unknown selectPopUpAndWait()
  10322. * @method unknown selectWindow()
  10323. * @method unknown setBrowserLogLevel()
  10324. * @method unknown setBrowserLogLevelAndWait()
  10325. * @method unknown setContext()
  10326. * @method unknown setCursorPosition()
  10327. * @method unknown setCursorPositionAndWait()
  10328. * @method unknown setMouseSpeed()
  10329. * @method unknown setMouseSpeedAndWait()
  10330. * @method unknown setSpeed()
  10331. * @method unknown setSpeedAndWait()
  10332. * @method unknown shiftKeyDown()
  10333. * @method unknown shiftKeyDownAndWait()
  10334. * @method unknown shiftKeyUp()
  10335. * @method unknown shiftKeyUpAndWait()
  10336. * @method unknown shutDownSeleniumServer()
  10337. * @method unknown store()
  10338. * @method unknown submit()
  10339. * @method unknown submitAndWait()
  10340. * @method unknown type()
  10341. * @method unknown typeAndWait()
  10342. * @method unknown typeKeys()
  10343. * @method unknown typeKeysAndWait()
  10344. * @method unknown uncheck()
  10345. * @method unknown uncheckAndWait()
  10346. * @method unknown useXpathLibrary()
  10347. * @method unknown useXpathLibraryAndWait()
  10348. * @method unknown waitForAlert
  10349. * @method unknown waitForAlertNotPresent
  10350. * @method unknown waitForAlertPresent
  10351. * @method unknown waitForAllButtons
  10352. * @method unknown waitForAllFields
  10353. * @method unknown waitForAllLinks
  10354. * @method unknown waitForAllWindowIds
  10355. * @method unknown waitForAllWindowNames
  10356. * @method unknown waitForAllWindowTitles
  10357. * @method unknown waitForAttribute
  10358. * @method unknown waitForAttributeFromAllWindows
  10359. * @method unknown waitForBodyText
  10360. * @method unknown waitForChecked
  10361. * @method unknown waitForCondition()
  10362. * @method unknown waitForConfirmation
  10363. * @method unknown waitForConfirmationNotPresent
  10364. * @method unknown waitForConfirmationPresent
  10365. * @method unknown waitForCookie
  10366. * @method unknown waitForCookieByName
  10367. * @method unknown waitForCookieNotPresent
  10368. * @method unknown waitForCookiePresent
  10369. * @method unknown waitForCssCount
  10370. * @method unknown waitForCursorPosition
  10371. * @method unknown waitForEditable
  10372. * @method unknown waitForElementHeight
  10373. * @method unknown waitForElementIndex
  10374. * @method unknown waitForElementNotPresent
  10375. * @method unknown waitForElementPositionLeft
  10376. * @method unknown waitForElementPositionTop
  10377. * @method unknown waitForElementPresent
  10378. * @method unknown waitForElementWidth
  10379. * @method unknown waitForEval
  10380. * @method unknown waitForExpression
  10381. * @method unknown waitForHtmlSource
  10382. * @method unknown waitForLocation
  10383. * @method unknown waitForLogMessages
  10384. * @method unknown waitForMouseSpeed
  10385. * @method unknown waitForNotAlert
  10386. * @method unknown waitForNotAllButtons
  10387. * @method unknown waitForNotAllFields
  10388. * @method unknown waitForNotAllLinks
  10389. * @method unknown waitForNotAllWindowIds
  10390. * @method unknown waitForNotAllWindowNames
  10391. * @method unknown waitForNotAllWindowTitles
  10392. * @method unknown waitForNotAttribute
  10393. * @method unknown waitForNotAttributeFromAllWindows
  10394. * @method unknown waitForNotBodyText
  10395. * @method unknown waitForNotChecked
  10396. * @method unknown waitForNotConfirmation
  10397. * @method unknown waitForNotCookie
  10398. * @method unknown waitForNotCookieByName
  10399. * @method unknown waitForNotCssCount
  10400. * @method unknown waitForNotCursorPosition
  10401. * @method unknown waitForNotEditable
  10402. * @method unknown waitForNotElementHeight
  10403. * @method unknown waitForNotElementIndex
  10404. * @method unknown waitForNotElementPositionLeft
  10405. * @method unknown waitForNotElementPositionTop
  10406. * @method unknown waitForNotElementWidth
  10407. * @method unknown waitForNotEval
  10408. * @method unknown waitForNotExpression
  10409. * @method unknown waitForNotHtmlSource
  10410. * @method unknown waitForNotLocation
  10411. * @method unknown waitForNotLogMessages
  10412. * @method unknown waitForNotMouseSpeed
  10413. * @method unknown waitForNotOrdered
  10414. * @method unknown waitForNotPrompt
  10415. * @method unknown waitForNotSelectOptions
  10416. * @method unknown waitForNotSelectedId
  10417. * @method unknown waitForNotSelectedIds
  10418. * @method unknown waitForNotSelectedIndex
  10419. * @method unknown waitForNotSelectedIndexes
  10420. * @method unknown waitForNotSelectedLabel
  10421. * @method unknown waitForNotSelectedLabels
  10422. * @method unknown waitForNotSelectedValue
  10423. * @method unknown waitForNotSelectedValues
  10424. * @method unknown waitForNotSomethingSelected
  10425. * @method unknown waitForNotSpeed
  10426. * @method unknown waitForNotSpeedAndWait
  10427. * @method unknown waitForNotTable
  10428. * @method unknown waitForNotText
  10429. * @method unknown waitForNotTitle
  10430. * @method unknown waitForNotValue
  10431. * @method unknown waitForNotVisible
  10432. * @method unknown waitForNotWhetherThisFrameMatchFrameExpression
  10433. * @method unknown waitForNotWhetherThisWindowMatchWindowExpression
  10434. * @method unknown waitForNotXpathCount
  10435. * @method unknown waitForOrdered
  10436. * @method unknown waitForPageToLoad()
  10437. * @method unknown waitForPopUp()
  10438. * @method unknown waitForPrompt
  10439. * @method unknown waitForPromptNotPresent
  10440. * @method unknown waitForPromptPresent
  10441. * @method unknown waitForSelectOptions
  10442. * @method unknown waitForSelectedId
  10443. * @method unknown waitForSelectedIds
  10444. * @method unknown waitForSelectedIndex
  10445. * @method unknown waitForSelectedIndexes
  10446. * @method unknown waitForSelectedLabel
  10447. * @method unknown waitForSelectedLabels
  10448. * @method unknown waitForSelectedValue
  10449. * @method unknown waitForSelectedValues
  10450. * @method unknown waitForSomethingSelected
  10451. * @method unknown waitForSpeed
  10452. * @method unknown waitForSpeedAndWait
  10453. * @method unknown waitForTable
  10454. * @method unknown waitForText
  10455. * @method unknown waitForTextNotPresent
  10456. * @method unknown waitForTextPresent
  10457. * @method unknown waitForTitle
  10458. * @method unknown waitForValue
  10459. * @method unknown waitForVisible
  10460. * @method unknown waitForWhetherThisFrameMatchFrameExpression
  10461. * @method unknown waitForWhetherThisWindowMatchWindowExpression
  10462. * @method unknown waitForXpathCount
  10463. * @method unknown windowFocus()
  10464. * @method unknown windowMaximize()
  10465. */
  10466. abstract class PHPUnit_Extensions_SeleniumTestCase extends PHPUnit_Framework_TestCase
  10467. {
  10468. /**
  10469. * @var array
  10470. */
  10471. public static $browsers = array();
  10472. /**
  10473. * @var string
  10474. */
  10475. protected $browserName;
  10476. /**
  10477. * @var boolean
  10478. */
  10479. protected $collectCodeCoverageInformation = FALSE;
  10480. /**
  10481. * @var string
  10482. */
  10483. protected $coverageScriptUrl = '';
  10484. /**
  10485. * @var PHPUnit_Extensions_SeleniumTestCase_Driver[]
  10486. */
  10487. protected $drivers = array();
  10488. /**
  10489. * @var boolean
  10490. */
  10491. protected $inDefaultAssertions = FALSE;
  10492. /**
  10493. * @var string
  10494. */
  10495. protected $testId;
  10496. /**
  10497. * @var array
  10498. * @access protected
  10499. */
  10500. protected $verificationErrors = array();
  10501. /**
  10502. * @var boolean
  10503. */
  10504. protected $captureScreenshotOnFailure = FALSE;
  10505. /**
  10506. * @var string
  10507. */
  10508. protected $screenshotPath = '';
  10509. /**
  10510. * @var string
  10511. */
  10512. protected $screenshotUrl = '';
  10513. /**
  10514. * @var string
  10515. */
  10516. protected $screenshotBgColor = '';
  10517. /**
  10518. * @var integer the number of seconds to wait before declaring
  10519. * the Selenium server not reachable
  10520. */
  10521. protected $serverConnectionTimeOut = 10;
  10522. /**
  10523. * @var boolean
  10524. */
  10525. private $serverRunning;
  10526. /**
  10527. * @var boolean
  10528. */
  10529. private static $shareSession;
  10530. /**
  10531. * The last sessionId used for running a test.
  10532. * @var string
  10533. */
  10534. private static $sessionId;
  10535. /**
  10536. * @param boolean
  10537. */
  10538. public static function shareSession($shareSession)
  10539. {
  10540. self::$shareSession = $shareSession;
  10541. }
  10542. /**
  10543. * @param string $name
  10544. * @param array $data
  10545. * @param string $dataName
  10546. * @param array $browser
  10547. * @throws InvalidArgumentException
  10548. */
  10549. public function __construct($name = NULL, array $data = array(), $dataName = '', array $browser = array())
  10550. {
  10551. parent::__construct($name, $data, $dataName);
  10552. $this->testId = md5(uniqid(rand(), TRUE));
  10553. $this->getDriver($browser);
  10554. }
  10555. public function setupSpecificBrowser(array $browser)
  10556. {
  10557. $this->getDriver($browser);
  10558. }
  10559. /**
  10560. * Stops any shared session still open at the end of the current
  10561. * PHPUnit process.
  10562. */
  10563. public function __destruct()
  10564. {
  10565. $this->stopSession();
  10566. }
  10567. /**
  10568. * @param string $className
  10569. * @return PHPUnit_Framework_TestSuite
  10570. */
  10571. public static function suite($className)
  10572. {
  10573. return PHPUnit_Extensions_SeleniumTestSuite::fromTestCaseClass($className);
  10574. }
  10575. /**
  10576. * Runs the test case and collects the results in a TestResult object.
  10577. * If no TestResult object is passed a new one will be created.
  10578. *
  10579. * @param PHPUnit_Framework_TestResult $result
  10580. * @return PHPUnit_Framework_TestResult
  10581. * @throws InvalidArgumentException
  10582. */
  10583. public function run(PHPUnit_Framework_TestResult $result = NULL)
  10584. {
  10585. if ($result === NULL) {
  10586. $result = $this->createResult();
  10587. }
  10588. $this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
  10589. foreach ($this->drivers as $driver) {
  10590. $driver->setCollectCodeCoverageInformation(
  10591. $this->collectCodeCoverageInformation
  10592. );
  10593. }
  10594. parent::run($result);
  10595. if ($this->collectCodeCoverageInformation) {
  10596. $result->getCodeCoverage()->append(
  10597. $this->getCodeCoverage(), $this
  10598. );
  10599. }
  10600. return $result;
  10601. }
  10602. /**
  10603. * @param array $browser
  10604. * @return PHPUnit_Extensions_SeleniumTestCase_Driver
  10605. */
  10606. protected function getDriver(array $browser)
  10607. {
  10608. if (isset($browser['name'])) {
  10609. if (!is_string($browser['name'])) {
  10610. throw new InvalidArgumentException(
  10611. 'Array element "name" is no string.'
  10612. );
  10613. }
  10614. } else {
  10615. $browser['name'] = '';
  10616. }
  10617. if (isset($browser['browser'])) {
  10618. if (!is_string($browser['browser'])) {
  10619. throw new InvalidArgumentException(
  10620. 'Array element "browser" is no string.'
  10621. );
  10622. }
  10623. } else {
  10624. $browser['browser'] = '';
  10625. }
  10626. if (isset($browser['host'])) {
  10627. if (!is_string($browser['host'])) {
  10628. throw new InvalidArgumentException(
  10629. 'Array element "host" is no string.'
  10630. );
  10631. }
  10632. } else {
  10633. $browser['host'] = 'localhost';
  10634. }
  10635. if (isset($browser['port'])) {
  10636. if (!is_int($browser['port'])) {
  10637. throw new InvalidArgumentException(
  10638. 'Array element "port" is no integer.'
  10639. );
  10640. }
  10641. } else {
  10642. $browser['port'] = 4444;
  10643. }
  10644. if (isset($browser['timeout'])) {
  10645. if (!is_int($browser['timeout'])) {
  10646. throw new InvalidArgumentException(
  10647. 'Array element "timeout" is no integer.'
  10648. );
  10649. }
  10650. } else {
  10651. $browser['timeout'] = 30;
  10652. }
  10653. if (isset($browser['httpTimeout'])) {
  10654. if (!is_int($browser['httpTimeout'])) {
  10655. throw new InvalidArgumentException(
  10656. 'Array element "httpTimeout" is no integer.'
  10657. );
  10658. }
  10659. } else {
  10660. $browser['httpTimeout'] = 45;
  10661. }
  10662. $driver = new PHPUnit_Extensions_SeleniumTestCase_Driver;
  10663. $driver->setName($browser['name']);
  10664. $driver->setBrowser($browser['browser']);
  10665. $driver->setHost($browser['host']);
  10666. $driver->setPort($browser['port']);
  10667. $driver->setTimeout($browser['timeout']);
  10668. $driver->setHttpTimeout($browser['httpTimeout']);
  10669. $driver->setTestCase($this);
  10670. $driver->setTestId($this->testId);
  10671. $this->drivers[0] = $driver;
  10672. return $driver;
  10673. }
  10674. public function skipWithNoServerRunning()
  10675. {
  10676. try {
  10677. fsockopen($this->drivers[0]->getHost(), $this->drivers[0]->getPort(), $errno, $errstr, $this->serverConnectionTimeOut);
  10678. $this->serverRunning = TRUE;
  10679. } catch (PHPUnit_Framework_Error_Warning $e) {
  10680. $this->markTestSkipped(
  10681. sprintf(
  10682. 'Could not connect to the Selenium Server on %s:%d.',
  10683. $this->drivers[0]->getHost(),
  10684. $this->drivers[0]->getPort()
  10685. )
  10686. );
  10687. $this->serverRunning = FALSE;
  10688. }
  10689. }
  10690. /**
  10691. * @return string
  10692. */
  10693. protected function prepareTestSession()
  10694. {
  10695. $testCaseClassVars = get_class_vars(get_class($this));
  10696. if ($testCaseClassVars['browsers']) {
  10697. return $this->start();
  10698. }
  10699. if (self::$shareSession && self::$sessionId !== NULL) {
  10700. $this->setSessionId(self::$sessionId);
  10701. $this->selectWindow('null');
  10702. } else {
  10703. self::$sessionId = $this->start();
  10704. }
  10705. return self::$sessionId;
  10706. }
  10707. /**
  10708. * @throws RuntimeException
  10709. */
  10710. protected function runTest()
  10711. {
  10712. $this->skipWithNoServerRunning();
  10713. $this->prepareTestSession();
  10714. if (!is_file($this->getName(FALSE))) {
  10715. $result = parent::runTest();
  10716. } else {
  10717. $this->runSelenese($this->getName(FALSE));
  10718. $result = NULL;
  10719. }
  10720. if (!empty($this->verificationErrors)) {
  10721. $this->fail(implode("\n", $this->verificationErrors));
  10722. }
  10723. if (!self::$shareSession) {
  10724. $this->stopSession();
  10725. }
  10726. return $result;
  10727. }
  10728. private function stopSession()
  10729. {
  10730. try {
  10731. $this->stop();
  10732. } catch (RuntimeException $e) { }
  10733. }
  10734. /**
  10735. * Returns a string representation of the test case.
  10736. *
  10737. * @return string
  10738. */
  10739. public function toString()
  10740. {
  10741. $buffer = parent::toString();
  10742. if (!empty($this->browserName)) {
  10743. $buffer .= ' with browser ' . $this->browserName;
  10744. }
  10745. return $buffer;
  10746. }
  10747. /**
  10748. * Runs a test from a Selenese (HTML) specification.
  10749. *
  10750. * @param string $filename
  10751. */
  10752. public function runSelenese($filename)
  10753. {
  10754. $document = PHPUnit_Util_XML::loadFile($filename, TRUE);
  10755. $xpath = new DOMXPath($document);
  10756. $rows = $xpath->query('body/table/tbody/tr');
  10757. foreach ($rows as $row) {
  10758. $action = NULL;
  10759. $arguments = array();
  10760. $columns = $xpath->query('td', $row);
  10761. foreach ($columns as $column) {
  10762. if ($action === NULL) {
  10763. $action = PHPUnit_Util_XML::nodeToText($column);
  10764. } else {
  10765. $arguments[] = PHPUnit_Util_XML::nodeToText($column);
  10766. }
  10767. }
  10768. if (method_exists($this, $action)) {
  10769. call_user_func_array(array($this, $action), $arguments);
  10770. } else {
  10771. $this->__call($action, $arguments);
  10772. }
  10773. }
  10774. }
  10775. /**
  10776. * Delegate method calls to the driver.
  10777. *
  10778. * @param string $command
  10779. * @param array $arguments
  10780. * @return mixed
  10781. */
  10782. public function __call($command, $arguments)
  10783. {
  10784. $result = call_user_func_array(
  10785. array($this->drivers[0], $command), $arguments
  10786. );
  10787. $this->verificationErrors = array_merge(
  10788. $this->verificationErrors, $this->drivers[0]->getVerificationErrors()
  10789. );
  10790. $this->drivers[0]->clearVerificationErrors();
  10791. return $result;
  10792. }
  10793. /**
  10794. * Asserts that an element's value is equal to a given string.
  10795. *
  10796. * @param string $locator
  10797. * @param string $text
  10798. * @param string $message
  10799. */
  10800. public function assertElementValueEquals($locator, $text, $message = '')
  10801. {
  10802. $this->assertEquals($text, $this->getValue($locator), $message);
  10803. }
  10804. /**
  10805. * Asserts that an element's value is not equal to a given string.
  10806. *
  10807. * @param string $locator
  10808. * @param string $text
  10809. * @param string $message
  10810. */
  10811. public function assertElementValueNotEquals($locator, $text, $message = '')
  10812. {
  10813. $this->assertNotEquals($text, $this->getValue($locator), $message);
  10814. }
  10815. /**
  10816. * Asserts that an element's value contains a given string.
  10817. *
  10818. * @param string $locator
  10819. * @param string $text
  10820. * @param string $message
  10821. */
  10822. public function assertElementValueContains($locator, $text, $message = '')
  10823. {
  10824. $this->assertContains($text, $this->getValue($locator), $message);
  10825. }
  10826. /**
  10827. * Asserts that an element's value does not contain a given string.
  10828. *
  10829. * @param string $locator
  10830. * @param string $text
  10831. * @param string $message
  10832. */
  10833. public function assertElementValueNotContains($locator, $text, $message = '')
  10834. {
  10835. $this->assertNotContains($text, $this->getValue($locator), $message);
  10836. }
  10837. /**
  10838. * Asserts that an element contains a given string.
  10839. *
  10840. * @param string $locator
  10841. * @param string $text
  10842. * @param string $message
  10843. */
  10844. public function assertElementContainsText($locator, $text, $message = '')
  10845. {
  10846. $this->assertContains($text, $this->getText($locator), $message);
  10847. }
  10848. /**
  10849. * Asserts that an element does not contain a given string.
  10850. *
  10851. * @param string $locator
  10852. * @param string $text
  10853. * @param string $message
  10854. */
  10855. public function assertElementNotContainsText($locator, $text, $message = '')
  10856. {
  10857. $this->assertNotContains($text, $this->getText($locator), $message);
  10858. }
  10859. /**
  10860. * Asserts that a select element has a specific option.
  10861. *
  10862. * @param string $selectLocator
  10863. * @param string $option
  10864. * @param string $message
  10865. */
  10866. public function assertSelectHasOption($selectLocator, $option, $message = '')
  10867. {
  10868. $this->assertContains($option, $this->getSelectOptions($selectLocator), $message);
  10869. }
  10870. /**
  10871. * Asserts that a select element does not have a specific option.
  10872. *
  10873. * @param string $selectLocator
  10874. * @param string $option
  10875. * @param string $message
  10876. */
  10877. public function assertSelectNotHasOption($selectLocator, $option, $message = '')
  10878. {
  10879. $this->assertNotContains($option, $this->getSelectOptions($selectLocator), $message);
  10880. }
  10881. /**
  10882. * Asserts that a specific label is selected.
  10883. *
  10884. * @param string $selectLocator
  10885. * @param string $value
  10886. * @param string $message
  10887. */
  10888. public function assertSelected($selectLocator, $option, $message = '')
  10889. {
  10890. if ($message == '') {
  10891. $message = sprintf(
  10892. 'Label "%s" not selected in "%s".',
  10893. $option,
  10894. $selectLocator
  10895. );
  10896. }
  10897. $this->assertEquals(
  10898. $option,
  10899. $this->getSelectedLabel($selectLocator),
  10900. $message
  10901. );
  10902. }
  10903. /**
  10904. * Asserts that a specific label is not selected.
  10905. *
  10906. * @param string $selectLocator
  10907. * @param string $value
  10908. * @param string $message
  10909. */
  10910. public function assertNotSelected($selectLocator, $option, $message = '')
  10911. {
  10912. if ($message == '') {
  10913. $message = sprintf(
  10914. 'Label "%s" selected in "%s".',
  10915. $option,
  10916. $selectLocator
  10917. );
  10918. }
  10919. $this->assertNotEquals(
  10920. $option,
  10921. $this->getSelectedLabel($selectLocator),
  10922. $message
  10923. );
  10924. }
  10925. /**
  10926. * Asserts that a specific value is selected.
  10927. *
  10928. * @param string $selectLocator
  10929. * @param string $value
  10930. * @param string $message
  10931. */
  10932. public function assertIsSelected($selectLocator, $value, $message = '')
  10933. {
  10934. if ($message == '') {
  10935. $message = sprintf(
  10936. 'Value "%s" not selected in "%s".',
  10937. $value,
  10938. $selectLocator
  10939. );
  10940. }
  10941. $this->assertEquals(
  10942. $value, $this->getSelectedValue($selectLocator),
  10943. $message
  10944. );
  10945. }
  10946. /**
  10947. * Asserts that a specific value is not selected.
  10948. *
  10949. * @param string $selectLocator
  10950. * @param string $value
  10951. * @param string $message
  10952. */
  10953. public function assertIsNotSelected($selectLocator, $value, $message = '')
  10954. {
  10955. if ($message == '') {
  10956. $message = sprintf(
  10957. 'Value "%s" selected in "%s".',
  10958. $value,
  10959. $selectLocator
  10960. );
  10961. }
  10962. $this->assertNotEquals(
  10963. $value,
  10964. $this->getSelectedValue($selectLocator),
  10965. $message
  10966. );
  10967. }
  10968. /**
  10969. * Template Method that is called after Selenium actions.
  10970. *
  10971. * @param string $action
  10972. */
  10973. protected function defaultAssertions($action)
  10974. {
  10975. }
  10976. /**
  10977. * @return array
  10978. */
  10979. protected function getCodeCoverage()
  10980. {
  10981. $coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
  10982. $this->coverageScriptUrl,
  10983. $this->testId
  10984. );
  10985. return $coverage->get();
  10986. }
  10987. /**
  10988. * @param string $action
  10989. */
  10990. public function runDefaultAssertions($action)
  10991. {
  10992. if (!$this->inDefaultAssertions) {
  10993. $this->inDefaultAssertions = TRUE;
  10994. $this->defaultAssertions($action);
  10995. $this->inDefaultAssertions = FALSE;
  10996. }
  10997. }
  10998. /**
  10999. * This method is called when a test method did not execute successfully.
  11000. *
  11001. * @param Exception $e
  11002. */
  11003. protected function onNotSuccessfulTest(Exception $e)
  11004. {
  11005. if (!$this->serverRunning) {
  11006. throw $e;
  11007. }
  11008. try {
  11009. $this->restoreSessionStateAfterFailedTest();
  11010. $buffer = '';
  11011. if ($this->captureScreenshotOnFailure) {
  11012. $buffer .= 'Current URL: ' . $this->drivers[0]->getLocation() .
  11013. "\n";
  11014. $screenshotInfo = $this->takeScreenshot();
  11015. if ($screenshotInfo != '') {
  11016. $buffer .= $screenshotInfo;
  11017. }
  11018. }
  11019. $this->stopSession();
  11020. } catch (Exception $another) {
  11021. $buffer = "Issues while capturing the screenshot:\n" . $another->getMessage();
  11022. }
  11023. if ($e instanceof PHPUnit_Framework_ExpectationFailedException
  11024. && is_object($e->getComparisonFailure())) {
  11025. $message = $e->getComparisonFailure()->toString();
  11026. } else {
  11027. $message = $e->getMessage();
  11028. }
  11029. $buffer .= "\n" . $message;
  11030. // gain the screenshot path, lose the stack trace
  11031. if ($this->captureScreenshotOnFailure) {
  11032. throw new PHPUnit_Framework_Error($buffer, $e->getCode(), $e->getFile(), $e->getLine(), $e);
  11033. }
  11034. // yes to stack trace and everything
  11035. if ($e instanceof PHPUnit_Framework_IncompleteTestError
  11036. || $e instanceof PHPUnit_Framework_SkippedTestError
  11037. || $e instanceof PHPUnit_Framework_AssertionFailedError) {
  11038. throw $e;
  11039. }
  11040. // yes to stack trace, only for F tests
  11041. // PHPUnit issue 471 prevents getTrace() from being useful
  11042. throw new PHPUnit_Framework_Error($buffer, $e->getCode(), $e->getFile(), $e->getLine(), $e);
  11043. }
  11044. private function restoreSessionStateAfterFailedTest()
  11045. {
  11046. self::$sessionId = NULL;
  11047. }
  11048. /**
  11049. * Returns correct path to screenshot save path.
  11050. *
  11051. * @return string
  11052. */
  11053. protected function getScreenshotPath()
  11054. {
  11055. $path = $this->screenshotPath;
  11056. if (!in_array(substr($path, strlen($path) -1, 1), array("/","\\"))) {
  11057. $path .= DIRECTORY_SEPARATOR;
  11058. }
  11059. return $path;
  11060. }
  11061. /**
  11062. * Take a screenshot and return information about it.
  11063. * Return an empty string if the screenshotPath and screenshotUrl
  11064. * properties are empty.
  11065. * Issue #88.
  11066. *
  11067. * @access protected
  11068. * @return string
  11069. */
  11070. protected function takeScreenshot()
  11071. {
  11072. if (!empty($this->screenshotPath) &&
  11073. !empty($this->screenshotUrl)) {
  11074. $filename = $this->getScreenshotPath() . $this->testId . '.png';
  11075. $kargs = '';
  11076. if ($this->screenshotBgColor!='') {
  11077. $kargs = 'background=' . $this->screenshotBgColor;
  11078. }
  11079. $this->drivers[0]->captureEntirePageScreenshot($filename, $kargs);
  11080. return 'Screenshot: ' . $this->screenshotUrl . '/' .
  11081. $this->testId . ".png\n";
  11082. } else {
  11083. return '';
  11084. }
  11085. }
  11086. /**
  11087. * Pause support for runSelenese() HTML cases
  11088. * @param $milliseconds
  11089. */
  11090. protected function pause($milliseconds)
  11091. {
  11092. sleep(round($milliseconds/1000));
  11093. }
  11094. }
  11095. <?php
  11096. /**
  11097. * PHPUnit
  11098. *
  11099. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  11100. * All rights reserved.
  11101. *
  11102. * Redistribution and use in source and binary forms, with or without
  11103. * modification, are permitted provided that the following conditions
  11104. * are met:
  11105. *
  11106. * * Redistributions of source code must retain the above copyright
  11107. * notice, this list of conditions and the following disclaimer.
  11108. *
  11109. * * Redistributions in binary form must reproduce the above copyright
  11110. * notice, this list of conditions and the following disclaimer in
  11111. * the documentation and/or other materials provided with the
  11112. * distribution.
  11113. *
  11114. * * Neither the name of Sebastian Bergmann nor the names of his
  11115. * contributors may be used to endorse or promote products derived
  11116. * from this software without specific prior written permission.
  11117. *
  11118. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  11119. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  11120. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  11121. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  11122. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  11123. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  11124. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  11125. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  11126. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  11127. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  11128. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  11129. * POSSIBILITY OF SUCH DAMAGE.
  11130. *
  11131. * @package PHPUnit_Selenium
  11132. * @author Giorgio Sironi <info@giorgiosironi.com>
  11133. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  11134. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  11135. * @link http://www.phpunit.de/
  11136. * @since File available since Release 1.2.2
  11137. */
  11138. /**
  11139. * TestSuite class for Selenium 1 tests
  11140. *
  11141. * @package PHPUnit_Selenium
  11142. * @author Giorgio Sironi <info@giorgiosironi.com>
  11143. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  11144. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  11145. * @version Release: @package_version@
  11146. * @link http://www.phpunit.de/
  11147. * @since Class available since Release 1.2.0
  11148. */
  11149. class PHPUnit_Extensions_SeleniumTestSuite extends PHPUnit_Framework_TestSuite
  11150. {
  11151. /**
  11152. * Overriding the default: Selenium suites are always built from a TestCase class.
  11153. * @var boolean
  11154. */
  11155. protected $testCase = TRUE;
  11156. /**
  11157. * Making the method public.
  11158. */
  11159. public function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
  11160. {
  11161. return parent::addTestMethod($class, $method);
  11162. }
  11163. /**
  11164. * @param string $className extending PHPUnit_Extensions_SeleniumTestCase
  11165. * @return PHPUnit_Extensions_SeleniumTestSuite
  11166. */
  11167. public static function fromTestCaseClass($className)
  11168. {
  11169. $suite = new self();
  11170. $suite->setName($className);
  11171. $class = new ReflectionClass($className);
  11172. $classGroups = PHPUnit_Util_Test::getGroups($className);
  11173. $staticProperties = $class->getStaticProperties();
  11174. if (isset($staticProperties['browsers'])) {
  11175. $browsers = $staticProperties['browsers'];
  11176. } else if (is_callable("{$className}::browsers")) {
  11177. $browsers = $className::browsers();
  11178. } else {
  11179. $browsers = null;
  11180. }
  11181. //BC: renamed seleneseDirectory -> selenesePath
  11182. if (!isset($staticProperties['selenesePath']) && isset($staticProperties['seleneseDirectory'])) {
  11183. $staticProperties['selenesePath'] = $staticProperties['seleneseDirectory'];
  11184. }
  11185. // Create tests from Selenese/HTML files.
  11186. if (isset($staticProperties['selenesePath']) &&
  11187. (is_dir($staticProperties['selenesePath']) || is_file($staticProperties['selenesePath']))) {
  11188. if (is_dir($staticProperties['selenesePath'])) {
  11189. $files = array_merge(
  11190. self::getSeleneseFiles($staticProperties['selenesePath'], '.htm'),
  11191. self::getSeleneseFiles($staticProperties['selenesePath'], '.html')
  11192. );
  11193. } else {
  11194. $files[] = realpath($staticProperties['selenesePath']);
  11195. }
  11196. // Create tests from Selenese/HTML files for multiple browsers.
  11197. if ($browsers) {
  11198. foreach ($browsers as $browser) {
  11199. $browserSuite = PHPUnit_Extensions_SeleniumBrowserSuite::fromClassAndBrowser($className, $browser);
  11200. foreach ($files as $file) {
  11201. self::addGeneratedTestTo($browserSuite,
  11202. new $className($file, array(), '', $browser),
  11203. $classGroups
  11204. );
  11205. }
  11206. $suite->addTest($browserSuite);
  11207. }
  11208. }
  11209. else {
  11210. // Create tests from Selenese/HTML files for single browser.
  11211. foreach ($files as $file) {
  11212. self::addGeneratedTestTo($suite,
  11213. new $className($file),
  11214. $classGroups);
  11215. }
  11216. }
  11217. }
  11218. // Create tests from test methods for multiple browsers.
  11219. if ($browsers) {
  11220. foreach ($browsers as $browser) {
  11221. $browserSuite = PHPUnit_Extensions_SeleniumBrowserSuite::fromClassAndBrowser($className, $browser);
  11222. foreach ($class->getMethods() as $method) {
  11223. $browserSuite->addTestMethod($class, $method);
  11224. }
  11225. $browserSuite->setupSpecificBrowser($browser);
  11226. $suite->addTest($browserSuite);
  11227. }
  11228. }
  11229. else {
  11230. // Create tests from test methods for single browser.
  11231. foreach ($class->getMethods() as $method) {
  11232. $suite->addTestMethod($class, $method);
  11233. }
  11234. }
  11235. return $suite;
  11236. }
  11237. private static function addGeneratedTestTo(PHPUnit_Framework_TestSuite $suite, PHPUnit_Framework_TestCase $test, $classGroups)
  11238. {
  11239. list ($methodName, ) = explode(' ', $test->getName());
  11240. $test->setDependencies(
  11241. PHPUnit_Util_Test::getDependencies(get_class($test), $methodName)
  11242. );
  11243. $suite->addTest($test, $classGroups);
  11244. }
  11245. /**
  11246. * @param string $directory
  11247. * @param string $suffix
  11248. * @return array
  11249. */
  11250. private static function getSeleneseFiles($directory, $suffix)
  11251. {
  11252. $facade = new File_Iterator_Facade;
  11253. return $facade->getFilesAsArray($directory, $suffix);
  11254. }
  11255. }
  11256. <?php
  11257. /**
  11258. * PHPUnit
  11259. *
  11260. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  11261. * All rights reserved.
  11262. *
  11263. * Redistribution and use in source and binary forms, with or without
  11264. * modification, are permitted provided that the following conditions
  11265. * are met:
  11266. *
  11267. * * Redistributions of source code must retain the above copyright
  11268. * notice, this list of conditions and the following disclaimer.
  11269. *
  11270. * * Redistributions in binary form must reproduce the above copyright
  11271. * notice, this list of conditions and the following disclaimer in
  11272. * the documentation and/or other materials provided with the
  11273. * distribution.
  11274. *
  11275. * * Neither the name of Sebastian Bergmann nor the names of his
  11276. * contributors may be used to endorse or promote products derived
  11277. * from this software without specific prior written permission.
  11278. *
  11279. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  11280. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  11281. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  11282. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  11283. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  11284. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  11285. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  11286. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  11287. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  11288. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  11289. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  11290. * POSSIBILITY OF SUCH DAMAGE.
  11291. *
  11292. * @package PHPUnit_Selenium
  11293. * @author Sebastian Bergmann <sebastian@phpunit.de>
  11294. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  11295. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  11296. * @link http://www.phpunit.de/
  11297. * @since File available since Release 1.0.0
  11298. */
  11299. /**
  11300. * Implementation of the Selenium RC client/server protocol.
  11301. *
  11302. * @package PHPUnit_Selenium
  11303. * @author Sebastian Bergmann <sebastian@phpunit.de>
  11304. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  11305. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  11306. * @version Release: @package_version@
  11307. * @link http://www.phpunit.de/
  11308. * @since Class available since Release 1.0.0
  11309. */
  11310. class PHPUnit_Extensions_SeleniumTestCase_Driver
  11311. {
  11312. /**
  11313. * @var PHPUnit_Extensions_SeleniumTestCase
  11314. */
  11315. protected $testCase;
  11316. /**
  11317. * @var string
  11318. */
  11319. protected $testId;
  11320. /**
  11321. * @var string
  11322. */
  11323. protected $name;
  11324. /**
  11325. * @var string
  11326. */
  11327. protected $browser;
  11328. /**
  11329. * @var string
  11330. */
  11331. protected $browserUrl;
  11332. /**
  11333. * @var boolean
  11334. */
  11335. protected $collectCodeCoverageInformation = FALSE;
  11336. /**
  11337. * @var string
  11338. */
  11339. protected $host = 'localhost';
  11340. /**
  11341. * @var integer
  11342. */
  11343. protected $port = 4444;
  11344. /**
  11345. * @var integer
  11346. */
  11347. protected $httpTimeout = 45;
  11348. /**
  11349. * @var integer
  11350. */
  11351. protected $seleniumTimeout = 30;
  11352. /**
  11353. * @var string
  11354. */
  11355. protected $sessionId;
  11356. /**
  11357. * @var integer
  11358. */
  11359. protected $sleep = 0;
  11360. /**
  11361. * @var boolean
  11362. */
  11363. protected $useWaitForPageToLoad = TRUE;
  11364. /**
  11365. * @var boolean
  11366. */
  11367. protected $wait = 5;
  11368. /**
  11369. * @var array
  11370. */
  11371. protected static $autoGeneratedCommands = array();
  11372. /**
  11373. * @var array
  11374. */
  11375. protected $commands = array();
  11376. /**
  11377. * @var array $userCommands A numerical array which holds custom user commands.
  11378. */
  11379. protected $userCommands = array();
  11380. /**
  11381. * @var array
  11382. */
  11383. protected $verificationErrors = array();
  11384. /**
  11385. * @var array
  11386. */
  11387. private $webDriverCapabilities;
  11388. public function __construct()
  11389. {
  11390. if (empty(self::$autoGeneratedCommands)) {
  11391. self::autoGenerateCommands();
  11392. }
  11393. }
  11394. /**
  11395. * Only browserName is supported.
  11396. */
  11397. public function setWebDriverCapabilities(array $capabilities)
  11398. {
  11399. $this->webDriverCapabilities = $capabilities;
  11400. }
  11401. /**
  11402. * @return string
  11403. */
  11404. public function start()
  11405. {
  11406. if ($this->browserUrl == NULL) {
  11407. throw new PHPUnit_Framework_Exception(
  11408. 'setBrowserUrl() needs to be called before start().'
  11409. );
  11410. }
  11411. if ($this->webDriverCapabilities !== NULL) {
  11412. $seleniumServerUrl = PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($this->host, $this->port);
  11413. $driver = new PHPUnit_Extensions_Selenium2TestCase_Driver($seleniumServerUrl);
  11414. $session = $driver->startSession($this->webDriverCapabilities, new PHPUnit_Extensions_Selenium2TestCase_URL($this->browserUrl));
  11415. $webDriverSessionId = $session->id();
  11416. $this->sessionId = $this->getString(
  11417. 'getNewBrowserSession',
  11418. array($this->browser, $this->browserUrl, '',
  11419. "webdriver.remote.sessionid=$webDriverSessionId")
  11420. );
  11421. $this->doCommand('setTimeout', array($this->seleniumTimeout * 1000));
  11422. }
  11423. if (!isset($this->sessionId)) {
  11424. $this->sessionId = $this->getString(
  11425. 'getNewBrowserSession',
  11426. array($this->browser, $this->browserUrl)
  11427. );
  11428. $this->doCommand('setTimeout', array($this->seleniumTimeout * 1000));
  11429. }
  11430. return $this->sessionId;
  11431. }
  11432. /**
  11433. * @return string
  11434. * @since Method available since Release 1.1.0
  11435. */
  11436. public function getSessionId()
  11437. {
  11438. return $this->sessionId;
  11439. }
  11440. /**
  11441. * @param string
  11442. * @since Method available since Release 1.2.0
  11443. */
  11444. public function setSessionId($sessionId)
  11445. {
  11446. $this->sessionId = $sessionId;
  11447. }
  11448. /**
  11449. */
  11450. public function stop()
  11451. {
  11452. if (!isset($this->sessionId)) {
  11453. return;
  11454. }
  11455. $this->doCommand('testComplete');
  11456. $this->sessionId = NULL;
  11457. }
  11458. /**
  11459. * @param boolean $flag
  11460. * @throws InvalidArgumentException
  11461. */
  11462. public function setCollectCodeCoverageInformation($flag)
  11463. {
  11464. if (!is_bool($flag)) {
  11465. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  11466. }
  11467. $this->collectCodeCoverageInformation = $flag;
  11468. }
  11469. /**
  11470. * @param PHPUnit_Extensions_SeleniumTestCase $testCase
  11471. */
  11472. public function setTestCase(PHPUnit_Extensions_SeleniumTestCase $testCase)
  11473. {
  11474. $this->testCase = $testCase;
  11475. }
  11476. /**
  11477. * @param integer $testId
  11478. */
  11479. public function setTestId($testId)
  11480. {
  11481. $this->testId = $testId;
  11482. }
  11483. /**
  11484. * @return integer $testId
  11485. */
  11486. public function getTestId()
  11487. {
  11488. return $this->testId;
  11489. }
  11490. /**
  11491. * @param string $name
  11492. * @throws InvalidArgumentException
  11493. */
  11494. public function setName($name)
  11495. {
  11496. if (!is_string($name)) {
  11497. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11498. }
  11499. $this->name = $name;
  11500. }
  11501. /**
  11502. * @return string
  11503. */
  11504. public function getName()
  11505. {
  11506. return $this->name;
  11507. }
  11508. /**
  11509. * @param string $browser
  11510. * @throws InvalidArgumentException
  11511. */
  11512. public function setBrowser($browser)
  11513. {
  11514. if (!is_string($browser)) {
  11515. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11516. }
  11517. $this->browser = $browser;
  11518. }
  11519. /**
  11520. * @return string
  11521. */
  11522. public function getBrowser()
  11523. {
  11524. return $this->browser;
  11525. }
  11526. /**
  11527. * @param string $browserUrl
  11528. * @throws InvalidArgumentException
  11529. */
  11530. public function setBrowserUrl($browserUrl)
  11531. {
  11532. if (!is_string($browserUrl)) {
  11533. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11534. }
  11535. $this->browserUrl = $browserUrl;
  11536. }
  11537. /**
  11538. * @param string $host
  11539. * @throws InvalidArgumentException
  11540. */
  11541. public function setHost($host)
  11542. {
  11543. if (!is_string($host)) {
  11544. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11545. }
  11546. $this->host = $host;
  11547. }
  11548. /**
  11549. * @return string
  11550. * @since Method available since Release 1.1.0
  11551. */
  11552. public function getHost()
  11553. {
  11554. return $this->host;
  11555. }
  11556. /**
  11557. * @param integer $port
  11558. * @throws InvalidArgumentException
  11559. */
  11560. public function setPort($port)
  11561. {
  11562. if (!is_int($port)) {
  11563. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  11564. }
  11565. $this->port = $port;
  11566. }
  11567. /**
  11568. * @return integer
  11569. * @since Method available since Release 1.1.0
  11570. */
  11571. public function getPort()
  11572. {
  11573. return $this->port;
  11574. }
  11575. /**
  11576. * @param integer $timeout for Selenium RC in seconds
  11577. * @throws InvalidArgumentException
  11578. */
  11579. public function setTimeout($timeout)
  11580. {
  11581. if (!is_int($timeout)) {
  11582. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  11583. }
  11584. $this->seleniumTimeout = $timeout;
  11585. }
  11586. /**
  11587. * @param integer $timeout for HTTP connection to Selenium RC in seconds
  11588. * @throws InvalidArgumentException
  11589. */
  11590. public function setHttpTimeout($timeout)
  11591. {
  11592. if (!is_int($timeout)) {
  11593. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  11594. }
  11595. $this->httpTimeout = $timeout;
  11596. }
  11597. /**
  11598. * @param integer $seconds
  11599. * @throws InvalidArgumentException
  11600. */
  11601. public function setSleep($seconds)
  11602. {
  11603. if (!is_int($seconds)) {
  11604. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  11605. }
  11606. $this->sleep = $seconds;
  11607. }
  11608. /**
  11609. * Sets the number of seconds to sleep() after *AndWait commands
  11610. * when setWaitForPageToLoad(FALSE) is used.
  11611. *
  11612. * @param integer $seconds
  11613. * @throws InvalidArgumentException
  11614. */
  11615. public function setWait($seconds)
  11616. {
  11617. if (!is_int($seconds)) {
  11618. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  11619. }
  11620. $this->wait = $seconds;
  11621. }
  11622. /**
  11623. * Sets whether waitForPageToLoad (TRUE) or sleep() (FALSE)
  11624. * is used after *AndWait commands.
  11625. *
  11626. * @param boolean $flag
  11627. * @throws InvalidArgumentException
  11628. */
  11629. public function setWaitForPageToLoad($flag)
  11630. {
  11631. if (!is_bool($flag)) {
  11632. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  11633. }
  11634. $this->useWaitForPageToLoad = $flag;
  11635. }
  11636. /**
  11637. * Sets whether captureScreenshotOnFailure (TRUE) or (FALSE)
  11638. * if true, the takeScreenshot() is triggered in onNotSuccessfulTest().
  11639. *
  11640. * @param boolean $flag
  11641. * @throws InvalidArgumentException
  11642. */
  11643. public function setCaptureScreenshotOnFailure($flag)
  11644. {
  11645. if (!is_bool($flag)) {
  11646. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  11647. }
  11648. $this->captureScreenshotOnFailure = $flag;
  11649. }
  11650. /**
  11651. * @param string $screenshotUrl
  11652. * @throws InvalidArgumentException
  11653. */
  11654. public function setScreenshotUrl($screenshotUrl)
  11655. {
  11656. if (!is_string($screenshotUrl)) {
  11657. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11658. }
  11659. $this->screenshotUrl = $screenshotUrl;
  11660. }
  11661. /**
  11662. * @param string $screenshotPath
  11663. * @throws InvalidArgumentException
  11664. */
  11665. public function setScreenshotPath($screenshotPath)
  11666. {
  11667. if (!is_string($screenshotPath)) {
  11668. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11669. }
  11670. $this->screenshotPath = $screenshotPath;
  11671. }
  11672. /**
  11673. * Adds allowed user commands into {@link self::$userCommands}. See
  11674. * {@link self::__call()} (switch/case -> default) for usage.
  11675. *
  11676. * @param string $command A command.
  11677. *
  11678. * @return $this
  11679. * @see self::__call()
  11680. */
  11681. public function addUserCommand($command)
  11682. {
  11683. if (!is_string($command)) {
  11684. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11685. }
  11686. $this->userCommands[] = $command;
  11687. return $this;
  11688. }
  11689. /**
  11690. * This method implements the Selenium RC protocol.
  11691. *
  11692. * @param string $command
  11693. * @param array $arguments
  11694. * @return mixed
  11695. * @method unknown addLocationStrategy()
  11696. * @method unknown addLocationStrategyAndWait()
  11697. * @method unknown addScript()
  11698. * @method unknown addScriptAndWait()
  11699. * @method unknown addSelection()
  11700. * @method unknown addSelectionAndWait()
  11701. * @method unknown allowNativeXpath()
  11702. * @method unknown allowNativeXpathAndWait()
  11703. * @method unknown altKeyDown()
  11704. * @method unknown altKeyDownAndWait()
  11705. * @method unknown altKeyUp()
  11706. * @method unknown altKeyUpAndWait()
  11707. * @method unknown answerOnNextPrompt()
  11708. * @method unknown assignId()
  11709. * @method unknown assignIdAndWait()
  11710. * @method unknown attachFile()
  11711. * @method unknown break()
  11712. * @method unknown captureEntirePageScreenshot()
  11713. * @method unknown captureEntirePageScreenshotAndWait()
  11714. * @method unknown captureEntirePageScreenshotToStringAndWait()
  11715. * @method unknown captureScreenshotAndWait()
  11716. * @method unknown captureScreenshotToStringAndWait()
  11717. * @method unknown check()
  11718. * @method unknown checkAndWait()
  11719. * @method unknown chooseCancelOnNextConfirmation()
  11720. * @method unknown chooseCancelOnNextConfirmationAndWait()
  11721. * @method unknown chooseOkOnNextConfirmation()
  11722. * @method unknown chooseOkOnNextConfirmationAndWait()
  11723. * @method unknown click()
  11724. * @method unknown clickAndWait()
  11725. * @method unknown clickAt()
  11726. * @method unknown clickAtAndWait()
  11727. * @method unknown close()
  11728. * @method unknown contextMenu()
  11729. * @method unknown contextMenuAndWait()
  11730. * @method unknown contextMenuAt()
  11731. * @method unknown contextMenuAtAndWait()
  11732. * @method unknown controlKeyDown()
  11733. * @method unknown controlKeyDownAndWait()
  11734. * @method unknown controlKeyUp()
  11735. * @method unknown controlKeyUpAndWait()
  11736. * @method unknown createCookie()
  11737. * @method unknown createCookieAndWait()
  11738. * @method unknown deleteAllVisibleCookies()
  11739. * @method unknown deleteAllVisibleCookiesAndWait()
  11740. * @method unknown deleteCookie()
  11741. * @method unknown deleteCookieAndWait()
  11742. * @method unknown deselectPopUp()
  11743. * @method unknown deselectPopUpAndWait()
  11744. * @method unknown doubleClick()
  11745. * @method unknown doubleClickAndWait()
  11746. * @method unknown doubleClickAt()
  11747. * @method unknown doubleClickAtAndWait()
  11748. * @method unknown dragAndDrop()
  11749. * @method unknown dragAndDropAndWait()
  11750. * @method unknown dragAndDropToObject()
  11751. * @method unknown dragAndDropToObjectAndWait()
  11752. * @method unknown dragDrop()
  11753. * @method unknown dragDropAndWait()
  11754. * @method unknown echo()
  11755. * @method unknown fireEvent()
  11756. * @method unknown fireEventAndWait()
  11757. * @method unknown focus()
  11758. * @method unknown focusAndWait()
  11759. * @method string getAlert()
  11760. * @method array getAllButtons()
  11761. * @method array getAllFields()
  11762. * @method array getAllLinks()
  11763. * @method array getAllWindowIds()
  11764. * @method array getAllWindowNames()
  11765. * @method array getAllWindowTitles()
  11766. * @method string getAttribute(string $attributeLocator)
  11767. * @method array getAttributeFromAllWindows(string $attributeName)
  11768. * @method string getBodyText()
  11769. * @method string getConfirmation()
  11770. * @method string getCookie()
  11771. * @method string getCookieByName(string $name)
  11772. * @method integer getCssCount(string $locator)
  11773. * @method integer getCursorPosition(string $locator)
  11774. * @method integer getElementHeight(string $locator)
  11775. * @method integer getElementIndex(string $locator)
  11776. * @method integer getElementPositionLeft(string $locator)
  11777. * @method integer getElementPositionTop(string $locator)
  11778. * @method integer getElementWidth(string $locator)
  11779. * @method string getEval(string $script)
  11780. * @method string getExpression(string $expression)
  11781. * @method string getHtmlSource()
  11782. * @method string getLocation()
  11783. * @method string getLogMessages()
  11784. * @method integer getMouseSpeed()
  11785. * @method string getPrompt()
  11786. * @method array getSelectOptions(string $selectLocator)
  11787. * @method string getSelectedId(string $selectLocator)
  11788. * @method array getSelectedIds(string $selectLocator)
  11789. * @method string getSelectedIndex(string $selectLocator)
  11790. * @method array getSelectedIndexes(string $selectLocator)
  11791. * @method string getSelectedLabel(string $selectLocator)
  11792. * @method array getSelectedLabels(string $selectLocator)
  11793. * @method string getSelectedValue(string $selectLocator)
  11794. * @method array getSelectedValues(string $selectLocator)
  11795. * @method unknown getSpeed()
  11796. * @method unknown getSpeedAndWait()
  11797. * @method string getTable(string $tableCellAddress)
  11798. * @method string getText(string $locator)
  11799. * @method string getTitle()
  11800. * @method string getValue(string $locator)
  11801. * @method boolean getWhetherThisFrameMatchFrameExpression(string $currentFrameString, string $target)
  11802. * @method boolean getWhetherThisWindowMatchWindowExpression(string $currentWindowString, string $target)
  11803. * @method integer getXpathCount(string $xpath)
  11804. * @method unknown goBack()
  11805. * @method unknown goBackAndWait()
  11806. * @method unknown highlight(string $locator)
  11807. * @method unknown highlightAndWait(string $locator)
  11808. * @method unknown ignoreAttributesWithoutValue(string $ignore)
  11809. * @method unknown ignoreAttributesWithoutValueAndWait(string $ignore)
  11810. * @method boolean isAlertPresent()
  11811. * @method boolean isChecked(locator)
  11812. * @method boolean isConfirmationPresent()
  11813. * @method boolean isCookiePresent(string $name)
  11814. * @method boolean isEditable(string $locator)
  11815. * @method boolean isElementPresent(string $locator)
  11816. * @method boolean isOrdered(string $locator1, string $locator2)
  11817. * @method boolean isPromptPresent()
  11818. * @method boolean isSomethingSelected(string $selectLocator)
  11819. * @method boolean isTextPresent(pattern)
  11820. * @method boolean isVisible(locator)
  11821. * @method unknown keyDown()
  11822. * @method unknown keyDownAndWait()
  11823. * @method unknown keyDownNative()
  11824. * @method unknown keyDownNativeAndWait()
  11825. * @method unknown keyPress()
  11826. * @method unknown keyPressAndWait()
  11827. * @method unknown keyPressNative()
  11828. * @method unknown keyPressNativeAndWait()
  11829. * @method unknown keyUp()
  11830. * @method unknown keyUpAndWait()
  11831. * @method unknown keyUpNative()
  11832. * @method unknown keyUpNativeAndWait()
  11833. * @method unknown metaKeyDown()
  11834. * @method unknown metaKeyDownAndWait()
  11835. * @method unknown metaKeyUp()
  11836. * @method unknown metaKeyUpAndWait()
  11837. * @method unknown mouseDown()
  11838. * @method unknown mouseDownAndWait()
  11839. * @method unknown mouseDownAt()
  11840. * @method unknown mouseDownAtAndWait()
  11841. * @method unknown mouseMove()
  11842. * @method unknown mouseMoveAndWait()
  11843. * @method unknown mouseMoveAt()
  11844. * @method unknown mouseMoveAtAndWait()
  11845. * @method unknown mouseOut()
  11846. * @method unknown mouseOutAndWait()
  11847. * @method unknown mouseOver()
  11848. * @method unknown mouseOverAndWait()
  11849. * @method unknown mouseUp()
  11850. * @method unknown mouseUpAndWait()
  11851. * @method unknown mouseUpAt()
  11852. * @method unknown mouseUpAtAndWait()
  11853. * @method unknown mouseUpRight()
  11854. * @method unknown mouseUpRightAndWait()
  11855. * @method unknown mouseUpRightAt()
  11856. * @method unknown mouseUpRightAtAndWait()
  11857. * @method unknown open()
  11858. * @method unknown openWindow()
  11859. * @method unknown openWindowAndWait()
  11860. * @method unknown pause()
  11861. * @method unknown refresh()
  11862. * @method unknown refreshAndWait()
  11863. * @method unknown removeAllSelections()
  11864. * @method unknown removeAllSelectionsAndWait()
  11865. * @method unknown removeScript()
  11866. * @method unknown removeScriptAndWait()
  11867. * @method unknown removeSelection()
  11868. * @method unknown removeSelectionAndWait()
  11869. * @method unknown retrieveLastRemoteControlLogs()
  11870. * @method unknown rollup()
  11871. * @method unknown rollupAndWait()
  11872. * @method unknown runScript()
  11873. * @method unknown runScriptAndWait()
  11874. * @method unknown select()
  11875. * @method unknown selectAndWait()
  11876. * @method unknown selectFrame()
  11877. * @method unknown selectPopUp()
  11878. * @method unknown selectPopUpAndWait()
  11879. * @method unknown selectWindow()
  11880. * @method unknown setBrowserLogLevel()
  11881. * @method unknown setBrowserLogLevelAndWait()
  11882. * @method unknown setContext()
  11883. * @method unknown setCursorPosition()
  11884. * @method unknown setCursorPositionAndWait()
  11885. * @method unknown setMouseSpeed()
  11886. * @method unknown setMouseSpeedAndWait()
  11887. * @method unknown setSpeed()
  11888. * @method unknown setSpeedAndWait()
  11889. * @method unknown shiftKeyDown()
  11890. * @method unknown shiftKeyDownAndWait()
  11891. * @method unknown shiftKeyUp()
  11892. * @method unknown shiftKeyUpAndWait()
  11893. * @method unknown shutDownSeleniumServer()
  11894. * @method unknown store()
  11895. * @method unknown submit()
  11896. * @method unknown submitAndWait()
  11897. * @method unknown type()
  11898. * @method unknown typeAndWait()
  11899. * @method unknown typeKeys()
  11900. * @method unknown typeKeysAndWait()
  11901. * @method unknown uncheck()
  11902. * @method unknown uncheckAndWait()
  11903. * @method unknown useXpathLibrary()
  11904. * @method unknown useXpathLibraryAndWait()
  11905. * @method unknown waitForCondition()
  11906. * @method unknown waitForElementPresent()
  11907. * @method unknown waitForElementNotPresent()
  11908. * @method unknown waitForPageToLoad()
  11909. * @method unknown waitForPopUp()
  11910. * @method unknown windowFocus()
  11911. * @method unknown windowMaximize()
  11912. */
  11913. public function __call($command, $arguments)
  11914. {
  11915. $arguments = $this->preprocessParameters($arguments);
  11916. $wait = FALSE;
  11917. if (substr($command, -7, 7) == 'AndWait') {
  11918. $command = substr($command, 0, -7);
  11919. $wait = TRUE;
  11920. }
  11921. switch ($command) {
  11922. case 'addLocationStrategy':
  11923. case 'addScript':
  11924. case 'addSelection':
  11925. case 'allowNativeXpath':
  11926. case 'altKeyDown':
  11927. case 'altKeyUp':
  11928. case 'answerOnNextPrompt':
  11929. case 'assignId':
  11930. case 'attachFile':
  11931. case 'break':
  11932. case 'captureEntirePageScreenshot':
  11933. case 'captureScreenshot':
  11934. case 'check':
  11935. case 'chooseCancelOnNextConfirmation':
  11936. case 'chooseOkOnNextConfirmation':
  11937. case 'click':
  11938. case 'clickAt':
  11939. case 'close':
  11940. case 'contextMenu':
  11941. case 'contextMenuAt':
  11942. case 'controlKeyDown':
  11943. case 'controlKeyUp':
  11944. case 'createCookie':
  11945. case 'deleteAllVisibleCookies':
  11946. case 'deleteCookie':
  11947. case 'deselectPopUp':
  11948. case 'doubleClick':
  11949. case 'doubleClickAt':
  11950. case 'dragAndDrop':
  11951. case 'dragAndDropToObject':
  11952. case 'dragDrop':
  11953. case 'echo':
  11954. case 'fireEvent':
  11955. case 'focus':
  11956. case 'goBack':
  11957. case 'highlight':
  11958. case 'ignoreAttributesWithoutValue':
  11959. case 'keyDown':
  11960. case 'keyDownNative':
  11961. case 'keyPress':
  11962. case 'keyPressNative':
  11963. case 'keyUp':
  11964. case 'keyUpNative':
  11965. case 'metaKeyDown':
  11966. case 'metaKeyUp':
  11967. case 'mouseDown':
  11968. case 'mouseDownAt':
  11969. case 'mouseMove':
  11970. case 'mouseMoveAt':
  11971. case 'mouseOut':
  11972. case 'mouseOver':
  11973. case 'mouseUp':
  11974. case 'mouseUpAt':
  11975. case 'mouseUpRight':
  11976. case 'mouseUpRightAt':
  11977. case 'open':
  11978. case 'openWindow':
  11979. case 'pause':
  11980. case 'refresh':
  11981. case 'removeAllSelections':
  11982. case 'removeScript':
  11983. case 'removeSelection':
  11984. case 'retrieveLastRemoteControlLogs':
  11985. case 'rollup':
  11986. case 'runScript':
  11987. case 'select':
  11988. case 'selectFrame':
  11989. case 'selectPopUp':
  11990. case 'selectWindow':
  11991. case 'setBrowserLogLevel':
  11992. case 'setContext':
  11993. case 'setCursorPosition':
  11994. case 'setMouseSpeed':
  11995. case 'setSpeed':
  11996. case 'shiftKeyDown':
  11997. case 'shiftKeyUp':
  11998. case 'shutDownSeleniumServer':
  11999. case 'store':
  12000. case 'submit':
  12001. case 'type':
  12002. case 'typeKeys':
  12003. case 'uncheck':
  12004. case 'useXpathLibrary':
  12005. case 'windowFocus':
  12006. case 'windowMaximize':
  12007. case isset(self::$autoGeneratedCommands[$command]): {
  12008. // Pre-Command Actions
  12009. switch ($command) {
  12010. case 'open':
  12011. case 'openWindow': {
  12012. if ($this->collectCodeCoverageInformation) {
  12013. $this->deleteCookie('PHPUNIT_SELENIUM_TEST_ID', 'path=/');
  12014. $this->createCookie(
  12015. 'PHPUNIT_SELENIUM_TEST_ID=' . $this->testId,
  12016. 'path=/'
  12017. );
  12018. }
  12019. }
  12020. break;
  12021. case 'store':
  12022. // store is a synonym of storeExpression
  12023. // and RC only understands storeExpression
  12024. $command = 'storeExpression';
  12025. break;
  12026. }
  12027. if (isset(self::$autoGeneratedCommands[$command]) && self::$autoGeneratedCommands[$command]['functionHelper']) {
  12028. $helperArguments = array($command, $arguments, self::$autoGeneratedCommands[$command]);
  12029. call_user_func_array(array($this, self::$autoGeneratedCommands[$command]['functionHelper']), $helperArguments);
  12030. } else {
  12031. $this->doCommand($command, $arguments);
  12032. }
  12033. // Post-Command Actions
  12034. switch ($command) {
  12035. case 'addLocationStrategy':
  12036. case 'allowNativeXpath':
  12037. case 'assignId':
  12038. case 'captureEntirePageScreenshot':
  12039. case 'captureScreenshot': {
  12040. // intentionally empty
  12041. }
  12042. break;
  12043. default: {
  12044. if ($wait) {
  12045. if ($this->useWaitForPageToLoad) {
  12046. $this->waitForPageToLoad($this->seleniumTimeout * 1000);
  12047. } else {
  12048. sleep($this->wait);
  12049. }
  12050. }
  12051. if ($this->sleep > 0) {
  12052. sleep($this->sleep);
  12053. }
  12054. $this->testCase->runDefaultAssertions($command);
  12055. }
  12056. }
  12057. }
  12058. break;
  12059. case 'getWhetherThisFrameMatchFrameExpression':
  12060. case 'getWhetherThisWindowMatchWindowExpression':
  12061. case 'isAlertPresent':
  12062. case 'isChecked':
  12063. case 'isConfirmationPresent':
  12064. case 'isCookiePresent':
  12065. case 'isEditable':
  12066. case 'isElementPresent':
  12067. case 'isOrdered':
  12068. case 'isPromptPresent':
  12069. case 'isSomethingSelected':
  12070. case 'isTextPresent':
  12071. case 'isVisible': {
  12072. return $this->getBoolean($command, $arguments);
  12073. }
  12074. break;
  12075. case 'getCssCount':
  12076. case 'getCursorPosition':
  12077. case 'getElementHeight':
  12078. case 'getElementIndex':
  12079. case 'getElementPositionLeft':
  12080. case 'getElementPositionTop':
  12081. case 'getElementWidth':
  12082. case 'getMouseSpeed':
  12083. case 'getSpeed':
  12084. case 'getXpathCount': {
  12085. $result = $this->getNumber($command, $arguments);
  12086. if ($wait) {
  12087. $this->waitForPageToLoad($this->seleniumTimeout * 1000);
  12088. }
  12089. return $result;
  12090. }
  12091. break;
  12092. case 'getAlert':
  12093. case 'getAttribute':
  12094. case 'getBodyText':
  12095. case 'getConfirmation':
  12096. case 'getCookie':
  12097. case 'getCookieByName':
  12098. case 'getEval':
  12099. case 'getExpression':
  12100. case 'getHtmlSource':
  12101. case 'getLocation':
  12102. case 'getLogMessages':
  12103. case 'getPrompt':
  12104. case 'getSelectedId':
  12105. case 'getSelectedIndex':
  12106. case 'getSelectedLabel':
  12107. case 'getSelectedValue':
  12108. case 'getTable':
  12109. case 'getText':
  12110. case 'getTitle':
  12111. case 'captureEntirePageScreenshotToString':
  12112. case 'captureScreenshotToString':
  12113. case 'getValue': {
  12114. $result = $this->getString($command, $arguments);
  12115. if ($wait) {
  12116. $this->waitForPageToLoad($this->seleniumTimeout * 1000);
  12117. }
  12118. return $result;
  12119. }
  12120. break;
  12121. case 'getAllButtons':
  12122. case 'getAllFields':
  12123. case 'getAllLinks':
  12124. case 'getAllWindowIds':
  12125. case 'getAllWindowNames':
  12126. case 'getAllWindowTitles':
  12127. case 'getAttributeFromAllWindows':
  12128. case 'getSelectedIds':
  12129. case 'getSelectedIndexes':
  12130. case 'getSelectedLabels':
  12131. case 'getSelectedValues':
  12132. case 'getSelectOptions': {
  12133. $result = $this->getStringArray($command, $arguments);
  12134. if ($wait) {
  12135. $this->waitForPageToLoad($this->seleniumTimeout * 1000);
  12136. }
  12137. return $result;
  12138. }
  12139. break;
  12140. case 'waitForCondition':
  12141. case 'waitForElementPresent':
  12142. case 'waitForElementNotPresent':
  12143. case 'waitForFrameToLoad':
  12144. case 'waitForPopUp': {
  12145. if (count($arguments) == 1) {
  12146. $arguments[] = $this->seleniumTimeout * 1000;
  12147. }
  12148. $this->doCommand($command, $arguments);
  12149. $this->testCase->runDefaultAssertions($command);
  12150. }
  12151. break;
  12152. case 'waitForPageToLoad': {
  12153. if (empty($arguments)) {
  12154. $arguments[] = $this->seleniumTimeout * 1000;
  12155. }
  12156. $this->doCommand($command, $arguments);
  12157. $this->testCase->runDefaultAssertions($command);
  12158. }
  12159. break;
  12160. default: {
  12161. if (!in_array($command, $this->userCommands)) {
  12162. throw new BadMethodCallException(
  12163. "Method $command not defined."
  12164. );
  12165. }
  12166. $this->doCommand($command, $arguments);
  12167. }
  12168. }
  12169. }
  12170. /**
  12171. * Send a command to the Selenium RC server.
  12172. *
  12173. * @param string $command
  12174. * @param array $arguments
  12175. * @param array $namedArguments
  12176. * @return string
  12177. * @author Seth Casana <totallymeat@gmail.org>
  12178. */
  12179. protected function doCommand($command, array $arguments = array(), array $namedArguments = array())
  12180. {
  12181. $url = sprintf(
  12182. 'http://%s:%s/selenium-server/driver/',
  12183. $this->host,
  12184. $this->port
  12185. );
  12186. $numArguments = count($arguments);
  12187. $postData = sprintf('cmd=%s', urlencode($command));
  12188. for ($i = 0; $i < $numArguments; $i++) {
  12189. $argNum = strval($i + 1);
  12190. if ($arguments[$i] == ' ') {
  12191. $postData .= sprintf('&%s=%s', $argNum, urlencode($arguments[$i]));
  12192. } else {
  12193. $postData .= sprintf('&%s=%s', $argNum, urlencode(trim($arguments[$i])));
  12194. }
  12195. }
  12196. foreach ($namedArguments as $key => $value) {
  12197. $postData .= sprintf('&%s=%s', $key, urlencode($value));
  12198. }
  12199. if (isset($this->sessionId)) {
  12200. $postData .= sprintf('&%s=%s', 'sessionId', $this->sessionId);
  12201. }
  12202. $curl = curl_init();
  12203. curl_setopt($curl, CURLOPT_URL, $url);
  12204. curl_setopt($curl, CURLOPT_HEADER, 0);
  12205. curl_setopt($curl, CURLOPT_POST, TRUE);
  12206. curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
  12207. curl_setopt($curl, CURLOPT_HTTPHEADER, array(
  12208. 'Content-Type: application/x-www-form-urlencoded; charset=utf-8'
  12209. ));
  12210. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  12211. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
  12212. $response = curl_exec($curl);
  12213. $info = curl_getinfo($curl);
  12214. if (!$response) {
  12215. throw new RuntimeException("CURL error while accessing the Selenium Server at '$url': " . curl_error($curl));
  12216. }
  12217. curl_close($curl);
  12218. if (!preg_match('/^OK/', $response)) {
  12219. throw new RuntimeException("Invalid response while accessing the Selenium Server at '$url': " . $response);
  12220. }
  12221. if ($info['http_code'] != 200) {
  12222. throw new RuntimeException(
  12223. 'The response from the Selenium RC server is invalid: ' .
  12224. $response
  12225. );
  12226. }
  12227. return $response;
  12228. }
  12229. protected function preprocessParameters($params)
  12230. {
  12231. foreach ($params as $key => $param ) {
  12232. if (is_string($param) && (strlen($param) > 0)) {
  12233. $params[$key] = $this->getString('getExpression', array($param));
  12234. }
  12235. }
  12236. return $params;
  12237. }
  12238. /**
  12239. * Send a command to the Selenium RC server and treat the result
  12240. * as a boolean.
  12241. *
  12242. * @param string $command
  12243. * @param array $arguments
  12244. * @return boolean
  12245. * @author Shin Ohno <ganchiku@gmail.com>
  12246. * @author Bjoern Schotte <schotte@mayflower.de>
  12247. */
  12248. protected function getBoolean($command, array $arguments)
  12249. {
  12250. $result = $this->getString($command, $arguments);
  12251. switch ($result) {
  12252. case 'true': return TRUE;
  12253. case 'false': return FALSE;
  12254. default: {
  12255. throw new PHPUnit_Framework_Exception(
  12256. 'Result is neither "true" nor "false": ' . PHPUnit_Util_Type::export($result)
  12257. );
  12258. }
  12259. }
  12260. }
  12261. /**
  12262. * Send a command to the Selenium RC server and treat the result
  12263. * as a number.
  12264. *
  12265. * @param string $command
  12266. * @param array $arguments
  12267. * @return numeric
  12268. * @author Shin Ohno <ganchiku@gmail.com>
  12269. * @author Bjoern Schotte <schotte@mayflower.de>
  12270. */
  12271. protected function getNumber($command, array $arguments)
  12272. {
  12273. $result = $this->getString($command, $arguments);
  12274. if (!is_numeric($result)) {
  12275. throw new PHPUnit_Framework_Exception(
  12276. 'Result is not numeric: ' . PHPUnit_Util_Type::export($result)
  12277. );
  12278. }
  12279. return $result;
  12280. }
  12281. /**
  12282. * Send a command to the Selenium RC server and treat the result
  12283. * as a string.
  12284. *
  12285. * @param string $command
  12286. * @param array $arguments
  12287. * @return string
  12288. * @author Shin Ohno <ganchiku@gmail.com>
  12289. * @author Bjoern Schotte <schotte@mayflower.de>
  12290. */
  12291. protected function getString($command, array $arguments)
  12292. {
  12293. try {
  12294. $result = $this->doCommand($command, $arguments);
  12295. }
  12296. catch (RuntimeException $e) {
  12297. throw $e;
  12298. }
  12299. return (strlen($result) > 3) ? substr($result, 3) : '';
  12300. }
  12301. /**
  12302. * Send a command to the Selenium RC server and treat the result
  12303. * as an array of strings.
  12304. *
  12305. * @param string $command
  12306. * @param array $arguments
  12307. * @return array
  12308. * @author Shin Ohno <ganchiku@gmail.com>
  12309. * @author Bjoern Schotte <schotte@mayflower.de>
  12310. */
  12311. protected function getStringArray($command, array $arguments)
  12312. {
  12313. $csv = $this->getString($command, $arguments);
  12314. $token = '';
  12315. $tokens = array();
  12316. $letters = preg_split('//', $csv, -1, PREG_SPLIT_NO_EMPTY);
  12317. $count = count($letters);
  12318. for ($i = 0; $i < $count; $i++) {
  12319. $letter = $letters[$i];
  12320. switch($letter) {
  12321. case '\\': {
  12322. $letter = $letters[++$i];
  12323. $token .= $letter;
  12324. }
  12325. break;
  12326. case ',': {
  12327. $tokens[] = $token;
  12328. $token = '';
  12329. }
  12330. break;
  12331. default: {
  12332. $token .= $letter;
  12333. }
  12334. }
  12335. }
  12336. $tokens[] = $token;
  12337. return $tokens;
  12338. }
  12339. public function getVerificationErrors()
  12340. {
  12341. return $this->verificationErrors;
  12342. }
  12343. public function clearVerificationErrors()
  12344. {
  12345. $this->verificationErrors = array();
  12346. }
  12347. protected function assertCommand($command, $arguments, $info)
  12348. {
  12349. $method = $info['originalMethod'];
  12350. $requiresTarget = $info['requiresTarget'];
  12351. $result = $this->__call($method, $arguments);
  12352. $message = "Failed command: " . $command . "('"
  12353. . (array_key_exists(0, $arguments) ? $arguments[0] . "'" : '')
  12354. . (array_key_exists(1, $arguments) ? ", '" . $arguments[1] . "'" : '')
  12355. . ")";
  12356. if ($info['isBoolean']) {
  12357. if (!isset($info['negative']) || !$info['negative']) {
  12358. PHPUnit_Framework_Assert::assertTrue($result, $message);
  12359. } else {
  12360. PHPUnit_Framework_Assert::assertFalse($result, $message);
  12361. }
  12362. } else {
  12363. if ($requiresTarget === TRUE) {
  12364. $expected = $arguments[1];
  12365. } else {
  12366. $expected = $arguments[0];
  12367. }
  12368. if (strpos($expected, 'exact:') === 0) {
  12369. $expected = substr($expected, strlen('exact:'));
  12370. if (!isset($info['negative']) || !$info['negative']) {
  12371. PHPUnit_Framework_Assert::assertEquals($expected, $result, $message);
  12372. } else {
  12373. PHPUnit_Framework_Assert::assertNotEquals($expected, $result, $message);
  12374. }
  12375. } else {
  12376. $caseInsensitive = FALSE;
  12377. if (strpos($expected, 'regexp:') === 0) {
  12378. $expected = substr($expected, strlen('regexp:'));
  12379. }
  12380. else if (strpos($expected, 'regexpi:') === 0) {
  12381. $expected = substr($expected, strlen('regexpi:'));
  12382. $caseInsensitive = TRUE;
  12383. }
  12384. else {
  12385. if (strpos($expected, 'glob:') === 0) {
  12386. $expected = substr($expected, strlen('glob:'));
  12387. }
  12388. $expected = '^' . str_replace(
  12389. array('*', '?'), array('.*', '.?'), $expected
  12390. ) . '$';
  12391. }
  12392. $expected = '/' . str_replace('/', '\/', $expected) . '/';
  12393. if ($caseInsensitive) {
  12394. $expected .= 'i';
  12395. }
  12396. if (!isset($info['negative']) || !$info['negative']) {
  12397. PHPUnit_Framework_Assert::assertRegExp(
  12398. $expected, $result, $message
  12399. );
  12400. } else {
  12401. PHPUnit_Framework_Assert::assertNotRegExp(
  12402. $expected, $result, $message
  12403. );
  12404. }
  12405. }
  12406. }
  12407. }
  12408. protected function verifyCommand($command, $arguments, $info)
  12409. {
  12410. try {
  12411. $this->assertCommand($command, $arguments, $info);
  12412. }
  12413. catch (PHPUnit_Framework_AssertionFailedError $e) {
  12414. array_push($this->verificationErrors, $e->toString());
  12415. }
  12416. }
  12417. protected function waitForCommand($command, $arguments, $info)
  12418. {
  12419. $lastExceptionMessage = '';
  12420. for ($second = 0; ; $second++) {
  12421. if ($second > $this->httpTimeout) {
  12422. PHPUnit_Framework_Assert::fail(
  12423. "WaitFor timeout. \n"
  12424. . "Last exception message: \n" . $lastExceptionMessage
  12425. );
  12426. }
  12427. try {
  12428. $this->assertCommand($command, $arguments, $info);
  12429. return;
  12430. }
  12431. catch (Exception $e) {
  12432. $lastExceptionMessage = $e->getMessage();
  12433. }
  12434. sleep(1);
  12435. }
  12436. }
  12437. /**
  12438. * Parses the docblock of PHPUnit_Extensions_SeleniumTestCase_Driver::__call
  12439. * for get*(), is*(), assert*(), verify*(), assertNot*(), verifyNot*(),
  12440. * store*(), waitFor*(), and waitForNot*() methods.
  12441. */
  12442. protected static function autoGenerateCommands()
  12443. {
  12444. $method = new ReflectionMethod(__CLASS__, '__call');
  12445. $docComment = $method->getDocComment();
  12446. if (preg_match_all('(@method\s+(\w+)\s+([\w]+)\((.*)\))', $docComment, $matches)) {
  12447. foreach ($matches[2] as $methodKey => $method) {
  12448. if (preg_match('/^(get|is)([A-Z].+)$/', $method, $methodMatches)) {
  12449. $baseName = $methodMatches[2];
  12450. $isBoolean = $methodMatches[1] == 'is';
  12451. $requiresTarget = (strlen($matches[3][$methodKey]) > 0);
  12452. if (preg_match('/^(.*)Present$/', $baseName, $methodMatches)) {
  12453. $notBaseName = $methodMatches[1] . 'NotPresent';
  12454. } else {
  12455. $notBaseName = 'Not' . $baseName;
  12456. }
  12457. self::$autoGeneratedCommands['store' . $baseName] = array(
  12458. 'functionHelper' => FALSE
  12459. );
  12460. self::$autoGeneratedCommands['assert' . $baseName] = array(
  12461. 'originalMethod' => $method,
  12462. 'isBoolean' => $isBoolean,
  12463. 'functionHelper' => 'assertCommand',
  12464. 'requiresTarget' => $requiresTarget
  12465. );
  12466. self::$autoGeneratedCommands['assert' . $notBaseName] = array(
  12467. 'originalMethod' => $method,
  12468. 'isBoolean' => $isBoolean,
  12469. 'negative' => TRUE,
  12470. 'functionHelper' => 'assertCommand',
  12471. 'requiresTarget' => $requiresTarget
  12472. );
  12473. self::$autoGeneratedCommands['verify' . $baseName] = array(
  12474. 'originalMethod' => $method,
  12475. 'isBoolean' => $isBoolean,
  12476. 'functionHelper' => 'verifyCommand',
  12477. 'requiresTarget' => $requiresTarget
  12478. );
  12479. self::$autoGeneratedCommands['verify' . $notBaseName] = array(
  12480. 'originalMethod' => $method,
  12481. 'isBoolean' => $isBoolean,
  12482. 'negative' => TRUE,
  12483. 'functionHelper' => 'verifyCommand',
  12484. 'requiresTarget' => $requiresTarget
  12485. );
  12486. self::$autoGeneratedCommands['waitFor' . $baseName] = array(
  12487. 'originalMethod' => $method,
  12488. 'isBoolean' => $isBoolean,
  12489. 'functionHelper' => 'waitForCommand',
  12490. 'requiresTarget' => $requiresTarget
  12491. );
  12492. self::$autoGeneratedCommands['waitFor' . $notBaseName] = array(
  12493. 'originalMethod' => $method,
  12494. 'isBoolean' => $isBoolean,
  12495. 'negative' => TRUE,
  12496. 'functionHelper' => 'waitForCommand',
  12497. 'requiresTarget' => $requiresTarget
  12498. );
  12499. }
  12500. }
  12501. }
  12502. }
  12503. }
  12504. <?php
  12505. /**
  12506. * PHPUnit
  12507. *
  12508. * Copyright (c) 2010-2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
  12509. * All rights reserved.
  12510. *
  12511. * Redistribution and use in source and binary forms, with or without
  12512. * modification, are permitted provided that the following conditions
  12513. * are met:
  12514. *
  12515. * * Redistributions of source code must retain the above copyright
  12516. * notice, this list of conditions and the following disclaimer.
  12517. *
  12518. * * Redistributions in binary form must reproduce the above copyright
  12519. * notice, this list of conditions and the following disclaimer in
  12520. * the documentation and/or other materials provided with the
  12521. * distribution.
  12522. *
  12523. * * Neither the name of Sebastian Bergmann nor the names of his
  12524. * contributors may be used to endorse or promote products derived
  12525. * from this software without specific prior written permission.
  12526. *
  12527. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12528. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12529. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12530. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12531. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12532. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12533. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12534. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12535. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12536. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12537. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12538. * POSSIBILITY OF SUCH DAMAGE.
  12539. *
  12540. * @package PHPUnit_Selenium
  12541. * @author Ivan Kurnosov <zerkms@zerkms.com>
  12542. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  12543. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12544. * @link http://www.phpunit.de/
  12545. * @since File available since Release 1.2.12
  12546. */
  12547. /**
  12548. * Class to hold the special keys Unicode entities
  12549. *
  12550. * @package PHPUnit_Selenium
  12551. * @author Ivan Kurnosov <zerkms@zerkms.com>
  12552. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  12553. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12554. * @version Release: @package_version@
  12555. * @link http://www.phpunit.de/
  12556. * @since Class available since Release 1.3.0
  12557. * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value
  12558. */
  12559. class PHPUnit_Extensions_Selenium2TestCase_Keys
  12560. {
  12561. const NULL = "\xEE\x80\x80";
  12562. const CANCEL = "\xEE\x80\x81";
  12563. const HELP = "\xEE\x80\x82";
  12564. const BACKSPACE = "\xEE\x80\x83";
  12565. const TAB = "\xEE\x80\x84";
  12566. const CLEAR = "\xEE\x80\x85";
  12567. const RETURN_ = "\xEE\x80\x86";
  12568. const ENTER = "\xEE\x80\x87";
  12569. const SHIFT = "\xEE\x80\x88";
  12570. const CONTROL = "\xEE\x80\x89";
  12571. const ALT = "\xEE\x80\x8A";
  12572. const PAUSE = "\xEE\x80\x8B";
  12573. const ESCAPE = "\xEE\x80\x8C";
  12574. const SPACE = "\xEE\x80\x8D";
  12575. const PAGEUP = "\xEE\x80\x8E";
  12576. const PAGEDOWN = "\xEE\x80\x8F";
  12577. const END = "\xEE\x80\x90";
  12578. const HOME = "\xEE\x80\x91";
  12579. const LEFT = "\xEE\x80\x92";
  12580. const UP = "\xEE\x80\x93";
  12581. const RIGHT = "\xEE\x80\x94";
  12582. const DOWN = "\xEE\x80\x95";
  12583. const INSERT = "\xEE\x80\x96";
  12584. const DELETE = "\xEE\x80\x97";
  12585. const SEMICOLON = "\xEE\x80\x98";
  12586. const EQUALS = "\xEE\x80\x99";
  12587. const NUMPAD0 = "\xEE\x80\x9A";
  12588. const NUMPAD1 = "\xEE\x80\x9B";
  12589. const NUMPAD2 = "\xEE\x80\x9C";
  12590. const NUMPAD3 = "\xEE\x80\x9D";
  12591. const NUMPAD4 = "\xEE\x80\x9E";
  12592. const NUMPAD5 = "\xEE\x80\x9F";
  12593. const NUMPAD6 = "\xEE\x80\xA0";
  12594. const NUMPAD7 = "\xEE\x80\xA1";
  12595. const NUMPAD8 = "\xEE\x80\xA2";
  12596. const NUMPAD9 = "\xEE\x80\xA3";
  12597. const MULTIPLY = "\xEE\x80\xA4";
  12598. const ADD = "\xEE\x80\xA5";
  12599. const SEPARATOR = "\xEE\x80\xA6";
  12600. const SUBTRACT = "\xEE\x80\xA7";
  12601. const DECIMAL = "\xEE\x80\xA8";
  12602. const DIVIDE = "\xEE\x80\xA9";
  12603. const F1 = "\xEE\x80\xB1";
  12604. const F2 = "\xEE\x80\xB2";
  12605. const F3 = "\xEE\x80\xB3";
  12606. const F4 = "\xEE\x80\xB4";
  12607. const F5 = "\xEE\x80\xB5";
  12608. const F6 = "\xEE\x80\xB6";
  12609. const F7 = "\xEE\x80\xB7";
  12610. const F8 = "\xEE\x80\xB8";
  12611. const F9 = "\xEE\x80\xB9";
  12612. const F10 = "\xEE\x80\xBA";
  12613. const F11 = "\xEE\x80\xBB";
  12614. const F12 = "\xEE\x80\xBC";
  12615. const COMMAND = "\xEE\x80\xBD";
  12616. }
  12617. <?php
  12618. /**
  12619. * PHPUnit
  12620. *
  12621. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  12622. * All rights reserved.
  12623. *
  12624. * Redistribution and use in source and binary forms, with or without
  12625. * modification, are permitted provided that the following conditions
  12626. * are met:
  12627. *
  12628. * * Redistributions of source code must retain the above copyright
  12629. * notice, this list of conditions and the following disclaimer.
  12630. *
  12631. * * Redistributions in binary form must reproduce the above copyright
  12632. * notice, this list of conditions and the following disclaimer in
  12633. * the documentation and/or other materials provided with the
  12634. * distribution.
  12635. *
  12636. * * Neither the name of Sebastian Bergmann nor the names of his
  12637. * contributors may be used to endorse or promote products derived
  12638. * from this software without specific prior written permission.
  12639. *
  12640. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12641. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12642. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12643. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12644. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12645. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12646. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12647. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12648. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12649. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12650. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12651. * POSSIBILITY OF SUCH DAMAGE.
  12652. *
  12653. * @package PHPUnit_Selenium
  12654. * @author Giorgio Sironi <info@giorgiosironi.com>
  12655. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12656. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12657. * @link http://www.phpunit.de/
  12658. * @since File available since Release 1.2.6
  12659. */
  12660. /**
  12661. * Adds a cookie.
  12662. *
  12663. * @package PHPUnit_Selenium
  12664. * @author Giorgio Sironi <info@giorgiosironi.com>
  12665. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12666. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12667. * @version Release: @package_version@
  12668. * @link http://www.phpunit.de/
  12669. * @since Class available since Release 1.2.6
  12670. */
  12671. class PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
  12672. {
  12673. private $name;
  12674. private $value;
  12675. private $path;
  12676. private $domain;
  12677. private $secure = FALSE;
  12678. private $expiry;
  12679. public function __construct($cookieFacade, $name, $value)
  12680. {
  12681. $this->cookieFacade = $cookieFacade;
  12682. $this->name = $name;
  12683. $this->value = $value;
  12684. }
  12685. /**
  12686. * @param string
  12687. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
  12688. */
  12689. public function path($path)
  12690. {
  12691. $this->path = $path;
  12692. return $this;
  12693. }
  12694. /**
  12695. * @param string
  12696. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
  12697. */
  12698. public function domain($domain)
  12699. {
  12700. $this->domain = $domain;
  12701. return $this;
  12702. }
  12703. /**
  12704. * @param boolean
  12705. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
  12706. */
  12707. public function secure($secure)
  12708. {
  12709. $this->secure = $secure;
  12710. return $this;
  12711. }
  12712. /**
  12713. * @param integer
  12714. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
  12715. */
  12716. public function expiry($expiry)
  12717. {
  12718. $this->expiry = $expiry;
  12719. return $this;
  12720. }
  12721. /**
  12722. * @return void
  12723. */
  12724. public function set()
  12725. {
  12726. $cookieData = array(
  12727. 'name' => $this->name,
  12728. 'value' => $this->value,
  12729. 'secure' => $this->secure,
  12730. );
  12731. foreach (array('path', 'domain', 'expiry') as $parameter) {
  12732. if ($this->$parameter !== NULL) {
  12733. $cookieData[$parameter] = $this->$parameter;
  12734. }
  12735. }
  12736. $this->cookieFacade->postCookie($cookieData);
  12737. }
  12738. }
  12739. <?php
  12740. /**
  12741. * PHPUnit
  12742. *
  12743. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  12744. * All rights reserved.
  12745. *
  12746. * Redistribution and use in source and binary forms, with or without
  12747. * modification, are permitted provided that the following conditions
  12748. * are met:
  12749. *
  12750. * * Redistributions of source code must retain the above copyright
  12751. * notice, this list of conditions and the following disclaimer.
  12752. *
  12753. * * Redistributions in binary form must reproduce the above copyright
  12754. * notice, this list of conditions and the following disclaimer in
  12755. * the documentation and/or other materials provided with the
  12756. * distribution.
  12757. *
  12758. * * Neither the name of Sebastian Bergmann nor the names of his
  12759. * contributors may be used to endorse or promote products derived
  12760. * from this software without specific prior written permission.
  12761. *
  12762. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12763. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12764. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12765. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12766. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12767. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12768. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12769. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12770. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12771. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12772. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12773. * POSSIBILITY OF SUCH DAMAGE.
  12774. *
  12775. * @package PHPUnit_Selenium
  12776. * @author Giorgio Sironi <info@giorgiosironi.com>
  12777. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12778. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12779. * @link http://www.phpunit.de/
  12780. * @since File available since Release 1.2.4
  12781. */
  12782. /**
  12783. * Manages timeouts for the current browser session.
  12784. *
  12785. * @package PHPUnit_Selenium
  12786. * @author Giorgio Sironi <info@giorgiosironi.com>
  12787. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12788. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12789. * @version Release: @package_version@
  12790. * @link http://www.phpunit.de/
  12791. * @since Class available since Release 1.2.4
  12792. * @method implicitWait(int $ms) Sets timeout when searching for elements
  12793. * @method asyncScript(int $ms) Sets timeout for asynchronous scripts executed by Session::executeAsync()
  12794. */
  12795. class PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts
  12796. extends PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
  12797. {
  12798. private $maximumTimeout;
  12799. private $lastImplicitWaitValue = 0;
  12800. public function __construct($driver,
  12801. PHPUnit_Extensions_Selenium2TestCase_URL $url,
  12802. $maximumTimeout)
  12803. {
  12804. parent::__construct($driver, $url);
  12805. $this->maximumTimeout = $maximumTimeout;
  12806. }
  12807. protected function initCommands()
  12808. {
  12809. $self = $this;
  12810. return array(
  12811. 'implicitWait' => function ($milliseconds, $commandUrl) use ($self) {
  12812. $self->check($milliseconds);
  12813. $self->setLastImplicitWaitValue($milliseconds);
  12814. $jsonParameters = array('ms' => $milliseconds);
  12815. return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $commandUrl);
  12816. },
  12817. 'asyncScript' => function ($milliseconds, $commandUrl) use ($self) {
  12818. $self->check($milliseconds);
  12819. $jsonParameters = array('ms' => $milliseconds);
  12820. return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $commandUrl);
  12821. },
  12822. );
  12823. }
  12824. public function setLastImplicitWaitValue($implicitWait)
  12825. {
  12826. $this->lastImplicitWaitValue = $implicitWait;
  12827. }
  12828. public function getLastImplicitWaitValue()
  12829. {
  12830. return $this->lastImplicitWaitValue;
  12831. }
  12832. public function check($timeout)
  12833. {
  12834. if ($timeout > $this->maximumTimeout) {
  12835. throw new PHPUnit_Extensions_Selenium2TestCase_Exception('There is no use in setting this timeout unless you also call $this->setSeleniumServerRequestsTimeout($seconds) in setUp().');
  12836. }
  12837. }
  12838. }
  12839. <?php
  12840. /**
  12841. * PHPUnit
  12842. *
  12843. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  12844. * All rights reserved.
  12845. *
  12846. * Redistribution and use in source and binary forms, with or without
  12847. * modification, are permitted provided that the following conditions
  12848. * are met:
  12849. *
  12850. * * Redistributions of source code must retain the above copyright
  12851. * notice, this list of conditions and the following disclaimer.
  12852. *
  12853. * * Redistributions in binary form must reproduce the above copyright
  12854. * notice, this list of conditions and the following disclaimer in
  12855. * the documentation and/or other materials provided with the
  12856. * distribution.
  12857. *
  12858. * * Neither the name of Sebastian Bergmann nor the names of his
  12859. * contributors may be used to endorse or promote products derived
  12860. * from this software without specific prior written permission.
  12861. *
  12862. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12863. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12864. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12865. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12866. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12867. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12868. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12869. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12870. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12871. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12872. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12873. * POSSIBILITY OF SUCH DAMAGE.
  12874. *
  12875. * @package PHPUnit_Selenium
  12876. * @author Giorgio Sironi <info@giorgiosironi.com>
  12877. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12878. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12879. * @link http://www.phpunit.de/
  12880. * @since File available since Release 1.2.6
  12881. */
  12882. /**
  12883. * Manage the local storage HTML 5 database.
  12884. *
  12885. * @package PHPUnit_Selenium
  12886. * @author Giorgio Sironi <info@giorgiosironi.com>
  12887. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12888. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12889. * @version Release: @package_version@
  12890. * @link http://www.phpunit.de/
  12891. * @since Class available since Release 1.2.6
  12892. */
  12893. class PHPUnit_Extensions_Selenium2TestCase_Session_Storage
  12894. {
  12895. private $driver;
  12896. private $url;
  12897. public function __construct(PHPUnit_Extensions_Selenium2TestCase_Driver $driver,
  12898. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  12899. {
  12900. $this->driver = $driver;
  12901. $this->url = $url;
  12902. }
  12903. public function __set($name, $value)
  12904. {
  12905. $this->driver->curl('POST', $this->url, array(
  12906. 'key' => $name,
  12907. 'value' => (string)$value
  12908. ));
  12909. }
  12910. public function __get($name)
  12911. {
  12912. return $this->driver->curl(
  12913. 'GET',
  12914. $this->url->descend('key')->descend($name)
  12915. )->getValue();
  12916. }
  12917. }
  12918. <?php
  12919. /**
  12920. * PHPUnit
  12921. *
  12922. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  12923. * All rights reserved.
  12924. *
  12925. * Redistribution and use in source and binary forms, with or without
  12926. * modification, are permitted provided that the following conditions
  12927. * are met:
  12928. *
  12929. * * Redistributions of source code must retain the above copyright
  12930. * notice, this list of conditions and the following disclaimer.
  12931. *
  12932. * * Redistributions in binary form must reproduce the above copyright
  12933. * notice, this list of conditions and the following disclaimer in
  12934. * the documentation and/or other materials provided with the
  12935. * distribution.
  12936. *
  12937. * * Neither the name of Sebastian Bergmann nor the names of his
  12938. * contributors may be used to endorse or promote products derived
  12939. * from this software without specific prior written permission.
  12940. *
  12941. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12942. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12943. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12944. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12945. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12946. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12947. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12948. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12949. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12950. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12951. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12952. * POSSIBILITY OF SUCH DAMAGE.
  12953. *
  12954. * @package PHPUnit_Selenium
  12955. * @author Giorgio Sironi <info@giorgiosironi.com>
  12956. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12957. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12958. * @link http://www.phpunit.de/
  12959. * @since File available since Release 1.2.6
  12960. */
  12961. /**
  12962. * Adds and remove cookies.
  12963. *
  12964. * @package PHPUnit_Selenium
  12965. * @author Giorgio Sironi <info@giorgiosironi.com>
  12966. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12967. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12968. * @version Release: @package_version@
  12969. * @link http://www.phpunit.de/
  12970. * @since Class available since Release 1.2.6
  12971. */
  12972. class PHPUnit_Extensions_Selenium2TestCase_Session_Cookie
  12973. {
  12974. private $driver;
  12975. private $url;
  12976. public function __construct(PHPUnit_Extensions_Selenium2TestCase_Driver $driver,
  12977. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  12978. {
  12979. $this->driver = $driver;
  12980. $this->url = $url;
  12981. }
  12982. /**
  12983. * @param string $name
  12984. * @param string $value
  12985. * @return void
  12986. */
  12987. public function add($name, $value)
  12988. {
  12989. return new PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder($this, $name, $value);
  12990. }
  12991. /**
  12992. * @param string $name
  12993. * @return string
  12994. */
  12995. public function get($name)
  12996. {
  12997. $cookies = $this->driver->curl('GET', $this->url)->getValue();
  12998. foreach ($cookies as $cookie) {
  12999. if ($cookie['name'] == $name) {
  13000. return $cookie['value'];
  13001. }
  13002. }
  13003. throw new PHPUnit_Extensions_Selenium2TestCase_Exception("There is no '$name' cookie available on this page.");
  13004. }
  13005. /**
  13006. * @param string $name
  13007. * @return void
  13008. */
  13009. public function remove($name)
  13010. {
  13011. $url = $this->url->descend($name);
  13012. $this->driver->curl('DELETE', $url);
  13013. }
  13014. /**
  13015. * @return void
  13016. */
  13017. public function clear()
  13018. {
  13019. $this->driver->curl('DELETE', $this->url);
  13020. }
  13021. /**
  13022. * @internal
  13023. * @param array $data
  13024. * @return void
  13025. */
  13026. public function postCookie(array $data)
  13027. {
  13028. $this->driver->curl('POST',
  13029. $this->url,
  13030. array(
  13031. 'cookie' => $data
  13032. ));
  13033. }
  13034. }
  13035. <?php
  13036. /**
  13037. * PHPUnit
  13038. *
  13039. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13040. * All rights reserved.
  13041. *
  13042. * Redistribution and use in source and binary forms, with or without
  13043. * modification, are permitted provided that the following conditions
  13044. * are met:
  13045. *
  13046. * * Redistributions of source code must retain the above copyright
  13047. * notice, this list of conditions and the following disclaimer.
  13048. *
  13049. * * Redistributions in binary form must reproduce the above copyright
  13050. * notice, this list of conditions and the following disclaimer in
  13051. * the documentation and/or other materials provided with the
  13052. * distribution.
  13053. *
  13054. * * Neither the name of Sebastian Bergmann nor the names of his
  13055. * contributors may be used to endorse or promote products derived
  13056. * from this software without specific prior written permission.
  13057. *
  13058. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13059. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13060. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13061. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13062. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13063. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13064. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13065. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13066. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13067. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13068. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13069. * POSSIBILITY OF SUCH DAMAGE.
  13070. *
  13071. * @package PHPUnit_Selenium
  13072. * @author Giorgio Sironi <info@giorgiosironi.com>
  13073. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13074. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13075. * @link http://www.phpunit.de/
  13076. * @since File available since Release 1.2.6
  13077. */
  13078. /**
  13079. * Indicates an exception during the execution of Selenium 2 commands.
  13080. *
  13081. * @package PHPUnit_Selenium
  13082. * @author Giorgio Sironi <info@giorgiosironi.com>
  13083. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13084. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13085. * @version Release: @package_version@
  13086. * @link http://www.phpunit.de/
  13087. * @since Class available since Release 1.2.6
  13088. */
  13089. class PHPUnit_Extensions_Selenium2TestCase_Exception extends RuntimeException
  13090. {
  13091. }
  13092. <?php
  13093. /**
  13094. * PHPUnit
  13095. *
  13096. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13097. * All rights reserved.
  13098. *
  13099. * Redistribution and use in source and binary forms, with or without
  13100. * modification, are permitted provided that the following conditions
  13101. * are met:
  13102. *
  13103. * * Redistributions of source code must retain the above copyright
  13104. * notice, this list of conditions and the following disclaimer.
  13105. *
  13106. * * Redistributions in binary form must reproduce the above copyright
  13107. * notice, this list of conditions and the following disclaimer in
  13108. * the documentation and/or other materials provided with the
  13109. * distribution.
  13110. *
  13111. * * Neither the name of Sebastian Bergmann nor the names of his
  13112. * contributors may be used to endorse or promote products derived
  13113. * from this software without specific prior written permission.
  13114. *
  13115. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13116. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13117. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13118. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13119. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13120. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13121. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13122. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13123. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13124. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13125. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13126. * POSSIBILITY OF SUCH DAMAGE.
  13127. *
  13128. * @package PHPUnit_Selenium
  13129. * @author Giorgio Sironi <info@giorgiosironi.com>
  13130. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13131. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13132. * @link http://www.phpunit.de/
  13133. * @since File available since Release 1.2.4
  13134. */
  13135. /**
  13136. * Object representing elements, or everything that may have subcommands.
  13137. *
  13138. * @package PHPUnit_Selenium
  13139. * @author Giorgio Sironi <info@giorgiosironi.com>
  13140. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13141. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13142. * @version Release: @package_version@
  13143. * @link http://www.phpunit.de/
  13144. * @since Class available since Release 1.2.4
  13145. */
  13146. abstract class PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
  13147. {
  13148. /**
  13149. * @var PHPUnit_Extensions_Selenium2TestCase_Driver
  13150. */
  13151. protected $driver;
  13152. /**
  13153. * @var string the API URL for this element,
  13154. */
  13155. protected $url;
  13156. /**
  13157. * @var array instances of
  13158. * PHPUnit_Extensions_Selenium2TestCase_ElementCommand
  13159. */
  13160. protected $commands;
  13161. public function __construct($driver,
  13162. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  13163. {
  13164. $this->driver = $driver;
  13165. $this->url = $url;
  13166. $this->commands = array();
  13167. foreach ($this->initCommands() as $commandName => $handler) {
  13168. if (is_string($handler)) {
  13169. $this->commands[$commandName] = $this->factoryMethod($handler);
  13170. } else if (is_callable($handler)) {
  13171. $this->commands[$commandName] = $handler;
  13172. } else {
  13173. throw new InvalidArgumentException("Command $commandName is not configured correctly.");
  13174. }
  13175. }
  13176. }
  13177. /**
  13178. * @return array class names, or
  13179. * callables of the form function($parameter, $commandUrl)
  13180. */
  13181. protected abstract function initCommands();
  13182. public function __call($commandName, $arguments)
  13183. {
  13184. $jsonParameters = $this->extractJsonParameters($arguments);
  13185. $response = $this->driver->execute($this->newCommand($commandName, $jsonParameters));
  13186. return $response->getValue();
  13187. }
  13188. protected function postCommand($name, PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria)
  13189. {
  13190. $response = $this->driver->curl('POST',
  13191. $this->url->addCommand($name),
  13192. $criteria->getArrayCopy());
  13193. return $response->getValue();
  13194. }
  13195. /**
  13196. * @params string $commandClass a class name, descending from
  13197. PHPUnit_Extensions_Selenium2TestCase_Command
  13198. * @return callable
  13199. */
  13200. private function factoryMethod($commandClass)
  13201. {
  13202. return function($jsonParameters, $url) use ($commandClass) {
  13203. return new $commandClass($jsonParameters, $url);
  13204. };
  13205. }
  13206. private function extractJsonParameters($arguments)
  13207. {
  13208. $this->checkArguments($arguments);
  13209. if (count($arguments) == 0) {
  13210. return NULL;
  13211. }
  13212. return $arguments[0];
  13213. }
  13214. private function checkArguments($arguments)
  13215. {
  13216. if (count($arguments) > 1) {
  13217. throw new Exception('You cannot call a command with multiple method arguments.');
  13218. }
  13219. }
  13220. /**
  13221. * @param string $commandName The called method name
  13222. * defined as a key in initCommands()
  13223. * @param array $jsonParameters
  13224. * @return PHPUnit_Extensions_Selenium2TestCase_Command
  13225. */
  13226. protected function newCommand($commandName, $jsonParameters)
  13227. {
  13228. if (isset($this->commands[$commandName])) {
  13229. $factoryMethod = $this->commands[$commandName];
  13230. $url = $this->url->addCommand($commandName);
  13231. $command = $factoryMethod($jsonParameters, $url);
  13232. return $command;
  13233. }
  13234. throw new BadMethodCallException("The command '$commandName' is not existent or not supported yet.");
  13235. }
  13236. }
  13237. <?php
  13238. /**
  13239. * PHPUnit
  13240. *
  13241. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13242. * All rights reserved.
  13243. *
  13244. * Redistribution and use in source and binary forms, with or without
  13245. * modification, are permitted provided that the following conditions
  13246. * are met:
  13247. *
  13248. * * Redistributions of source code must retain the above copyright
  13249. * notice, this list of conditions and the following disclaimer.
  13250. *
  13251. * * Redistributions in binary form must reproduce the above copyright
  13252. * notice, this list of conditions and the following disclaimer in
  13253. * the documentation and/or other materials provided with the
  13254. * distribution.
  13255. *
  13256. * * Neither the name of Sebastian Bergmann nor the names of his
  13257. * contributors may be used to endorse or promote products derived
  13258. * from this software without specific prior written permission.
  13259. *
  13260. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13261. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13262. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13263. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13264. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13265. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13266. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13267. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13268. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13269. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13270. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13271. * POSSIBILITY OF SUCH DAMAGE.
  13272. *
  13273. * @package PHPUnit_Selenium
  13274. * @author Giorgio Sironi <info@giorgiosironi.com>
  13275. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13276. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13277. * @link http://www.phpunit.de/
  13278. * @since File available since Release 1.2.8
  13279. */
  13280. /**
  13281. * Base class for implementing commands with special semantics.
  13282. *
  13283. * @package PHPUnit_Selenium
  13284. * @author Giorgio Sironi <info@giorgiosironi.com>
  13285. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13286. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13287. * @version Release: @package_version@
  13288. * @link http://www.phpunit.de/
  13289. * @since Class available since Release 1.2.8
  13290. */
  13291. class PHPUnit_Extensions_Selenium2TestCase_ScreenshotListener implements PHPUnit_Framework_TestListener
  13292. {
  13293. private $directory;
  13294. public function __construct($directory)
  13295. {
  13296. $this->directory = $directory;
  13297. }
  13298. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  13299. {
  13300. $this->storeAScreenshot($test);
  13301. }
  13302. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  13303. {
  13304. $this->storeAScreenshot($test);
  13305. }
  13306. private function storeAScreenshot(PHPUnit_Framework_Test $test)
  13307. {
  13308. if ($test instanceof PHPUnit_Extensions_Selenium2TestCase)
  13309. {
  13310. try {
  13311. $file = $this->directory . '/' . get_class($test) . '__' . $test->getName() . '__' . date('Y-m-d\TH-i-s') . '.png';
  13312. file_put_contents($file, $test->currentScreenshot());
  13313. } catch (Exception $e) {
  13314. $file = $this->directory . '/' . get_class($test) . '__' . $test->getName() . '__' . date('Y-m-d\TH-i-s') . '.txt';
  13315. file_put_contents($file, "Screenshot generation doesn't work." . "\n"
  13316. . $e->getMessage() . "\n"
  13317. . $e->getTraceAsString());
  13318. }
  13319. }
  13320. }
  13321. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
  13322. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
  13323. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
  13324. public function startTest(PHPUnit_Framework_Test $test) {}
  13325. public function endTest(PHPUnit_Framework_Test $test, $time) {}
  13326. public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {}
  13327. public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {}
  13328. }
  13329. <?php
  13330. /**
  13331. * PHPUnit
  13332. *
  13333. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13334. * All rights reserved.
  13335. *
  13336. * Redistribution and use in source and binary forms, with or without
  13337. * modification, are permitted provided that the following conditions
  13338. * are met:
  13339. *
  13340. * * Redistributions of source code must retain the above copyright
  13341. * notice, this list of conditions and the following disclaimer.
  13342. *
  13343. * * Redistributions in binary form must reproduce the above copyright
  13344. * notice, this list of conditions and the following disclaimer in
  13345. * the documentation and/or other materials provided with the
  13346. * distribution.
  13347. *
  13348. * * Neither the name of Sebastian Bergmann nor the names of his
  13349. * contributors may be used to endorse or promote products derived
  13350. * from this software without specific prior written permission.
  13351. *
  13352. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13353. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13354. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13355. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13356. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13357. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13358. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13359. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13360. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13361. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13362. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13363. * POSSIBILITY OF SUCH DAMAGE.
  13364. *
  13365. * @package PHPUnit_Selenium
  13366. * @author Giorgio Sironi <info@giorgiosironi.com>
  13367. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13368. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13369. * @link http://www.phpunit.de/
  13370. * @since File available since Release 1.2.0
  13371. */
  13372. /**
  13373. * Base class for implementing commands with special semantics.
  13374. *
  13375. * @package PHPUnit_Selenium
  13376. * @author Giorgio Sironi <info@giorgiosironi.com>
  13377. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13378. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13379. * @version Release: @package_version@
  13380. * @link http://www.phpunit.de/
  13381. * @since Class available since Release 1.2.0
  13382. */
  13383. abstract class PHPUnit_Extensions_Selenium2TestCase_Command
  13384. {
  13385. protected $jsonParameters;
  13386. private $commandName;
  13387. /**
  13388. * @param array $jsonParameters null in case of no parameters
  13389. */
  13390. public function __construct($jsonParameters,
  13391. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  13392. {
  13393. if (!is_array($jsonParameters) && $jsonParameters !== NULL) {
  13394. throw new InvalidArgumentException("The JSON parameters must be an array, or a NULL value in case they are not required.");
  13395. }
  13396. $this->jsonParameters = $jsonParameters;
  13397. $this->url = $url;
  13398. }
  13399. public function url()
  13400. {
  13401. return $this->url;
  13402. }
  13403. /**
  13404. * @return string
  13405. */
  13406. abstract public function httpMethod();
  13407. /**
  13408. * @param array $jsonParameters null in case of no parameters
  13409. */
  13410. public function jsonParameters()
  13411. {
  13412. return $this->jsonParameters;
  13413. }
  13414. }
  13415. <?php
  13416. /**
  13417. * PHPUnit
  13418. *
  13419. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13420. * All rights reserved.
  13421. *
  13422. * Redistribution and use in source and binary forms, with or without
  13423. * modification, are permitted provided that the following conditions
  13424. * are met:
  13425. *
  13426. * * Redistributions of source code must retain the above copyright
  13427. * notice, this list of conditions and the following disclaimer.
  13428. *
  13429. * * Redistributions in binary form must reproduce the above copyright
  13430. * notice, this list of conditions and the following disclaimer in
  13431. * the documentation and/or other materials provided with the
  13432. * distribution.
  13433. *
  13434. * * Neither the name of Sebastian Bergmann nor the names of his
  13435. * contributors may be used to endorse or promote products derived
  13436. * from this software without specific prior written permission.
  13437. *
  13438. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13439. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13440. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13441. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13442. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13443. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13444. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13445. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13446. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13447. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13448. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13449. * POSSIBILITY OF SUCH DAMAGE.
  13450. *
  13451. * @package PHPUnit_Selenium
  13452. * @author Giorgio Sironi <info@giorgiosironi.com>
  13453. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13454. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13455. * @link http://www.phpunit.de/
  13456. * @since File available since Release 1.2.5
  13457. */
  13458. /**
  13459. * Gets or sets an attribute of an object.
  13460. *
  13461. * @package PHPUnit_Selenium
  13462. * @author Giorgio Sironi <info@giorgiosironi.com>
  13463. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13464. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13465. * @version Release: @package_version@
  13466. * @link http://www.phpunit.de/
  13467. * @since Class available since Release 1.2.5
  13468. */
  13469. class PHPUnit_Extensions_Selenium2TestCase_StateCommand
  13470. extends PHPUnit_Extensions_Selenium2TestCase_Command
  13471. {
  13472. public function httpMethod()
  13473. {
  13474. if ($this->jsonParameters) {
  13475. return 'POST';
  13476. }
  13477. return 'GET';
  13478. }
  13479. }
  13480. <?php
  13481. /**
  13482. * PHPUnit
  13483. *
  13484. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13485. * All rights reserved.
  13486. *
  13487. * Redistribution and use in source and binary forms, with or without
  13488. * modification, are permitted provided that the following conditions
  13489. * are met:
  13490. *
  13491. * * Redistributions of source code must retain the above copyright
  13492. * notice, this list of conditions and the following disclaimer.
  13493. *
  13494. * * Redistributions in binary form must reproduce the above copyright
  13495. * notice, this list of conditions and the following disclaimer in
  13496. * the documentation and/or other materials provided with the
  13497. * distribution.
  13498. *
  13499. * * Neither the name of Sebastian Bergmann nor the names of his
  13500. * contributors may be used to endorse or promote products derived
  13501. * from this software without specific prior written permission.
  13502. *
  13503. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13504. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13505. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13506. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13507. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13508. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13509. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13510. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13511. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13512. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13513. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13514. * POSSIBILITY OF SUCH DAMAGE.
  13515. *
  13516. * @package PHPUnit_Selenium
  13517. * @author Giorgio Sironi <info@giorgiosironi.com>
  13518. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13519. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13520. * @link http://www.phpunit.de/
  13521. * @since File available since Release 1.2.0
  13522. */
  13523. /**
  13524. * Object representing a DOM element.
  13525. *
  13526. * @package PHPUnit_Selenium
  13527. * @author Giorgio Sironi <info@giorgiosironi.com>
  13528. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13529. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13530. * @version Release: @package_version@
  13531. * @link http://www.phpunit.de/
  13532. * @since Class available since Release 1.2.0
  13533. * @method string attribute($name) Retrieves an element's attribute
  13534. * @method void clear() Empties the content of a form element.
  13535. * @method void click() Clicks on element
  13536. * @method string css($propertyName) Retrieves the value of a CSS property
  13537. * @method bool displayed() Checks an element's visibility
  13538. * @method bool enabled() Checks a form element's state
  13539. * @method bool equals(PHPUnit_Extensions_Selenium2TestCase_Element $another) Checks if the two elements are the same on the page
  13540. * @method array location() Retrieves the element's position in the page: keys 'x' and 'y' in the returned array
  13541. * @method bool selected() Checks the state of an option or other form element
  13542. * @method array size() Retrieves the dimensions of the element: 'width' and 'height' of the returned array
  13543. * @method void submit() Submits a form; can be called on its children
  13544. * @method string text() Get content of ordinary elements
  13545. */
  13546. class PHPUnit_Extensions_Selenium2TestCase_Element
  13547. extends PHPUnit_Extensions_Selenium2TestCase_Element_Accessor
  13548. {
  13549. /**
  13550. * @return \self
  13551. * @throws InvalidArgumentException
  13552. */
  13553. public static function fromResponseValue(
  13554. array $value,
  13555. PHPUnit_Extensions_Selenium2TestCase_URL $parentFolder,
  13556. PHPUnit_Extensions_Selenium2TestCase_Driver $driver)
  13557. {
  13558. if (!isset($value['ELEMENT'])) {
  13559. throw new InvalidArgumentException('Element not found.');
  13560. }
  13561. $url = $parentFolder->descend($value['ELEMENT']);
  13562. return new self($driver, $url);
  13563. }
  13564. /**
  13565. * @return integer
  13566. */
  13567. public function getId()
  13568. {
  13569. return $this->url->lastSegment();
  13570. }
  13571. /**
  13572. * @return array class names
  13573. */
  13574. protected function initCommands()
  13575. {
  13576. return array(
  13577. 'attribute' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Attribute',
  13578. 'clear' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  13579. 'click' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Click',
  13580. 'css' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Css',
  13581. 'displayed' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13582. 'enabled' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13583. 'equals' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Equals',
  13584. 'location' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13585. 'name' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13586. 'selected' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13587. 'size' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13588. 'submit' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  13589. 'text' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13590. 'value' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Value',
  13591. 'tap' => $this->touchCommandFactoryMethod('touch/click'),
  13592. 'scroll' => $this->touchCommandFactoryMethod('touch/scroll'),
  13593. 'doubletap' => $this->touchCommandFactoryMethod('touch/doubleclick'),
  13594. 'longtap' => $this->touchCommandFactoryMethod('touch/longclick'),
  13595. 'flick' => $this->touchCommandFactoryMethod('touch/flick')
  13596. );
  13597. }
  13598. protected function getSessionUrl()
  13599. {
  13600. return $this->url->ascend()->ascend();
  13601. }
  13602. private function touchCommandFactoryMethod($urlSegment)
  13603. {
  13604. $url = $this->getSessionUrl()->addCommand($urlSegment);
  13605. $self = $this;
  13606. return function ($jsonParameters, $commandUrl) use ($url, $self) {
  13607. if ((is_array($jsonParameters) &&
  13608. !isset($jsonParameters['element'])) ||
  13609. is_null($jsonParameters)) {
  13610. $jsonParameters['element'] = $self->getId();
  13611. }
  13612. return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $url);
  13613. };
  13614. }
  13615. /**
  13616. * Retrieves the tag name
  13617. * @return string
  13618. */
  13619. public function name()
  13620. {
  13621. return strtolower(parent::name());
  13622. }
  13623. /**
  13624. * Generates an array that is structured as the WebDriver Object of the JSONWireProtocoll
  13625. *
  13626. * @return array
  13627. */
  13628. public function toWebDriverObject()
  13629. {
  13630. return array('ELEMENT' => (string)$this->getId());
  13631. }
  13632. /**
  13633. * Get or set value of form elements. If the element already has a value, the set one will be appended to it.
  13634. * Created **ONLY** for keeping backward compatibility, since in selenium v2.42.0 it was removed
  13635. * The currently recommended solution is to use `$element->attribute('value')`
  13636. * @see https://code.google.com/p/selenium/source/detail?r=953007b48e83f90450f3e41b11ec31e2928f1605
  13637. * @see https://code.google.com/p/selenium/source/browse/java/CHANGELOG
  13638. *
  13639. * @param string $newValue
  13640. * @return null|string
  13641. */
  13642. public function value($newValue = NULL)
  13643. {
  13644. if ($newValue !== NULL) {
  13645. return parent::value($newValue);
  13646. }
  13647. return $this->attribute('value');
  13648. }
  13649. }
  13650. <?php
  13651. /**
  13652. * PHPUnit
  13653. *
  13654. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13655. * All rights reserved.
  13656. *
  13657. * Redistribution and use in source and binary forms, with or without
  13658. * modification, are permitted provided that the following conditions
  13659. * are met:
  13660. *
  13661. * * Redistributions of source code must retain the above copyright
  13662. * notice, this list of conditions and the following disclaimer.
  13663. *
  13664. * * Redistributions in binary form must reproduce the above copyright
  13665. * notice, this list of conditions and the following disclaimer in
  13666. * the documentation and/or other materials provided with the
  13667. * distribution.
  13668. *
  13669. * * Neither the name of Sebastian Bergmann nor the names of his
  13670. * contributors may be used to endorse or promote products derived
  13671. * from this software without specific prior written permission.
  13672. *
  13673. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13674. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13675. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13676. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13677. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13678. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13679. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13680. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13681. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13682. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13683. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13684. * POSSIBILITY OF SUCH DAMAGE.
  13685. *
  13686. * @package PHPUnit_Selenium
  13687. * @author Giorgio Sironi <info@giorgiosironi.com>
  13688. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13689. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13690. * @link http://www.phpunit.de/
  13691. * @since File available since Release 1.2.0
  13692. */
  13693. /**
  13694. * Object representing an HTTP response from the Selenium Server.
  13695. *
  13696. * @package PHPUnit_Selenium
  13697. * @author Giorgio Sironi <info@giorgiosironi.com>
  13698. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13699. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13700. * @version Release: @package_version@
  13701. * @link http://www.phpunit.de/
  13702. * @since Class available since Release 1.2.0
  13703. */
  13704. class PHPUnit_Extensions_Selenium2TestCase_Response
  13705. {
  13706. /**
  13707. * @var array decoded response
  13708. */
  13709. private $jsonResponse;
  13710. /**
  13711. * @var array CURL info for the response.
  13712. */
  13713. private $info;
  13714. public function __construct($jsonResponse, $info)
  13715. {
  13716. $this->jsonResponse = $jsonResponse;
  13717. $this->info = $info;
  13718. }
  13719. public function getValue()
  13720. {
  13721. if (isset($this->jsonResponse['value'])) {
  13722. return $this->jsonResponse['value'];
  13723. }
  13724. }
  13725. /**
  13726. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  13727. */
  13728. public function getURL()
  13729. {
  13730. $url = $this->info['url'];
  13731. $sessionId = $this->jsonResponse['sessionId'];
  13732. // if url doesn't have sessionId included - append it manually
  13733. // this change was performed in selenium v2.34
  13734. // @see https://code.google.com/p/selenium/issues/detail?id=6089
  13735. // @see https://github.com/sebastianbergmann/phpunit-selenium/issues/265
  13736. if (strpos($url, $sessionId) === FALSE) {
  13737. $url .= '/' . $sessionId;
  13738. }
  13739. return new PHPUnit_Extensions_Selenium2TestCase_URL($url);
  13740. }
  13741. }
  13742. <?php
  13743. /**
  13744. * PHPUnit
  13745. *
  13746. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13747. * All rights reserved.
  13748. *
  13749. * Redistribution and use in source and binary forms, with or without
  13750. * modification, are permitted provided that the following conditions
  13751. * are met:
  13752. *
  13753. * * Redistributions of source code must retain the above copyright
  13754. * notice, this list of conditions and the following disclaimer.
  13755. *
  13756. * * Redistributions in binary form must reproduce the above copyright
  13757. * notice, this list of conditions and the following disclaimer in
  13758. * the documentation and/or other materials provided with the
  13759. * distribution.
  13760. *
  13761. * * Neither the name of Sebastian Bergmann nor the names of his
  13762. * contributors may be used to endorse or promote products derived
  13763. * from this software without specific prior written permission.
  13764. *
  13765. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13766. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13767. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13768. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13769. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13770. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13771. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13772. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13773. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13774. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13775. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13776. * POSSIBILITY OF SUCH DAMAGE.
  13777. *
  13778. * @package PHPUnit_Selenium
  13779. * @author Giorgio Sironi <info@giorgiosironi.com>
  13780. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13781. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13782. * @link http://www.phpunit.de/
  13783. * @since File available since Release 1.2.9
  13784. */
  13785. /**
  13786. * @package PHPUnit_Selenium
  13787. * @author Giorgio Sironi <info@giorgiosironi.com>
  13788. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13789. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13790. * @version Release: @package_version@
  13791. * @link http://www.phpunit.de/
  13792. * @since Class available since Release 1.2.8
  13793. */
  13794. class PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException
  13795. extends PHPUnit_Extensions_Selenium2TestCase_Exception
  13796. {
  13797. }
  13798. <?php
  13799. /**
  13800. * PHPUnit
  13801. *
  13802. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13803. * All rights reserved.
  13804. *
  13805. * Redistribution and use in source and binary forms, with or without
  13806. * modification, are permitted provided that the following conditions
  13807. * are met:
  13808. *
  13809. * * Redistributions of source code must retain the above copyright
  13810. * notice, this list of conditions and the following disclaimer.
  13811. *
  13812. * * Redistributions in binary form must reproduce the above copyright
  13813. * notice, this list of conditions and the following disclaimer in
  13814. * the documentation and/or other materials provided with the
  13815. * distribution.
  13816. *
  13817. * * Neither the name of Sebastian Bergmann nor the names of his
  13818. * contributors may be used to endorse or promote products derived
  13819. * from this software without specific prior written permission.
  13820. *
  13821. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13822. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13823. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13824. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13825. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13826. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13827. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13828. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13829. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13830. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13831. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13832. * POSSIBILITY OF SUCH DAMAGE.
  13833. *
  13834. * @package PHPUnit_Selenium
  13835. * @author Giorgio Sironi <info@giorgiosironi.com>
  13836. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13837. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13838. * @link http://www.phpunit.de/
  13839. * @since File available since Release 1.2.6
  13840. */
  13841. /**
  13842. * Keeps a Session object shared between test runs to save time.
  13843. *
  13844. * @package PHPUnit_Selenium
  13845. * @author Giorgio Sironi <info@giorgiosironi.com>
  13846. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13847. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13848. * @version Release: @package_version@
  13849. * @link http://www.phpunit.de/
  13850. * @since Class available since Release 1.2.6
  13851. */
  13852. class PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared
  13853. implements PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  13854. {
  13855. private $original;
  13856. private $session;
  13857. private $mainWindow;
  13858. private $lastTestWasNotSuccessful = FALSE;
  13859. public function __construct(PHPUnit_Extensions_Selenium2TestCase_SessionStrategy $originalStrategy)
  13860. {
  13861. $this->original = $originalStrategy;
  13862. }
  13863. public function session(array $parameters)
  13864. {
  13865. if ($this->lastTestWasNotSuccessful) {
  13866. if ($this->session !== NULL) {
  13867. $this->session->stop();
  13868. $this->session = NULL;
  13869. }
  13870. $this->lastTestWasNotSuccessful = FALSE;
  13871. }
  13872. if ($this->session === NULL) {
  13873. $this->session = $this->original->session($parameters);
  13874. $this->mainWindow = $this->session->windowHandle();
  13875. } else {
  13876. $this->session->window($this->mainWindow);
  13877. }
  13878. return $this->session;
  13879. }
  13880. public function notSuccessfulTest()
  13881. {
  13882. $this->lastTestWasNotSuccessful = TRUE;
  13883. }
  13884. public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL)
  13885. {
  13886. }
  13887. }
  13888. <?php
  13889. /**
  13890. * PHPUnit
  13891. *
  13892. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13893. * All rights reserved.
  13894. *
  13895. * Redistribution and use in source and binary forms, with or without
  13896. * modification, are permitted provided that the following conditions
  13897. * are met:
  13898. *
  13899. * * Redistributions of source code must retain the above copyright
  13900. * notice, this list of conditions and the following disclaimer.
  13901. *
  13902. * * Redistributions in binary form must reproduce the above copyright
  13903. * notice, this list of conditions and the following disclaimer in
  13904. * the documentation and/or other materials provided with the
  13905. * distribution.
  13906. *
  13907. * * Neither the name of Sebastian Bergmann nor the names of his
  13908. * contributors may be used to endorse or promote products derived
  13909. * from this software without specific prior written permission.
  13910. *
  13911. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13912. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13913. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13914. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13915. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13916. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13917. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13918. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13919. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13920. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13921. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13922. * POSSIBILITY OF SUCH DAMAGE.
  13923. *
  13924. * @package PHPUnit_Selenium
  13925. * @author Giorgio Sironi <info@giorgiosironi.com>
  13926. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13927. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13928. * @link http://www.phpunit.de/
  13929. * @since File available since Release 1.2.6
  13930. */
  13931. /**
  13932. * Produces a new Session object shared for each test.
  13933. *
  13934. * @package PHPUnit_Selenium
  13935. * @author Giorgio Sironi <info@giorgiosironi.com>
  13936. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13937. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13938. * @version Release: @package_version@
  13939. * @link http://www.phpunit.de/
  13940. * @since Class available since Release 1.2.6
  13941. */
  13942. class PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated
  13943. implements PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  13944. {
  13945. public function session(array $parameters)
  13946. {
  13947. $seleniumServerUrl = PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($parameters['host'], $parameters['port']);
  13948. $driver = new PHPUnit_Extensions_Selenium2TestCase_Driver($seleniumServerUrl, $parameters['seleniumServerRequestsTimeout']);
  13949. $capabilities = array_merge($parameters['desiredCapabilities'],
  13950. array(
  13951. 'browserName' => $parameters['browserName']
  13952. ));
  13953. $session = $driver->startSession($capabilities, $parameters['browserUrl']);
  13954. return $session;
  13955. }
  13956. public function notSuccessfulTest()
  13957. {
  13958. }
  13959. public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL)
  13960. {
  13961. if ($session !== NULL) {
  13962. $session->stop();
  13963. }
  13964. }
  13965. }
  13966. <?php
  13967. /**
  13968. * PHPUnit
  13969. *
  13970. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13971. * All rights reserved.
  13972. *
  13973. * Redistribution and use in source and binary forms, with or without
  13974. * modification, are permitted provided that the following conditions
  13975. * are met:
  13976. *
  13977. * * Redistributions of source code must retain the above copyright
  13978. * notice, this list of conditions and the following disclaimer.
  13979. *
  13980. * * Redistributions in binary form must reproduce the above copyright
  13981. * notice, this list of conditions and the following disclaimer in
  13982. * the documentation and/or other materials provided with the
  13983. * distribution.
  13984. *
  13985. * * Neither the name of Sebastian Bergmann nor the names of his
  13986. * contributors may be used to endorse or promote products derived
  13987. * from this software without specific prior written permission.
  13988. *
  13989. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13990. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13991. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13992. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13993. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13994. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13995. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13996. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13997. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13998. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13999. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14000. * POSSIBILITY OF SUCH DAMAGE.
  14001. *
  14002. * @package PHPUnit_Selenium
  14003. * @author Giorgio Sironi <info@giorgiosironi.com>
  14004. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14005. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14006. * @link http://www.phpunit.de/
  14007. * @since File available since Release 1.2.0
  14008. */
  14009. /**
  14010. * Clicks ok on an alert popup.
  14011. *
  14012. * @package PHPUnit_Selenium
  14013. * @author Giorgio Sironi <info@giorgiosironi.com>
  14014. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14015. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14016. * @version Release: @package_version@
  14017. * @link http://www.phpunit.de/
  14018. * @since Class available since Release 1.2.0
  14019. */
  14020. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Click
  14021. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14022. {
  14023. public function httpMethod()
  14024. {
  14025. return 'POST';
  14026. }
  14027. }
  14028. <?php
  14029. /**
  14030. * PHPUnit
  14031. *
  14032. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14033. * All rights reserved.
  14034. *
  14035. * Redistribution and use in source and binary forms, with or without
  14036. * modification, are permitted provided that the following conditions
  14037. * are met:
  14038. *
  14039. * * Redistributions of source code must retain the above copyright
  14040. * notice, this list of conditions and the following disclaimer.
  14041. *
  14042. * * Redistributions in binary form must reproduce the above copyright
  14043. * notice, this list of conditions and the following disclaimer in
  14044. * the documentation and/or other materials provided with the
  14045. * distribution.
  14046. *
  14047. * * Neither the name of Sebastian Bergmann nor the names of his
  14048. * contributors may be used to endorse or promote products derived
  14049. * from this software without specific prior written permission.
  14050. *
  14051. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14052. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14053. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14054. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14055. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14056. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14057. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14058. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14059. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14060. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14061. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14062. * POSSIBILITY OF SUCH DAMAGE.
  14063. *
  14064. * @package PHPUnit_Selenium
  14065. * @author Giorgio Sironi <info@giorgiosironi.com>
  14066. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14067. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14068. * @link http://www.phpunit.de/
  14069. * @since File available since Release 1.2.4
  14070. */
  14071. /**
  14072. * Checks equality (same element on the page) with another DOM element.
  14073. *
  14074. * @package PHPUnit_Selenium
  14075. * @author Giorgio Sironi <info@giorgiosironi.com>
  14076. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14077. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14078. * @version Release: @package_version@
  14079. * @link http://www.phpunit.de/
  14080. * @since Class available since Release 1.2.4
  14081. */
  14082. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Equals
  14083. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14084. {
  14085. /**
  14086. * @param array $parameter
  14087. */
  14088. public function __construct($parameter,
  14089. PHPUnit_Extensions_Selenium2TestCase_URL $equalsResourceBaseUrl)
  14090. {
  14091. $this->jsonParameters = array();
  14092. if (!($parameter instanceof PHPUnit_Extensions_Selenium2TestCase_Element)) {
  14093. throw new InvalidArgumentException("Elements can only test equality with other Element instances.");
  14094. }
  14095. $this->url = $equalsResourceBaseUrl->descend($parameter->getId());
  14096. }
  14097. public function httpMethod()
  14098. {
  14099. return 'GET';
  14100. }
  14101. }
  14102. <?php
  14103. /**
  14104. * PHPUnit
  14105. *
  14106. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14107. * All rights reserved.
  14108. *
  14109. * Redistribution and use in source and binary forms, with or without
  14110. * modification, are permitted provided that the following conditions
  14111. * are met:
  14112. *
  14113. * * Redistributions of source code must retain the above copyright
  14114. * notice, this list of conditions and the following disclaimer.
  14115. *
  14116. * * Redistributions in binary form must reproduce the above copyright
  14117. * notice, this list of conditions and the following disclaimer in
  14118. * the documentation and/or other materials provided with the
  14119. * distribution.
  14120. *
  14121. * * Neither the name of Sebastian Bergmann nor the names of his
  14122. * contributors may be used to endorse or promote products derived
  14123. * from this software without specific prior written permission.
  14124. *
  14125. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14126. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14127. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14128. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14129. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14130. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14131. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14132. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14133. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14134. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14135. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14136. * POSSIBILITY OF SUCH DAMAGE.
  14137. *
  14138. * @package PHPUnit_Selenium
  14139. * @author Giorgio Sironi <info@giorgiosironi.com>
  14140. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14141. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14142. * @link http://www.phpunit.de/
  14143. * @since File available since Release 1.2.0
  14144. */
  14145. /**
  14146. * Class for implementing commands that just return a value
  14147. * (obtained with GET).
  14148. *
  14149. * @package PHPUnit_Selenium
  14150. * @author Giorgio Sironi <info@giorgiosironi.com>
  14151. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14152. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14153. * @version Release: @package_version@
  14154. * @link http://www.phpunit.de/
  14155. * @since Class available since Release 1.2.0
  14156. */
  14157. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor
  14158. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14159. {
  14160. public function httpMethod()
  14161. {
  14162. return 'GET';
  14163. }
  14164. }
  14165. <?php
  14166. /**
  14167. * PHPUnit
  14168. *
  14169. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14170. * All rights reserved.
  14171. *
  14172. * Redistribution and use in source and binary forms, with or without
  14173. * modification, are permitted provided that the following conditions
  14174. * are met:
  14175. *
  14176. * * Redistributions of source code must retain the above copyright
  14177. * notice, this list of conditions and the following disclaimer.
  14178. *
  14179. * * Redistributions in binary form must reproduce the above copyright
  14180. * notice, this list of conditions and the following disclaimer in
  14181. * the documentation and/or other materials provided with the
  14182. * distribution.
  14183. *
  14184. * * Neither the name of Sebastian Bergmann nor the names of his
  14185. * contributors may be used to endorse or promote products derived
  14186. * from this software without specific prior written permission.
  14187. *
  14188. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14189. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14190. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14191. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14192. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14193. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14194. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14195. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14196. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14197. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14198. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14199. * POSSIBILITY OF SUCH DAMAGE.
  14200. *
  14201. * @package PHPUnit_Selenium
  14202. * @author Giorgio Sironi <info@giorgiosironi.com>
  14203. * @copyright 2012 Sebastian Bergmann <sebastian@phpunit.de>
  14204. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14205. * @link http://www.phpunit.de/
  14206. * @since File available since Release 1.2.4
  14207. */
  14208. /**
  14209. * Class for implementing commands that just accomplishes an action (via POST).
  14210. *
  14211. * @package PHPUnit_Selenium
  14212. * @author Giorgio Sironi <info@giorgiosironi.com>
  14213. * @copyright 2012 Sebastian Bergmann <sebastian@phpunit.de>
  14214. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14215. * @version Release: @package_version@
  14216. * @link http://www.phpunit.de/
  14217. * @since Class available since Release 1.2.4
  14218. */
  14219. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost
  14220. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14221. {
  14222. public function httpMethod()
  14223. {
  14224. return 'POST';
  14225. }
  14226. }
  14227. <?php
  14228. /**
  14229. * PHPUnit
  14230. *
  14231. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14232. * All rights reserved.
  14233. *
  14234. * Redistribution and use in source and binary forms, with or without
  14235. * modification, are permitted provided that the following conditions
  14236. * are met:
  14237. *
  14238. * * Redistributions of source code must retain the above copyright
  14239. * notice, this list of conditions and the following disclaimer.
  14240. *
  14241. * * Redistributions in binary form must reproduce the above copyright
  14242. * notice, this list of conditions and the following disclaimer in
  14243. * the documentation and/or other materials provided with the
  14244. * distribution.
  14245. *
  14246. * * Neither the name of Sebastian Bergmann nor the names of his
  14247. * contributors may be used to endorse or promote products derived
  14248. * from this software without specific prior written permission.
  14249. *
  14250. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14251. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14252. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14253. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14254. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14255. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14256. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14257. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14258. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14259. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14260. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14261. * POSSIBILITY OF SUCH DAMAGE.
  14262. *
  14263. * @package PHPUnit_Selenium
  14264. * @author Giorgio Sironi <info@giorgiosironi.com>
  14265. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14266. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14267. * @link http://www.phpunit.de/
  14268. * @since File available since Release 1.2.0
  14269. */
  14270. /**
  14271. * Get and set the element's value attribute.
  14272. *
  14273. * @package PHPUnit_Selenium
  14274. * @author Giorgio Sironi <info@giorgiosironi.com>
  14275. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14276. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14277. * @version Release: @package_version@
  14278. * @link http://www.phpunit.de/
  14279. * @since Class available since Release 1.2.0
  14280. */
  14281. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Value
  14282. extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys
  14283. {
  14284. public function httpMethod()
  14285. {
  14286. if ($this->jsonParameters) {
  14287. return 'POST';
  14288. }
  14289. throw new BadMethodCallException("JSON Wire Protocol only supports POST to /value now. To get the value of an element GET /attribute/:naem should be used and this object should never be involved.");
  14290. }
  14291. }
  14292. <?php
  14293. /**
  14294. * PHPUnit
  14295. *
  14296. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14297. * All rights reserved.
  14298. *
  14299. * Redistribution and use in source and binary forms, with or without
  14300. * modification, are permitted provided that the following conditions
  14301. * are met:
  14302. *
  14303. * * Redistributions of source code must retain the above copyright
  14304. * notice, this list of conditions and the following disclaimer.
  14305. *
  14306. * * Redistributions in binary form must reproduce the above copyright
  14307. * notice, this list of conditions and the following disclaimer in
  14308. * the documentation and/or other materials provided with the
  14309. * distribution.
  14310. *
  14311. * * Neither the name of Sebastian Bergmann nor the names of his
  14312. * contributors may be used to endorse or promote products derived
  14313. * from this software without specific prior written permission.
  14314. *
  14315. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14316. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14317. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14318. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14319. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14320. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14321. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14322. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14323. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14324. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14325. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14326. * POSSIBILITY OF SUCH DAMAGE.
  14327. *
  14328. * @package PHPUnit_Selenium
  14329. * @author Giorgio Sironi <info@giorgiosironi.com>
  14330. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14331. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14332. * @link http://www.phpunit.de/
  14333. * @since File available since Release 1.2.4
  14334. */
  14335. /**
  14336. * Retrieves an attribute of a DOM element.
  14337. *
  14338. * @package PHPUnit_Selenium
  14339. * @author Giorgio Sironi <info@giorgiosironi.com>
  14340. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14341. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14342. * @version Release: @package_version@
  14343. * @link http://www.phpunit.de/
  14344. * @since Class available since Release 1.2.4
  14345. */
  14346. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Attribute
  14347. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14348. {
  14349. /**
  14350. * @param array $parameter
  14351. */
  14352. public function __construct($parameter,
  14353. PHPUnit_Extensions_Selenium2TestCase_URL $attributeResourceBaseUrl)
  14354. {
  14355. $this->jsonParameters = array();
  14356. $this->url = $attributeResourceBaseUrl->descend($parameter);
  14357. }
  14358. public function httpMethod()
  14359. {
  14360. return 'GET';
  14361. }
  14362. }
  14363. <?php
  14364. /**
  14365. * PHPUnit
  14366. *
  14367. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14368. * All rights reserved.
  14369. *
  14370. * Redistribution and use in source and binary forms, with or without
  14371. * modification, are permitted provided that the following conditions
  14372. * are met:
  14373. *
  14374. * * Redistributions of source code must retain the above copyright
  14375. * notice, this list of conditions and the following disclaimer.
  14376. *
  14377. * * Redistributions in binary form must reproduce the above copyright
  14378. * notice, this list of conditions and the following disclaimer in
  14379. * the documentation and/or other materials provided with the
  14380. * distribution.
  14381. *
  14382. * * Neither the name of Sebastian Bergmann nor the names of his
  14383. * contributors may be used to endorse or promote products derived
  14384. * from this software without specific prior written permission.
  14385. *
  14386. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14387. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14388. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14389. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14390. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14391. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14392. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14393. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14394. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14395. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14396. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14397. * POSSIBILITY OF SUCH DAMAGE.
  14398. *
  14399. * @package PHPUnit_Selenium
  14400. * @author Giorgio Sironi <info@giorgiosironi.com>
  14401. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14402. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14403. * @link http://www.phpunit.de/
  14404. * @since File available since Release 1.2.4
  14405. */
  14406. /**
  14407. * Retrieves the value of a CSS property.
  14408. *
  14409. * @package PHPUnit_Selenium
  14410. * @author Giorgio Sironi <info@giorgiosironi.com>
  14411. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14412. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14413. * @version Release: @package_version@
  14414. * @link http://www.phpunit.de/
  14415. * @since Class available since Release 1.2.4
  14416. */
  14417. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Css
  14418. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14419. {
  14420. /**
  14421. * @param array $propertyName
  14422. */
  14423. public function __construct($propertyName,
  14424. PHPUnit_Extensions_Selenium2TestCase_URL $cssResourceBaseUrl)
  14425. {
  14426. $this->jsonParameters = array();
  14427. $this->url = $cssResourceBaseUrl->descend($propertyName);
  14428. }
  14429. public function httpMethod()
  14430. {
  14431. return 'GET';
  14432. }
  14433. }
  14434. <?php
  14435. /**
  14436. * PHPUnit
  14437. *
  14438. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14439. * All rights reserved.
  14440. *
  14441. * Redistribution and use in source and binary forms, with or without
  14442. * modification, are permitted provided that the following conditions
  14443. * are met:
  14444. *
  14445. * * Redistributions of source code must retain the above copyright
  14446. * notice, this list of conditions and the following disclaimer.
  14447. *
  14448. * * Redistributions in binary form must reproduce the above copyright
  14449. * notice, this list of conditions and the following disclaimer in
  14450. * the documentation and/or other materials provided with the
  14451. * distribution.
  14452. *
  14453. * * Neither the name of Sebastian Bergmann nor the names of his
  14454. * contributors may be used to endorse or promote products derived
  14455. * from this software without specific prior written permission.
  14456. *
  14457. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14458. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14459. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14460. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14461. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14462. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14463. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14464. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14465. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14466. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14467. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14468. * POSSIBILITY OF SUCH DAMAGE.
  14469. *
  14470. * @package PHPUnit_Selenium
  14471. * @author Giorgio Sironi <info@giorgiosironi.com>
  14472. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14473. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14474. * @link http://www.phpunit.de/
  14475. * @since File available since Release 1.2.0
  14476. */
  14477. /**
  14478. * Conditions for selecting a DOM element.
  14479. *
  14480. * @package PHPUnit_Selenium
  14481. * @author Giorgio Sironi <info@giorgiosironi.com>
  14482. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14483. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14484. * @version Release: @package_version@
  14485. * @link http://www.phpunit.de/
  14486. * @since Class available since Release 1.2.0
  14487. * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element
  14488. */
  14489. class PHPUnit_Extensions_Selenium2TestCase_ElementCriteria extends ArrayObject
  14490. {
  14491. public function __construct($strategy)
  14492. {
  14493. $this['using'] = $strategy;
  14494. }
  14495. /**
  14496. * @return PHPUnit_Extensions_Selenium2TestCase_ElementCriteria
  14497. */
  14498. public function value($searchTarget)
  14499. {
  14500. $this['value'] = $searchTarget;
  14501. return $this;
  14502. }
  14503. }
  14504. <?php
  14505. /**
  14506. * PHPUnit
  14507. *
  14508. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14509. * All rights reserved.
  14510. *
  14511. * Redistribution and use in source and binary forms, with or without
  14512. * modification, are permitted provided that the following conditions
  14513. * are met:
  14514. *
  14515. * * Redistributions of source code must retain the above copyright
  14516. * notice, this list of conditions and the following disclaimer.
  14517. *
  14518. * * Redistributions in binary form must reproduce the above copyright
  14519. * notice, this list of conditions and the following disclaimer in
  14520. * the documentation and/or other materials provided with the
  14521. * distribution.
  14522. *
  14523. * * Neither the name of Sebastian Bergmann nor the names of his
  14524. * contributors may be used to endorse or promote products derived
  14525. * from this software without specific prior written permission.
  14526. *
  14527. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14528. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14529. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14530. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14531. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14532. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14533. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14534. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14535. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14536. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14537. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14538. * POSSIBILITY OF SUCH DAMAGE.
  14539. *
  14540. * @package PHPUnit_Selenium
  14541. * @author Giorgio Sironi <info@giorgiosironi.com>
  14542. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14543. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14544. * @link http://www.phpunit.de/
  14545. * @since File available since Release 1.2.5
  14546. */
  14547. /**
  14548. * Object representing a browser window.
  14549. *
  14550. * @package PHPUnit_Selenium
  14551. * @author Giorgio Sironi <info@giorgiosironi.com>
  14552. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14553. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14554. * @version Release: @package_version@
  14555. * @link http://www.phpunit.de/
  14556. * @since Class available since Release 1.2.5
  14557. * @method array size(array $size = null) Window size as array('width' => $x, 'height' => $y)
  14558. * @method array position(array $position = null) Window position as array('x' => $x, 'y' => $y)
  14559. * @method array maximize() Maximize window
  14560. */
  14561. class PHPUnit_Extensions_Selenium2TestCase_Window extends PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
  14562. {
  14563. /**
  14564. * @return array class names
  14565. */
  14566. protected function initCommands()
  14567. {
  14568. return array(
  14569. 'size' => 'PHPUnit_Extensions_Selenium2TestCase_StateCommand',
  14570. 'position' => 'PHPUnit_Extensions_Selenium2TestCase_StateCommand',
  14571. 'maximize' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  14572. );
  14573. }
  14574. }
  14575. <?php
  14576. /**
  14577. * PHPUnit
  14578. *
  14579. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14580. * All rights reserved.
  14581. *
  14582. * Redistribution and use in source and binary forms, with or without
  14583. * modification, are permitted provided that the following conditions
  14584. * are met:
  14585. *
  14586. * * Redistributions of source code must retain the above copyright
  14587. * notice, this list of conditions and the following disclaimer.
  14588. *
  14589. * * Redistributions in binary form must reproduce the above copyright
  14590. * notice, this list of conditions and the following disclaimer in
  14591. * the documentation and/or other materials provided with the
  14592. * distribution.
  14593. *
  14594. * * Neither the name of Sebastian Bergmann nor the names of his
  14595. * contributors may be used to endorse or promote products derived
  14596. * from this software without specific prior written permission.
  14597. *
  14598. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14599. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14600. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14601. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14602. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14603. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14604. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14605. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14606. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14607. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14608. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14609. * POSSIBILITY OF SUCH DAMAGE.
  14610. *
  14611. * @package PHPUnit_Selenium
  14612. * @author Giorgio Sironi <info@giorgiosironi.com>
  14613. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14614. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14615. * @link http://www.phpunit.de/
  14616. * @since File available since Release 1.2.0
  14617. */
  14618. /**
  14619. * Driver for creating browser session with Selenium 2 (WebDriver API).
  14620. *
  14621. * @package PHPUnit_Selenium
  14622. * @author Giorgio Sironi <info@giorgiosironi.com>
  14623. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14624. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14625. * @version Release: @package_version@
  14626. * @link http://www.phpunit.de/
  14627. * @since Class available since Release 1.2.0
  14628. */
  14629. class PHPUnit_Extensions_Selenium2TestCase_Driver
  14630. {
  14631. private $seleniumServerUrl;
  14632. private $seleniumServerRequestsTimeout;
  14633. public function __construct(PHPUnit_Extensions_Selenium2TestCase_URL $seleniumServerUrl, $timeout = 60)
  14634. {
  14635. $this->seleniumServerUrl = $seleniumServerUrl;
  14636. $this->seleniumServerRequestsTimeout = $timeout;
  14637. }
  14638. public function startSession(array $desiredCapabilities, PHPUnit_Extensions_Selenium2TestCase_URL $browserUrl)
  14639. {
  14640. $sessionCreation = $this->seleniumServerUrl->descend("/wd/hub/session");
  14641. $response = $this->curl('POST', $sessionCreation, array(
  14642. 'desiredCapabilities' => $desiredCapabilities
  14643. ));
  14644. $sessionPrefix = $response->getURL();
  14645. $timeouts = new PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts(
  14646. $this,
  14647. $sessionPrefix->descend('timeouts'),
  14648. $this->seleniumServerRequestsTimeout * 1000
  14649. );
  14650. return new PHPUnit_Extensions_Selenium2TestCase_Session(
  14651. $this,
  14652. $sessionPrefix,
  14653. $browserUrl,
  14654. $timeouts
  14655. );
  14656. }
  14657. /**
  14658. * Performs an HTTP request to the Selenium 2 server.
  14659. *
  14660. * @param string $method 'GET'|'POST'|'DELETE'|...
  14661. * @param string $url
  14662. * @param array $params JSON parameters for POST requests
  14663. */
  14664. public function curl($http_method,
  14665. PHPUnit_Extensions_Selenium2TestCase_URL $url,
  14666. $params = NULL)
  14667. {
  14668. $curl = curl_init($url->getValue());
  14669. curl_setopt($curl, CURLOPT_TIMEOUT, $this->seleniumServerRequestsTimeout);
  14670. curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
  14671. curl_setopt($curl,
  14672. CURLOPT_HTTPHEADER,
  14673. array(
  14674. 'Content-type: application/json;charset=UTF-8',
  14675. 'Accept: application/json;charset=UTF-8'
  14676. ));
  14677. if ($http_method === 'POST') {
  14678. curl_setopt($curl, CURLOPT_POST, TRUE);
  14679. if ($params && is_array($params)) {
  14680. curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
  14681. } else {
  14682. curl_setopt($curl, CURLOPT_POSTFIELDS, '');
  14683. }
  14684. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
  14685. } else if ($http_method == 'DELETE') {
  14686. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
  14687. }
  14688. $rawResponse = trim(curl_exec($curl));
  14689. if (curl_errno($curl)) {
  14690. throw new PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException(
  14691. 'Error connection[' . curl_errno($curl) . '] to ' .
  14692. $url->getValue() . ': ' . curl_error($curl)
  14693. );
  14694. }
  14695. $info = curl_getinfo($curl);
  14696. if ($info['http_code'] == 0) {
  14697. throw new PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException();
  14698. }
  14699. if ($info['http_code'] == 404) {
  14700. throw new BadMethodCallException("The command $url is not recognized by the server.");
  14701. }
  14702. curl_close($curl);
  14703. $content = json_decode($rawResponse, TRUE);
  14704. if ($info['http_code'] == 500) {
  14705. $message = '';
  14706. if (isset($content['value']['message'])) {
  14707. $message .= $content['value']['message'];
  14708. } else {
  14709. $message .= "Internal server error while executing $http_method request at $url. Response: " . var_export($content, TRUE);
  14710. }
  14711. if (isset($content['value']['class'])) {
  14712. $message .= PHP_EOL . $content['value']['class'];
  14713. }
  14714. throw new PHPUnit_Extensions_Selenium2TestCase_WebDriverException($message, isset($content['status']) ? $content['status'] : 13);
  14715. }
  14716. return new PHPUnit_Extensions_Selenium2TestCase_Response($content, $info);
  14717. }
  14718. public function execute(PHPUnit_Extensions_Selenium2TestCase_Command $command)
  14719. {
  14720. return $this->curl($command->httpMethod(),
  14721. $command->url(),
  14722. $command->jsonParameters());
  14723. }
  14724. }
  14725. <?php
  14726. /**
  14727. * PHPUnit
  14728. *
  14729. * Copyright (c) 2010-2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
  14730. * All rights reserved.
  14731. *
  14732. * Redistribution and use in source and binary forms, with or without
  14733. * modification, are permitted provided that the following conditions
  14734. * are met:
  14735. *
  14736. * * Redistributions of source code must retain the above copyright
  14737. * notice, this list of conditions and the following disclaimer.
  14738. *
  14739. * * Redistributions in binary form must reproduce the above copyright
  14740. * notice, this list of conditions and the following disclaimer in
  14741. * the documentation and/or other materials provided with the
  14742. * distribution.
  14743. *
  14744. * * Neither the name of Sebastian Bergmann nor the names of his
  14745. * contributors may be used to endorse or promote products derived
  14746. * from this software without specific prior written permission.
  14747. *
  14748. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14749. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14750. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14751. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14752. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14753. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14754. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14755. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14756. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14757. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14758. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14759. * POSSIBILITY OF SUCH DAMAGE.
  14760. *
  14761. * @package PHPUnit_Selenium
  14762. * @author Ivan Kurnosov <zerkms@zerkms.com>
  14763. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  14764. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14765. * @link http://www.phpunit.de/
  14766. * @since File available since Release 1.2.12
  14767. */
  14768. /**
  14769. * The WaitUntil implementation, inspired by Java and .NET clients
  14770. *
  14771. * @package PHPUnit_Selenium
  14772. * @author Ivan Kurnosov <zerkms@zerkms.com>
  14773. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  14774. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14775. * @version Release: @package_version@
  14776. * @link http://www.phpunit.de/
  14777. * @since Class available since Release 1.2.12
  14778. * @see http://selenium.googlecode.com/svn/trunk/dotnet/src/WebDriver.Support/UI/WebDriverWait.cs
  14779. * @see http://selenium.googlecode.com/svn/trunk/java/client/src/org/openqa/selenium/support/ui/FluentWait.java
  14780. */
  14781. class PHPUnit_Extensions_Selenium2TestCase_WaitUntil
  14782. {
  14783. /**
  14784. * PHPUnit Test Case instance
  14785. *
  14786. * @var PHPUnit_Extensions_Selenium2TestCase
  14787. */
  14788. private $_testCase;
  14789. /**
  14790. * Default timeout, ms
  14791. *
  14792. * @var int
  14793. */
  14794. private $_defaultTimeout = 0;
  14795. /**
  14796. * The sleep interval between iterations, ms
  14797. *
  14798. * @var int
  14799. */
  14800. private $_defaultSleepInterval = 500;
  14801. /**
  14802. * @param PHPUnit_Extensions_Selenium2TestCase $testCase
  14803. */
  14804. public function __construct(PHPUnit_Extensions_Selenium2TestCase $testCase)
  14805. {
  14806. $this->_testCase = $testCase;
  14807. }
  14808. /**
  14809. * @param $callback Callback to run until it returns not null or timeout occurs
  14810. * @param null $timeout
  14811. * @return mixed
  14812. * @throws PHPUnit_Extensions_Selenium2TestCase_Exception
  14813. * @throws PHPUnit_Extensions_Selenium2TestCase_WebDriverException
  14814. */
  14815. public function run($callback, $timeout = NULL)
  14816. {
  14817. if (!is_callable($callback)) {
  14818. throw new PHPUnit_Extensions_Selenium2TestCase_Exception('The valid callback is expected');
  14819. }
  14820. // if there was an implicit timeout specified - remember it and temporarily turn it off
  14821. $implicitWait = $this->_testCase->timeouts()->getLastImplicitWaitValue();
  14822. if ($implicitWait) {
  14823. $this->_testCase->timeouts()->implicitWait(0);
  14824. }
  14825. if (is_null($timeout)) {
  14826. $timeout = $this->_defaultTimeout;
  14827. }
  14828. $timeout /= 1000;
  14829. $endTime = microtime(TRUE) + $timeout;
  14830. $lastException = NULL;
  14831. while (TRUE) {
  14832. try {
  14833. $result = call_user_func($callback, $this->_testCase);
  14834. if (!is_null($result)) {
  14835. if ($implicitWait) {
  14836. $this->_testCase->timeouts()->implicitWait($implicitWait);
  14837. }
  14838. return $result;
  14839. }
  14840. } catch(Exception $e) {
  14841. $lastException = $e;
  14842. }
  14843. if (microtime(TRUE) > $endTime) {
  14844. if ($implicitWait) {
  14845. $this->_testCase->timeouts()->implicitWait($implicitWait);
  14846. }
  14847. $message = "Timed out after {$timeout} second" . ($timeout != 1 ? 's' : '');
  14848. throw new PHPUnit_Extensions_Selenium2TestCase_WebDriverException($message,
  14849. PHPUnit_Extensions_Selenium2TestCase_WebDriverException::Timeout, $lastException);
  14850. }
  14851. usleep($this->_defaultSleepInterval * 1000);
  14852. }
  14853. }
  14854. }
  14855. <?php
  14856. /**
  14857. * PHPUnit
  14858. *
  14859. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14860. * All rights reserved.
  14861. *
  14862. * Redistribution and use in source and binary forms, with or without
  14863. * modification, are permitted provided that the following conditions
  14864. * are met:
  14865. *
  14866. * * Redistributions of source code must retain the above copyright
  14867. * notice, this list of conditions and the following disclaimer.
  14868. *
  14869. * * Redistributions in binary form must reproduce the above copyright
  14870. * notice, this list of conditions and the following disclaimer in
  14871. * the documentation and/or other materials provided with the
  14872. * distribution.
  14873. *
  14874. * * Neither the name of Sebastian Bergmann nor the names of his
  14875. * contributors may be used to endorse or promote products derived
  14876. * from this software without specific prior written permission.
  14877. *
  14878. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14879. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14880. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14881. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14882. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14883. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14884. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14885. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14886. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14887. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14888. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14889. * POSSIBILITY OF SUCH DAMAGE.
  14890. *
  14891. * @package PHPUnit_Selenium
  14892. * @author Christian Becker <chris@beckr.org>
  14893. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14894. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14895. * @link http://www.phpunit.de/
  14896. * @since
  14897. */
  14898. /**
  14899. * Indicates an exception as a result of a non-sucessful WebDriver response status code.
  14900. *
  14901. * @package PHPUnit_Selenium
  14902. * @author Christian Becker <chris@beckr.org>
  14903. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14904. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14905. * @version Release: @package_version@
  14906. * @link http://www.phpunit.de/
  14907. * @since
  14908. */
  14909. class PHPUnit_Extensions_Selenium2TestCase_WebDriverException extends PHPUnit_Extensions_Selenium2TestCase_Exception
  14910. {
  14911. /* @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes */
  14912. const Success = 0;
  14913. const NoSuchDriver = 6;
  14914. const NoSuchElement = 7;
  14915. const NoSuchFrame = 8;
  14916. const UnknownCommand = 9;
  14917. const StaleElementReference = 10;
  14918. const ElementNotVisible = 11;
  14919. const InvalidElementState = 12;
  14920. const UnknownError = 13;
  14921. const ElementIsNotSelectable = 15;
  14922. const JavaScriptError = 17;
  14923. const XPathLookupError = 19;
  14924. const Timeout = 21;
  14925. const NoSuchWindow = 23;
  14926. const InvalidCookieDomain = 24;
  14927. const UnableToSetCookie = 25;
  14928. const UnexpectedAlertOpen = 26;
  14929. const NoAlertOpenError = 27;
  14930. const ScriptTimeout = 28;
  14931. const InvalidElementCoordinates = 29;
  14932. const IMENotAvailable = 30;
  14933. const IMEEngineActivationFailed = 31;
  14934. const InvalidSelector = 32;
  14935. const SessionNotCreatedException = 33;
  14936. const MoveTargetOutOfBounds = 34;
  14937. }<?php
  14938. /**
  14939. * PHPUnit
  14940. *
  14941. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14942. * All rights reserved.
  14943. *
  14944. * Redistribution and use in source and binary forms, with or without
  14945. * modification, are permitted provided that the following conditions
  14946. * are met:
  14947. *
  14948. * * Redistributions of source code must retain the above copyright
  14949. * notice, this list of conditions and the following disclaimer.
  14950. *
  14951. * * Redistributions in binary form must reproduce the above copyright
  14952. * notice, this list of conditions and the following disclaimer in
  14953. * the documentation and/or other materials provided with the
  14954. * distribution.
  14955. *
  14956. * * Neither the name of Sebastian Bergmann nor the names of his
  14957. * contributors may be used to endorse or promote products derived
  14958. * from this software without specific prior written permission.
  14959. *
  14960. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14961. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14962. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14963. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14964. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14965. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14966. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14967. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14968. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14969. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14970. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14971. * POSSIBILITY OF SUCH DAMAGE.
  14972. *
  14973. * @package PHPUnit_Selenium
  14974. * @author Christian Soronellas <csoronellas@emagister.com>
  14975. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14976. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14977. * @link http://www.phpunit.de/
  14978. * @since File available since Release 1.2.0
  14979. */
  14980. /**
  14981. * Gets or sets the current URL of the window.
  14982. *
  14983. * @package PHPUnit_Selenium
  14984. * @author Christian Soronellas <csoronellas@emagister.com>
  14985. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14986. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14987. * @version Release: @package_version@
  14988. * @link http://www.phpunit.de/
  14989. * @since Class available since Release 1.2.0
  14990. */
  14991. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys
  14992. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14993. {
  14994. public function __construct($jsonParameters,
  14995. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  14996. {
  14997. if ($jsonParameters === NULL) {
  14998. parent::__construct(NULL, $url);
  14999. } else {
  15000. $jsonParameters = $this->keysForText($jsonParameters);
  15001. parent::__construct($jsonParameters, $url);
  15002. }
  15003. }
  15004. /**
  15005. * @return string
  15006. */
  15007. public function httpMethod()
  15008. {
  15009. return 'POST';
  15010. }
  15011. /**
  15012. * Given a string returns an array of the characters that compose the string
  15013. *
  15014. * @param string $text
  15015. * @throws InvalidArgumentException
  15016. * @return array
  15017. */
  15018. public function keysForText($text)
  15019. {
  15020. if (is_scalar($text)) {
  15021. return array('value' => preg_split('//u', (string) $text, -1, PREG_SPLIT_NO_EMPTY));
  15022. }
  15023. if (is_array($text)) {
  15024. return $text;
  15025. }
  15026. throw new InvalidArgumentException('The "text" argument should be a string or an array of special characters!');
  15027. }
  15028. }
  15029. <?php
  15030. /**
  15031. * PHPUnit
  15032. *
  15033. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15034. * All rights reserved.
  15035. *
  15036. * Redistribution and use in source and binary forms, with or without
  15037. * modification, are permitted provided that the following conditions
  15038. * are met:
  15039. *
  15040. * * Redistributions of source code must retain the above copyright
  15041. * notice, this list of conditions and the following disclaimer.
  15042. *
  15043. * * Redistributions in binary form must reproduce the above copyright
  15044. * notice, this list of conditions and the following disclaimer in
  15045. * the documentation and/or other materials provided with the
  15046. * distribution.
  15047. *
  15048. * * Neither the name of Sebastian Bergmann nor the names of his
  15049. * contributors may be used to endorse or promote products derived
  15050. * from this software without specific prior written permission.
  15051. *
  15052. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15053. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15054. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15055. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15056. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15057. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15058. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15059. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15060. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15061. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15062. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15063. * POSSIBILITY OF SUCH DAMAGE.
  15064. *
  15065. * @package PHPUnit_Selenium
  15066. * @author Giorgio Sironi <info@giorgiosironi.com>
  15067. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15068. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15069. * @link http://www.phpunit.de/
  15070. * @since File available since Release 1.2.13
  15071. */
  15072. /**
  15073. * Sends session click command for emulating LEFT, MIDDLE or RIGHT mouse buttons
  15074. *
  15075. * @package PHPUnit_Selenium
  15076. * @author Ivan Kurnosov <zerkms@zerkms.com>
  15077. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15078. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15079. * @version Release: @package_version@
  15080. * @link http://www.phpunit.de/
  15081. * @since Class available since Release 1.2.13
  15082. */
  15083. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Click
  15084. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15085. {
  15086. const LEFT = 0;
  15087. const MIDDLE = 1;
  15088. const RIGHT = 2;
  15089. public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url)
  15090. {
  15091. if (is_null($argument)) {
  15092. $jsonParameters = NULL;
  15093. } elseif (!is_scalar($argument) || !in_array($argument, array(
  15094. self::LEFT, self::RIGHT, self::MIDDLE
  15095. ))) {
  15096. throw new BadMethodCallException('Wrong parameter for click(): expecting 0, 1 or 2.');
  15097. } else {
  15098. $jsonParameters = array('button' => $argument);
  15099. }
  15100. parent::__construct($jsonParameters, $url);
  15101. }
  15102. public function httpMethod()
  15103. {
  15104. return 'POST';
  15105. }
  15106. }
  15107. <?php
  15108. /**
  15109. * PHPUnit
  15110. *
  15111. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15112. * All rights reserved.
  15113. *
  15114. * Redistribution and use in source and binary forms, with or without
  15115. * modification, are permitted provided that the following conditions
  15116. * are met:
  15117. *
  15118. * * Redistributions of source code must retain the above copyright
  15119. * notice, this list of conditions and the following disclaimer.
  15120. *
  15121. * * Redistributions in binary form must reproduce the above copyright
  15122. * notice, this list of conditions and the following disclaimer in
  15123. * the documentation and/or other materials provided with the
  15124. * distribution.
  15125. *
  15126. * * Neither the name of Sebastian Bergmann nor the names of his
  15127. * contributors may be used to endorse or promote products derived
  15128. * from this software without specific prior written permission.
  15129. *
  15130. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15131. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15132. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15133. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15134. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15135. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15136. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15137. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15138. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15139. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15140. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15141. * POSSIBILITY OF SUCH DAMAGE.
  15142. *
  15143. * @package PHPUnit_Selenium
  15144. * @author Jonathan Lipps <jlipps@gmail.com>
  15145. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15146. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15147. * @link http://www.phpunit.de/
  15148. * @since File available since Release 1.2.0
  15149. */
  15150. /**
  15151. * Gets or posts an attribute from/to the session (title, alert text, etc.)
  15152. *
  15153. * @package PHPUnit_Selenium
  15154. * @author Jonathan Lipps <jlipps@gmail.com>
  15155. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15156. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15157. * @version Release: @package_version@
  15158. * @link http://www.phpunit.de/
  15159. * @since Class available since Release 1.2.9
  15160. */
  15161. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Location
  15162. extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute
  15163. {
  15164. public function __construct($location, $commandUrl)
  15165. {
  15166. if ($location !== NULL) {
  15167. $jsonParameters = array('location' => $location);
  15168. } else {
  15169. $jsonParameters = NULL;
  15170. }
  15171. parent::__construct($jsonParameters, $commandUrl);
  15172. }
  15173. public function httpMethod()
  15174. {
  15175. if ($this->jsonParameters) {
  15176. return 'POST';
  15177. }
  15178. return 'GET';
  15179. }
  15180. }
  15181. <?php
  15182. /**
  15183. * PHPUnit
  15184. *
  15185. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15186. * All rights reserved.
  15187. *
  15188. * Redistribution and use in source and binary forms, with or without
  15189. * modification, are permitted provided that the following conditions
  15190. * are met:
  15191. *
  15192. * * Redistributions of source code must retain the above copyright
  15193. * notice, this list of conditions and the following disclaimer.
  15194. *
  15195. * * Redistributions in binary form must reproduce the above copyright
  15196. * notice, this list of conditions and the following disclaimer in
  15197. * the documentation and/or other materials provided with the
  15198. * distribution.
  15199. *
  15200. * * Neither the name of Sebastian Bergmann nor the names of his
  15201. * contributors may be used to endorse or promote products derived
  15202. * from this software without specific prior written permission.
  15203. *
  15204. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15205. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15206. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15207. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15208. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15209. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15210. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15211. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15212. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15213. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15214. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15215. * POSSIBILITY OF SUCH DAMAGE.
  15216. *
  15217. * @package PHPUnit_Selenium
  15218. * @author Giorgio Sironi <info@giorgiosironi.com>
  15219. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15220. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15221. * @link http://www.phpunit.de/
  15222. * @since File available since Release 1.2.0
  15223. */
  15224. /**
  15225. * Gets an attribute from the session (title, alert text, etc.)
  15226. *
  15227. * @package PHPUnit_Selenium
  15228. * @author Giorgio Sironi <info@giorgiosironi.com>
  15229. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15230. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15231. * @version Release: @package_version@
  15232. * @link http://www.phpunit.de/
  15233. * @since Class available since Release 1.2.0
  15234. */
  15235. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor
  15236. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15237. {
  15238. public function httpMethod()
  15239. {
  15240. return 'GET';
  15241. }
  15242. }
  15243. <?php
  15244. /**
  15245. * PHPUnit
  15246. *
  15247. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15248. * All rights reserved.
  15249. *
  15250. * Redistribution and use in source and binary forms, with or without
  15251. * modification, are permitted provided that the following conditions
  15252. * are met:
  15253. *
  15254. * * Redistributions of source code must retain the above copyright
  15255. * notice, this list of conditions and the following disclaimer.
  15256. *
  15257. * * Redistributions in binary form must reproduce the above copyright
  15258. * notice, this list of conditions and the following disclaimer in
  15259. * the documentation and/or other materials provided with the
  15260. * distribution.
  15261. *
  15262. * * Neither the name of Sebastian Bergmann nor the names of his
  15263. * contributors may be used to endorse or promote products derived
  15264. * from this software without specific prior written permission.
  15265. *
  15266. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15267. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15268. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15269. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15270. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15271. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15272. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15273. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15274. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15275. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15276. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15277. * POSSIBILITY OF SUCH DAMAGE.
  15278. *
  15279. * @package PHPUnit_Selenium
  15280. * @author Giorgio Sironi <info@giorgiosironi.com>
  15281. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15282. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15283. * @link http://www.phpunit.de/
  15284. * @since File available since Release 1.3.2
  15285. */
  15286. /**
  15287. * Sends a file to a RC
  15288. * Returns the FQ path to the transfered file
  15289. *
  15290. * @package PHPUnit_Selenium
  15291. * @author Kevin Ran <heilong24@gmail.com>
  15292. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15293. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15294. * @version Release: @package_version@
  15295. * @link http://www.phpunit.de/
  15296. * @since Class available since Release 1.3.2
  15297. */
  15298. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_File
  15299. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15300. {
  15301. /**
  15302. * @var
  15303. */
  15304. private static $_zipArchive;
  15305. public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url)
  15306. {
  15307. if (!is_file($argument)) {
  15308. throw new BadMethodCallException("No such file: {$argument}");
  15309. }
  15310. $zipfile_path = $this->_zipArchiveFile($argument);
  15311. $contents = file_get_contents($zipfile_path);
  15312. if ($contents === false) {
  15313. throw new Exception("Unable to read generated zip file: {$zipfile_path}");
  15314. }
  15315. $file = base64_encode($contents);
  15316. parent::__construct(array('file' => $file), $url);
  15317. unlink($zipfile_path);
  15318. }
  15319. public function httpMethod()
  15320. {
  15321. return 'POST';
  15322. }
  15323. /**
  15324. * Creates a zip archive with the given file
  15325. *
  15326. * @param string $file_path FQ path to file
  15327. * @return string Generated zip file
  15328. */
  15329. protected function _zipArchiveFile( $file_path )
  15330. {
  15331. // file MUST be readable
  15332. if( !is_readable( $file_path ) ) {
  15333. throw new Exception( "Unable to read {$file_path}" );
  15334. } // if !file_data
  15335. $filename_hash = sha1( time() . $file_path );
  15336. $tmp_dir = $this->_getTmpDir();
  15337. $zip_filename = "{$tmp_dir}{$filename_hash}.zip";
  15338. $zip = $this->_getZipArchiver();
  15339. if ($zip->open($zip_filename, ZIPARCHIVE::CREATE) === FALSE) {
  15340. throw new Exception( "Unable to create zip archive: {$zip_filename}" );
  15341. }
  15342. $zip->addFile($file_path, basename($file_path));
  15343. $zip->close();
  15344. return $zip_filename;
  15345. }
  15346. /**
  15347. * Returns a runtime instance of a ZipArchive
  15348. *
  15349. * @return ZipArchive
  15350. */
  15351. protected function _getZipArchiver()
  15352. {
  15353. // create ZipArchive if necessary
  15354. if (!static::$_zipArchive) {
  15355. static::$_zipArchive = new ZipArchive();
  15356. }
  15357. return static::$_zipArchive;
  15358. }
  15359. /**
  15360. * Calls sys_get_temp_dir and ensures that it has a trailing slash
  15361. * ( behavior varies across systems )
  15362. *
  15363. * @return string
  15364. */
  15365. protected function _getTmpDir()
  15366. {
  15367. return rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
  15368. }
  15369. }
  15370. <?php
  15371. /**
  15372. * PHPUnit
  15373. *
  15374. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15375. * All rights reserved.
  15376. *
  15377. * Redistribution and use in source and binary forms, with or without
  15378. * modification, are permitted provided that the following conditions
  15379. * are met:
  15380. *
  15381. * * Redistributions of source code must retain the above copyright
  15382. * notice, this list of conditions and the following disclaimer.
  15383. *
  15384. * * Redistributions in binary form must reproduce the above copyright
  15385. * notice, this list of conditions and the following disclaimer in
  15386. * the documentation and/or other materials provided with the
  15387. * distribution.
  15388. *
  15389. * * Neither the name of Sebastian Bergmann nor the names of his
  15390. * contributors may be used to endorse or promote products derived
  15391. * from this software without specific prior written permission.
  15392. *
  15393. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15394. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15395. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15396. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15397. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15398. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15399. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15400. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15401. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15402. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15403. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15404. * POSSIBILITY OF SUCH DAMAGE.
  15405. *
  15406. * @package PHPUnit_Selenium
  15407. * @author Giorgio Sironi <info@giorgiosironi.com>
  15408. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15409. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15410. * @link http://www.phpunit.de/
  15411. * @since File available since Release 1.2.0
  15412. */
  15413. /**
  15414. * Clicks Ok on an alert popup.
  15415. *
  15416. * @package PHPUnit_Selenium
  15417. * @author Giorgio Sironi <info@giorgiosironi.com>
  15418. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15419. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15420. * @version Release: @package_version@
  15421. * @link http://www.phpunit.de/
  15422. * @since Class available since Release 1.2.0
  15423. */
  15424. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AcceptAlert
  15425. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15426. {
  15427. public function httpMethod()
  15428. {
  15429. return 'POST';
  15430. }
  15431. }
  15432. <?php
  15433. /**
  15434. * PHPUnit
  15435. *
  15436. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15437. * All rights reserved.
  15438. *
  15439. * Redistribution and use in source and binary forms, with or without
  15440. * modification, are permitted provided that the following conditions
  15441. * are met:
  15442. *
  15443. * * Redistributions of source code must retain the above copyright
  15444. * notice, this list of conditions and the following disclaimer.
  15445. *
  15446. * * Redistributions in binary form must reproduce the above copyright
  15447. * notice, this list of conditions and the following disclaimer in
  15448. * the documentation and/or other materials provided with the
  15449. * distribution.
  15450. *
  15451. * * Neither the name of Sebastian Bergmann nor the names of his
  15452. * contributors may be used to endorse or promote products derived
  15453. * from this software without specific prior written permission.
  15454. *
  15455. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15456. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15457. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15458. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15459. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15460. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15461. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15462. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15463. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15464. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15465. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15466. * POSSIBILITY OF SUCH DAMAGE.
  15467. *
  15468. * @package PHPUnit_Selenium
  15469. * @author Giorgio Sironi <info@giorgiosironi.com>
  15470. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15471. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15472. * @link http://www.phpunit.de/
  15473. * @since File available since Release 1.2.4
  15474. */
  15475. /**
  15476. * Obtains the text of an alert, or types into a prompt.
  15477. *
  15478. * @package PHPUnit_Selenium
  15479. * @author Giorgio Sironi <info@giorgiosironi.com>
  15480. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15481. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15482. * @version Release: @package_version@
  15483. * @link http://www.phpunit.de/
  15484. * @since Class available since Release 1.2.4
  15485. */
  15486. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AlertText
  15487. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15488. {
  15489. public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url)
  15490. {
  15491. if (is_string($argument)) {
  15492. $jsonParameters =array('text' => $argument);
  15493. } else if ($argument == NULL) {
  15494. $jsonParameters = NULL;
  15495. } else {
  15496. throw new BadMethodCallException('Wrong parameters for alertText().');
  15497. }
  15498. parent::__construct($jsonParameters, $url);
  15499. }
  15500. public function httpMethod()
  15501. {
  15502. if ($this->jsonParameters) {
  15503. return 'POST';
  15504. }
  15505. return 'GET';
  15506. }
  15507. }
  15508. <?php
  15509. /**
  15510. * PHPUnit
  15511. *
  15512. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15513. * All rights reserved.
  15514. *
  15515. * Redistribution and use in source and binary forms, with or without
  15516. * modification, are permitted provided that the following conditions
  15517. * are met:
  15518. *
  15519. * * Redistributions of source code must retain the above copyright
  15520. * notice, this list of conditions and the following disclaimer.
  15521. *
  15522. * * Redistributions in binary form must reproduce the above copyright
  15523. * notice, this list of conditions and the following disclaimer in
  15524. * the documentation and/or other materials provided with the
  15525. * distribution.
  15526. *
  15527. * * Neither the name of Sebastian Bergmann nor the names of his
  15528. * contributors may be used to endorse or promote products derived
  15529. * from this software without specific prior written permission.
  15530. *
  15531. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15532. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15533. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15534. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15535. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15536. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15537. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15538. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15539. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15540. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15541. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15542. * POSSIBILITY OF SUCH DAMAGE.
  15543. *
  15544. * @package PHPUnit_Selenium
  15545. * @author Giorgio Sironi <info@giorgiosironi.com>
  15546. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15547. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15548. * @link http://www.phpunit.de/
  15549. * @since File available since Release 1.2.0
  15550. */
  15551. /**
  15552. * Gets or sets the current URL of the window.
  15553. *
  15554. * @package PHPUnit_Selenium
  15555. * @author Giorgio Sironi <info@giorgiosironi.com>
  15556. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15557. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15558. * @version Release: @package_version@
  15559. * @link http://www.phpunit.de/
  15560. * @since Class available since Release 1.2.0
  15561. */
  15562. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Url
  15563. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15564. {
  15565. public function __construct($url, $commandUrl, PHPUnit_Extensions_Selenium2TestCase_URL $baseUrl)
  15566. {
  15567. if ($url !== NULL) {
  15568. $absoluteLocation = $baseUrl->jump($url)->getValue();
  15569. $jsonParameters = array('url' => $absoluteLocation);
  15570. } else {
  15571. $jsonParameters = NULL;
  15572. }
  15573. parent::__construct($jsonParameters, $commandUrl);
  15574. }
  15575. public function httpMethod()
  15576. {
  15577. if ($this->jsonParameters) {
  15578. return 'POST';
  15579. }
  15580. return 'GET';
  15581. }
  15582. }
  15583. <?php
  15584. /**
  15585. * PHPUnit
  15586. *
  15587. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15588. * All rights reserved.
  15589. *
  15590. * Redistribution and use in source and binary forms, with or without
  15591. * modification, are permitted provided that the following conditions
  15592. * are met:
  15593. *
  15594. * * Redistributions of source code must retain the above copyright
  15595. * notice, this list of conditions and the following disclaimer.
  15596. *
  15597. * * Redistributions in binary form must reproduce the above copyright
  15598. * notice, this list of conditions and the following disclaimer in
  15599. * the documentation and/or other materials provided with the
  15600. * distribution.
  15601. *
  15602. * * Neither the name of Sebastian Bergmann nor the names of his
  15603. * contributors may be used to endorse or promote products derived
  15604. * from this software without specific prior written permission.
  15605. *
  15606. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15607. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15608. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15609. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15610. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15611. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15612. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15613. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15614. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15615. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15616. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15617. * POSSIBILITY OF SUCH DAMAGE.
  15618. *
  15619. * @package PHPUnit_Selenium
  15620. * @author Giorgio Sironi <info@giorgiosironi.com>
  15621. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15622. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15623. * @link http://www.phpunit.de/
  15624. * @since File available since Release 1.2.4
  15625. */
  15626. /**
  15627. * Changes the focus to a window.
  15628. *
  15629. * @package PHPUnit_Selenium
  15630. * @author Giorgio Sironi <info@giorgiosironi.com>
  15631. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15632. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15633. * @version Release: @package_version@
  15634. * @link http://www.phpunit.de/
  15635. * @since Class available since Release 1.2.4
  15636. */
  15637. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Window
  15638. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15639. {
  15640. public function __construct($name, $commandUrl)
  15641. {
  15642. $jsonParameters = array('name' => $name);
  15643. parent::__construct($jsonParameters, $commandUrl);
  15644. }
  15645. public function httpMethod()
  15646. {
  15647. return 'POST';
  15648. }
  15649. }
  15650. <?php
  15651. /**
  15652. * PHPUnit
  15653. *
  15654. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15655. * All rights reserved.
  15656. *
  15657. * Redistribution and use in source and binary forms, with or without
  15658. * modification, are permitted provided that the following conditions
  15659. * are met:
  15660. *
  15661. * * Redistributions of source code must retain the above copyright
  15662. * notice, this list of conditions and the following disclaimer.
  15663. *
  15664. * * Redistributions in binary form must reproduce the above copyright
  15665. * notice, this list of conditions and the following disclaimer in
  15666. * the documentation and/or other materials provided with the
  15667. * distribution.
  15668. *
  15669. * * Neither the name of Sebastian Bergmann nor the names of his
  15670. * contributors may be used to endorse or promote products derived
  15671. * from this software without specific prior written permission.
  15672. *
  15673. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15674. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15675. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15676. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15677. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15678. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15679. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15680. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15681. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15682. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15683. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15684. * POSSIBILITY OF SUCH DAMAGE.
  15685. *
  15686. * @package PHPUnit_Selenium
  15687. * @author Jonathan Lipps <jlipps@gmail.com>
  15688. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15689. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15690. * @link http://www.phpunit.de/
  15691. * @since File available since Release 1.2.0
  15692. */
  15693. /**
  15694. * Gets or posts an attribute from/to the session (title, alert text, etc.)
  15695. *
  15696. * @package PHPUnit_Selenium
  15697. * @author Jonathan Lipps <jlipps@gmail.com>
  15698. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15699. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15700. * @version Release: @package_version@
  15701. * @link http://www.phpunit.de/
  15702. * @since Class available since Release 1.2.9
  15703. */
  15704. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute
  15705. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15706. {
  15707. public function httpMethod()
  15708. {
  15709. if ($this->jsonParameters) {
  15710. return 'POST';
  15711. }
  15712. return 'GET';
  15713. }
  15714. }
  15715. <?php
  15716. /**
  15717. * PHPUnit
  15718. *
  15719. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15720. * All rights reserved.
  15721. *
  15722. * Redistribution and use in source and binary forms, with or without
  15723. * modification, are permitted provided that the following conditions
  15724. * are met:
  15725. *
  15726. * * Redistributions of source code must retain the above copyright
  15727. * notice, this list of conditions and the following disclaimer.
  15728. *
  15729. * * Redistributions in binary form must reproduce the above copyright
  15730. * notice, this list of conditions and the following disclaimer in
  15731. * the documentation and/or other materials provided with the
  15732. * distribution.
  15733. *
  15734. * * Neither the name of Sebastian Bergmann nor the names of his
  15735. * contributors may be used to endorse or promote products derived
  15736. * from this software without specific prior written permission.
  15737. *
  15738. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15739. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15740. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15741. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15742. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15743. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15744. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15745. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15746. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15747. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15748. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15749. * POSSIBILITY OF SUCH DAMAGE.
  15750. *
  15751. * @package PHPUnit_Selenium
  15752. * @author Giorgio Sironi <info@giorgiosironi.com>
  15753. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15754. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15755. * @link http://www.phpunit.de/
  15756. * @since File available since Release 1.2.8
  15757. */
  15758. /**
  15759. * Moves the mouse pointer.
  15760. *
  15761. * @author Giorgio Sironi <info@giorgiosironi.com>
  15762. * @package PHPUnit_Selenium
  15763. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15764. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15765. * @version Release: @package_version@
  15766. * @link http://www.phpunit.de/
  15767. * @since Class available since Release 1.2.8
  15768. */
  15769. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_MoveTo
  15770. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15771. {
  15772. public function __construct($element,
  15773. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  15774. {
  15775. if (!is_array($element)) {
  15776. $element = array(
  15777. 'element' => $element,
  15778. );
  15779. }
  15780. $validKeys = array(
  15781. 'element' => NULL,
  15782. 'xoffset' => NULL,
  15783. 'yoffset' => NULL,
  15784. );
  15785. $jsonParameters = array_intersect_key($element, $validKeys);
  15786. if (isset($jsonParameters['element'])) {
  15787. if (!($jsonParameters['element'] instanceof PHPUnit_Extensions_Selenium2TestCase_Element)) {
  15788. throw new PHPUnit_Extensions_Selenium2TestCase_Exception('Only moving over an element is supported. Please pass a PHPUnit_Extensions_Selenium2TestCase_Element instance.');
  15789. }
  15790. $jsonParameters['element'] = $jsonParameters['element']->getId();
  15791. }
  15792. if (isset($jsonParameters['xoffset']) || isset($jsonParameters['yoffset'])) {
  15793. // @see https://github.com/sebastianbergmann/phpunit-selenium/pull/250#issuecomment-21308153
  15794. // @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/moveto
  15795. error_log('Even though this method is a part of the WebDriver Wire protocol it might be not supported by your browser yet');
  15796. }
  15797. parent::__construct($jsonParameters, $url);
  15798. }
  15799. /**
  15800. * @return string
  15801. */
  15802. public function httpMethod()
  15803. {
  15804. return 'POST';
  15805. }
  15806. }
  15807. <?php
  15808. /**
  15809. * PHPUnit
  15810. *
  15811. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15812. * All rights reserved.
  15813. *
  15814. * Redistribution and use in source and binary forms, with or without
  15815. * modification, are permitted provided that the following conditions
  15816. * are met:
  15817. *
  15818. * * Redistributions of source code must retain the above copyright
  15819. * notice, this list of conditions and the following disclaimer.
  15820. *
  15821. * * Redistributions in binary form must reproduce the above copyright
  15822. * notice, this list of conditions and the following disclaimer in
  15823. * the documentation and/or other materials provided with the
  15824. * distribution.
  15825. *
  15826. * * Neither the name of Sebastian Bergmann nor the names of his
  15827. * contributors may be used to endorse or promote products derived
  15828. * from this software without specific prior written permission.
  15829. *
  15830. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15831. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15832. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15833. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15834. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15835. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15836. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15837. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15838. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15839. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15840. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15841. * POSSIBILITY OF SUCH DAMAGE.
  15842. *
  15843. * @package PHPUnit_Selenium
  15844. * @author Jonathan Lipps <jlipps@gmail.com>
  15845. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15846. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15847. * @link http://www.phpunit.de/
  15848. * @since File available since Release 1.2.0
  15849. */
  15850. /**
  15851. * Gets or posts an attribute from/to the session (title, alert text, etc.)
  15852. *
  15853. * @package PHPUnit_Selenium
  15854. * @author Jonathan Lipps <jlipps@gmail.com>
  15855. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15856. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15857. * @version Release: @package_version@
  15858. * @link http://www.phpunit.de/
  15859. * @since Class available since Release 1.2.9
  15860. */
  15861. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Orientation
  15862. extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute
  15863. {
  15864. public function __construct($orientation, $commandUrl)
  15865. {
  15866. if ($orientation !== NULL) {
  15867. $jsonParameters = array('orientation' => $orientation);
  15868. } else {
  15869. $jsonParameters = NULL;
  15870. }
  15871. parent::__construct($jsonParameters, $commandUrl);
  15872. }
  15873. public function httpMethod()
  15874. {
  15875. if ($this->jsonParameters) {
  15876. return 'POST';
  15877. }
  15878. return 'GET';
  15879. }
  15880. }
  15881. <?php
  15882. /**
  15883. * PHPUnit
  15884. *
  15885. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15886. * All rights reserved.
  15887. *
  15888. * Redistribution and use in source and binary forms, with or without
  15889. * modification, are permitted provided that the following conditions
  15890. * are met:
  15891. *
  15892. * * Redistributions of source code must retain the above copyright
  15893. * notice, this list of conditions and the following disclaimer.
  15894. *
  15895. * * Redistributions in binary form must reproduce the above copyright
  15896. * notice, this list of conditions and the following disclaimer in
  15897. * the documentation and/or other materials provided with the
  15898. * distribution.
  15899. *
  15900. * * Neither the name of Sebastian Bergmann nor the names of his
  15901. * contributors may be used to endorse or promote products derived
  15902. * from this software without specific prior written permission.
  15903. *
  15904. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15905. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15906. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15907. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15908. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15909. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15910. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15911. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15912. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15913. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15914. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15915. * POSSIBILITY OF SUCH DAMAGE.
  15916. *
  15917. * @package PHPUnit_Selenium
  15918. * @author Andrew Krasichkov <krasichkovandrew@gmail.com>
  15919. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15920. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15921. * @link http://www.phpunit.de/
  15922. * @since File available since Release 1.3.2
  15923. */
  15924. /**
  15925. * Get the log for a given log type. Log buffer is reset after each request.
  15926. *
  15927. * @package PHPUnit_Selenium
  15928. * @author Andrew Krasichkov <krasichkovandrew@gmail.com>
  15929. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15930. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15931. * @version Release: @package_version@
  15932. * @link http://www.phpunit.de/
  15933. * @since Class available since Release 1.3.2
  15934. */
  15935. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Log
  15936. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15937. {
  15938. public function __construct($type, $commandUrl)
  15939. {
  15940. $jsonParameters = array('type' => $type);
  15941. parent::__construct($jsonParameters, $commandUrl);
  15942. }
  15943. public function httpMethod()
  15944. {
  15945. return 'POST';
  15946. }
  15947. }<?php
  15948. /**
  15949. * PHPUnit
  15950. *
  15951. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15952. * All rights reserved.
  15953. *
  15954. * Redistribution and use in source and binary forms, with or without
  15955. * modification, are permitted provided that the following conditions
  15956. * are met:
  15957. *
  15958. * * Redistributions of source code must retain the above copyright
  15959. * notice, this list of conditions and the following disclaimer.
  15960. *
  15961. * * Redistributions in binary form must reproduce the above copyright
  15962. * notice, this list of conditions and the following disclaimer in
  15963. * the documentation and/or other materials provided with the
  15964. * distribution.
  15965. *
  15966. * * Neither the name of Sebastian Bergmann nor the names of his
  15967. * contributors may be used to endorse or promote products derived
  15968. * from this software without specific prior written permission.
  15969. *
  15970. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15971. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15972. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15973. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15974. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15975. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15976. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15977. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15978. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15979. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15980. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15981. * POSSIBILITY OF SUCH DAMAGE.
  15982. *
  15983. * @package PHPUnit_Selenium
  15984. * @author Giorgio Sironi <info@giorgiosironi.com>
  15985. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15986. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15987. * @link http://www.phpunit.de/
  15988. * @since File available since Release
  15989. */
  15990. /**
  15991. * Gets the active element from the session
  15992. *
  15993. * @package PHPUnit_Selenium
  15994. * @author Marcel Erz <marcel.erz@gmail.com>
  15995. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15996. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15997. * @version Release: @package_version@
  15998. * @link http://www.phpunit.de/
  15999. * @since Class available since Release
  16000. */
  16001. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Active
  16002. extends PHPUnit_Extensions_Selenium2TestCase_Command
  16003. {
  16004. public function __construct($jsonParameters, PHPUnit_Extensions_Selenium2TestCase_URL $url)
  16005. {
  16006. $url = $url->addCommand('element')->addCommand('active');
  16007. parent::__construct($jsonParameters, $url);
  16008. }
  16009. public function httpMethod()
  16010. {
  16011. return 'POST';
  16012. }
  16013. }
  16014. <?php
  16015. /**
  16016. * PHPUnit
  16017. *
  16018. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16019. * All rights reserved.
  16020. *
  16021. * Redistribution and use in source and binary forms, with or without
  16022. * modification, are permitted provided that the following conditions
  16023. * are met:
  16024. *
  16025. * * Redistributions of source code must retain the above copyright
  16026. * notice, this list of conditions and the following disclaimer.
  16027. *
  16028. * * Redistributions in binary form must reproduce the above copyright
  16029. * notice, this list of conditions and the following disclaimer in
  16030. * the documentation and/or other materials provided with the
  16031. * distribution.
  16032. *
  16033. * * Neither the name of Sebastian Bergmann nor the names of his
  16034. * contributors may be used to endorse or promote products derived
  16035. * from this software without specific prior written permission.
  16036. *
  16037. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16038. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16039. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16040. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16041. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16042. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16043. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16044. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16045. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16046. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16047. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16048. * POSSIBILITY OF SUCH DAMAGE.
  16049. *
  16050. * @package PHPUnit_Selenium
  16051. * @author Giorgio Sironi <info@giorgiosironi.com>
  16052. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16053. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16054. * @link http://www.phpunit.de/
  16055. * @since File available since Release 1.2.0
  16056. */
  16057. /**
  16058. * Clicks Cancel on an alert popup.
  16059. *
  16060. * @package PHPUnit_Selenium
  16061. * @author Giorgio Sironi <info@giorgiosironi.com>
  16062. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16063. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16064. * @version Release: @package_version@
  16065. * @link http://www.phpunit.de/
  16066. * @since Class available since Release 1.2.0
  16067. */
  16068. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_DismissAlert
  16069. extends PHPUnit_Extensions_Selenium2TestCase_Command
  16070. {
  16071. public function httpMethod()
  16072. {
  16073. return 'POST';
  16074. }
  16075. }
  16076. <?php
  16077. /**
  16078. * PHPUnit
  16079. *
  16080. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16081. * All rights reserved.
  16082. *
  16083. * Redistribution and use in source and binary forms, with or without
  16084. * modification, are permitted provided that the following conditions
  16085. * are met:
  16086. *
  16087. * * Redistributions of source code must retain the above copyright
  16088. * notice, this list of conditions and the following disclaimer.
  16089. *
  16090. * * Redistributions in binary form must reproduce the above copyright
  16091. * notice, this list of conditions and the following disclaimer in
  16092. * the documentation and/or other materials provided with the
  16093. * distribution.
  16094. *
  16095. * * Neither the name of Sebastian Bergmann nor the names of his
  16096. * contributors may be used to endorse or promote products derived
  16097. * from this software without specific prior written permission.
  16098. *
  16099. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16100. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16101. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16102. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16103. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16104. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16105. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16106. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16107. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16108. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16109. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16110. * POSSIBILITY OF SUCH DAMAGE.
  16111. *
  16112. * @package PHPUnit_Selenium
  16113. * @author Giorgio Sironi <info@giorgiosironi.com>
  16114. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16115. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16116. * @link http://www.phpunit.de/
  16117. * @since File available since Release 1.2.4
  16118. */
  16119. /**
  16120. * Changes the focus to a frame.
  16121. *
  16122. * @package PHPUnit_Selenium
  16123. * @author Giorgio Sironi <info@giorgiosironi.com>
  16124. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16125. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16126. * @version Release: @package_version@
  16127. * @link http://www.phpunit.de/
  16128. * @since Class available since Release 1.2.4
  16129. */
  16130. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Frame
  16131. extends PHPUnit_Extensions_Selenium2TestCase_Command
  16132. {
  16133. public function __construct($id, $commandUrl)
  16134. {
  16135. $jsonParameters = array(
  16136. 'id' => $this->extractId($id)
  16137. );
  16138. parent::__construct($jsonParameters, $commandUrl);
  16139. }
  16140. /**
  16141. * @param $id
  16142. * @return array
  16143. */
  16144. private function extractId($id)
  16145. {
  16146. if ($this->isElement($id)) { //selenium-element
  16147. return $id->toWebDriverObject();
  16148. }
  16149. //html-id or null
  16150. return $id;
  16151. }
  16152. /**
  16153. * @param $id
  16154. * @return bool
  16155. */
  16156. private function isElement($id)
  16157. {
  16158. return $id instanceof PHPUnit_Extensions_Selenium2TestCase_Element;
  16159. }
  16160. public function httpMethod()
  16161. {
  16162. return 'POST';
  16163. }
  16164. }
  16165. <?php
  16166. /**
  16167. * PHPUnit
  16168. *
  16169. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16170. * All rights reserved.
  16171. *
  16172. * Redistribution and use in source and binary forms, with or without
  16173. * modification, are permitted provided that the following conditions
  16174. * are met:
  16175. *
  16176. * * Redistributions of source code must retain the above copyright
  16177. * notice, this list of conditions and the following disclaimer.
  16178. *
  16179. * * Redistributions in binary form must reproduce the above copyright
  16180. * notice, this list of conditions and the following disclaimer in
  16181. * the documentation and/or other materials provided with the
  16182. * distribution.
  16183. *
  16184. * * Neither the name of Sebastian Bergmann nor the names of his
  16185. * contributors may be used to endorse or promote products derived
  16186. * from this software without specific prior written permission.
  16187. *
  16188. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16189. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16190. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16191. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16192. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16193. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16194. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16195. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16196. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16197. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16198. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16199. * POSSIBILITY OF SUCH DAMAGE.
  16200. *
  16201. * @package PHPUnit_Selenium
  16202. * @author Giorgio Sironi <info@giorgiosironi.com>
  16203. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16204. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16205. * @link http://www.phpunit.de/
  16206. * @since File available since Release 1.2.0
  16207. */
  16208. /**
  16209. * URL Value Object allowing easy concatenation.
  16210. *
  16211. * @package PHPUnit_Selenium
  16212. * @author Giorgio Sironi <info@giorgiosironi.com>
  16213. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16214. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16215. * @version Release: @package_version@
  16216. * @link http://www.phpunit.de/
  16217. * @since Class available since Release 1.2.0
  16218. */
  16219. final class PHPUnit_Extensions_Selenium2TestCase_URL
  16220. {
  16221. /**
  16222. * @var string
  16223. */
  16224. private $value;
  16225. /**
  16226. * @param string $value
  16227. */
  16228. public function __construct($value)
  16229. {
  16230. $this->value = $value;
  16231. }
  16232. /**
  16233. * @param string $host
  16234. * @param int port
  16235. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16236. */
  16237. public static function fromHostAndPort($host, $port)
  16238. {
  16239. return new self("http://{$host}:{$port}");
  16240. }
  16241. /**
  16242. * @return string
  16243. */
  16244. public function getValue()
  16245. {
  16246. return $this->value;
  16247. }
  16248. public function __toString()
  16249. {
  16250. return $this->getValue();
  16251. }
  16252. /**
  16253. * @param string $addition
  16254. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16255. */
  16256. public function descend($addition)
  16257. {
  16258. if ($addition == '') {
  16259. // if we're adding nothing, respect the current url's choice of
  16260. // whether or not to include a trailing slash; prevents inadvertent
  16261. // adding of slashes to urls that can't handle it
  16262. $newValue = $this->value;
  16263. } else {
  16264. $newValue = rtrim($this->value, '/')
  16265. . '/'
  16266. . ltrim($addition, '/');
  16267. }
  16268. return new self($newValue);
  16269. }
  16270. /**
  16271. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16272. */
  16273. public function ascend()
  16274. {
  16275. $lastSlash = strrpos($this->value, "/");
  16276. $newValue = substr($this->value, 0, $lastSlash);
  16277. return new self($newValue);
  16278. }
  16279. /**
  16280. * @return string
  16281. */
  16282. public function lastSegment()
  16283. {
  16284. $segments = explode('/', $this->value);
  16285. return end($segments);
  16286. }
  16287. /**
  16288. * @param string $command
  16289. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16290. */
  16291. public function addCommand($command)
  16292. {
  16293. return $this->descend($this->camelCaseToUnderScores($command));
  16294. }
  16295. /**
  16296. * @param string $newUrl
  16297. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16298. */
  16299. public function jump($newUrl)
  16300. {
  16301. if ($this->isAbsolute($newUrl)) {
  16302. return new self($newUrl);
  16303. } else {
  16304. return $this->descend($newUrl);
  16305. }
  16306. }
  16307. private function camelCaseToUnderScores($string)
  16308. {
  16309. $string = preg_replace('/([A-Z]{1,1})/', ' \1', $string);
  16310. $string = strtolower($string);
  16311. return str_replace(' ', '_', $string);
  16312. }
  16313. private function isAbsolute($urlValue)
  16314. {
  16315. return preg_match('/^(http|https):\/\//', $urlValue) > 0;
  16316. }
  16317. }
  16318. <?php
  16319. /**
  16320. * PHPUnit
  16321. *
  16322. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16323. * All rights reserved.
  16324. *
  16325. * Redistribution and use in source and binary forms, with or without
  16326. * modification, are permitted provided that the following conditions
  16327. * are met:
  16328. *
  16329. * * Redistributions of source code must retain the above copyright
  16330. * notice, this list of conditions and the following disclaimer.
  16331. *
  16332. * * Redistributions in binary form must reproduce the above copyright
  16333. * notice, this list of conditions and the following disclaimer in
  16334. * the documentation and/or other materials provided with the
  16335. * distribution.
  16336. *
  16337. * * Neither the name of Sebastian Bergmann nor the names of his
  16338. * contributors may be used to endorse or promote products derived
  16339. * from this software without specific prior written permission.
  16340. *
  16341. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16342. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16343. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16344. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16345. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16346. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16347. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16348. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16349. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16350. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16351. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16352. * POSSIBILITY OF SUCH DAMAGE.
  16353. *
  16354. * @package PHPUnit_Selenium
  16355. * @author Giorgio Sironi <info@giorgiosironi.com>
  16356. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16357. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16358. * @link http://www.phpunit.de/
  16359. * @since File available since Release 1.2.6
  16360. */
  16361. /**
  16362. * Specifies how to create Session objects for running tests.
  16363. *
  16364. * @package PHPUnit_Selenium
  16365. * @author Giorgio Sironi <info@giorgiosironi.com>
  16366. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16367. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16368. * @version Release: @package_version@
  16369. * @link http://www.phpunit.de/
  16370. * @since Class available since Release 1.2.6
  16371. */
  16372. interface PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  16373. {
  16374. /**
  16375. * @param array $parameters 'host' => Selenium Server machine
  16376. 'port' => Selenium Server port
  16377. 'browser' => a browser name
  16378. * 'browserUrl' => base URL to use during the test
  16379. */
  16380. public function session(array $parameters);
  16381. public function notSuccessfulTest();
  16382. public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL);
  16383. }
  16384. <?php
  16385. /**
  16386. * PHPUnit
  16387. *
  16388. * Copyright (c) 2010-2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
  16389. * All rights reserved.
  16390. *
  16391. * Redistribution and use in source and binary forms, with or without
  16392. * modification, are permitted provided that the following conditions
  16393. * are met:
  16394. *
  16395. * * Redistributions of source code must retain the above copyright
  16396. * notice, this list of conditions and the following disclaimer.
  16397. *
  16398. * * Redistributions in binary form must reproduce the above copyright
  16399. * notice, this list of conditions and the following disclaimer in
  16400. * the documentation and/or other materials provided with the
  16401. * distribution.
  16402. *
  16403. * * Neither the name of Sebastian Bergmann nor the names of his
  16404. * contributors may be used to endorse or promote products derived
  16405. * from this software without specific prior written permission.
  16406. *
  16407. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16408. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16409. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16410. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16411. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16412. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16413. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16414. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16415. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16416. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16417. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16418. * POSSIBILITY OF SUCH DAMAGE.
  16419. *
  16420. * @package PHPUnit_Selenium
  16421. * @author Ivan Kurnosov <zerkms@zerkms.com>
  16422. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  16423. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16424. * @link http://www.phpunit.de/
  16425. * @since File available since Release 1.2.12
  16426. */
  16427. /**
  16428. * Class-mapper, that converts requested special key into correspondent Unicode character
  16429. *
  16430. * @package PHPUnit_Selenium
  16431. * @author Ivan Kurnosov <zerkms@zerkms.com>
  16432. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  16433. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16434. * @version Release: @package_version@
  16435. * @link http://www.phpunit.de/
  16436. * @since Class available since Release 1.2.12
  16437. * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value
  16438. */
  16439. class PHPUnit_Extensions_Selenium2TestCase_KeysHolder
  16440. {
  16441. private $_keys = array(
  16442. 'null' => "\xEE\x80\x80",
  16443. 'cancel' => "\xEE\x80\x81",
  16444. 'help' => "\xEE\x80\x82",
  16445. 'backspace' => "\xEE\x80\x83",
  16446. 'tab' => "\xEE\x80\x84",
  16447. 'clear' => "\xEE\x80\x85",
  16448. 'return' => "\xEE\x80\x86",
  16449. 'enter' => "\xEE\x80\x87",
  16450. 'shift' => "\xEE\x80\x88",
  16451. 'control' => "\xEE\x80\x89",
  16452. 'alt' => "\xEE\x80\x8A",
  16453. 'pause' => "\xEE\x80\x8B",
  16454. 'escape' => "\xEE\x80\x8C",
  16455. 'space' => "\xEE\x80\x8D",
  16456. 'pageup' => "\xEE\x80\x8E",
  16457. 'pagedown' => "\xEE\x80\x8F",
  16458. 'end' => "\xEE\x80\x90",
  16459. 'home' => "\xEE\x80\x91",
  16460. 'left' => "\xEE\x80\x92",
  16461. 'up' => "\xEE\x80\x93",
  16462. 'right' => "\xEE\x80\x94",
  16463. 'down' => "\xEE\x80\x95",
  16464. 'insert' => "\xEE\x80\x96",
  16465. 'delete' => "\xEE\x80\x97",
  16466. 'semicolon' => "\xEE\x80\x98",
  16467. 'equals' => "\xEE\x80\x99",
  16468. 'numpad0' => "\xEE\x80\x9A",
  16469. 'numpad1' => "\xEE\x80\x9B",
  16470. 'numpad2' => "\xEE\x80\x9C",
  16471. 'numpad3' => "\xEE\x80\x9D",
  16472. 'numpad4' => "\xEE\x80\x9E",
  16473. 'numpad5' => "\xEE\x80\x9F",
  16474. 'numpad6' => "\xEE\x80\xA0",
  16475. 'numpad7' => "\xEE\x80\xA1",
  16476. 'numpad8' => "\xEE\x80\xA2",
  16477. 'numpad9' => "\xEE\x80\xA3",
  16478. 'multiply' => "\xEE\x80\xA4",
  16479. 'add' => "\xEE\x80\xA5",
  16480. 'separator' => "\xEE\x80\xA6",
  16481. 'subtract' => "\xEE\x80\xA7",
  16482. 'decimal' => "\xEE\x80\xA8",
  16483. 'divide' => "\xEE\x80\xA9",
  16484. 'f1' => "\xEE\x80\xB1",
  16485. 'f2' => "\xEE\x80\xB2",
  16486. 'f3' => "\xEE\x80\xB3",
  16487. 'f4' => "\xEE\x80\xB4",
  16488. 'f5' => "\xEE\x80\xB5",
  16489. 'f6' => "\xEE\x80\xB6",
  16490. 'f7' => "\xEE\x80\xB7",
  16491. 'f8' => "\xEE\x80\xB8",
  16492. 'f9' => "\xEE\x80\xB9",
  16493. 'f10' => "\xEE\x80\xBA",
  16494. 'f11' => "\xEE\x80\xBB",
  16495. 'f12' => "\xEE\x80\xBC",
  16496. 'command' => "\xEE\x80\xBD",
  16497. );
  16498. public function specialKey($name)
  16499. {
  16500. $normalizedName = strtolower($name);
  16501. if (!isset($this->_keys[$normalizedName])) {
  16502. throw new PHPUnit_Extensions_Selenium2TestCase_Exception("There is no special key '$name' defined");
  16503. }
  16504. return $this->_keys[$normalizedName];
  16505. }
  16506. }
  16507. <?php
  16508. /**
  16509. * PHPUnit
  16510. *
  16511. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16512. * All rights reserved.
  16513. *
  16514. * Redistribution and use in source and binary forms, with or without
  16515. * modification, are permitted provided that the following conditions
  16516. * are met:
  16517. *
  16518. * * Redistributions of source code must retain the above copyright
  16519. * notice, this list of conditions and the following disclaimer.
  16520. *
  16521. * * Redistributions in binary form must reproduce the above copyright
  16522. * notice, this list of conditions and the following disclaimer in
  16523. * the documentation and/or other materials provided with the
  16524. * distribution.
  16525. *
  16526. * * Neither the name of Sebastian Bergmann nor the names of his
  16527. * contributors may be used to endorse or promote products derived
  16528. * from this software without specific prior written permission.
  16529. *
  16530. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16531. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16532. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16533. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16534. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16535. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16536. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16537. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16538. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16539. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16540. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16541. * POSSIBILITY OF SUCH DAMAGE.
  16542. *
  16543. * @package PHPUnit_Selenium
  16544. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16545. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16546. * @link http://www.phpunit.de/
  16547. */
  16548. /**
  16549. * Provides access to /element and /elements commands
  16550. *
  16551. * @package PHPUnit_Selenium
  16552. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16553. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16554. * @version Release: @package_version@
  16555. * @link http://www.phpunit.de/
  16556. */
  16557. abstract class PHPUnit_Extensions_Selenium2TestCase_Element_Accessor
  16558. extends PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
  16559. {
  16560. /**
  16561. * @param string $value e.g. 'container'
  16562. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16563. */
  16564. public function byClassName($value)
  16565. {
  16566. return $this->by('class name', $value);
  16567. }
  16568. /**
  16569. * @param string $value e.g. 'div.container'
  16570. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16571. */
  16572. public function byCssSelector($value)
  16573. {
  16574. return $this->by('css selector', $value);
  16575. }
  16576. /**
  16577. * @param string $value e.g. 'uniqueId'
  16578. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16579. */
  16580. public function byId($value)
  16581. {
  16582. return $this->by('id', $value);
  16583. }
  16584. /**
  16585. * @param string $value e.g. 'Link text'
  16586. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16587. */
  16588. public function byLinkText($value)
  16589. {
  16590. return $this->by('link text', $value);
  16591. }
  16592. /**
  16593. * @param string $value e.g. 'Link te'
  16594. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16595. */
  16596. public function byPartialLinkText($value)
  16597. {
  16598. return $this->by('partial link text', $value);
  16599. }
  16600. /**
  16601. * @param string $value e.g. 'email_address'
  16602. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16603. */
  16604. public function byName($value)
  16605. {
  16606. return $this->by('name', $value);
  16607. }
  16608. /**
  16609. * @param string $value e.g. 'body'
  16610. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16611. */
  16612. public function byTag($value)
  16613. {
  16614. return $this->by('tag name', $value);
  16615. }
  16616. /**
  16617. * @param string $value e.g. '/div[@attribute="value"]'
  16618. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16619. */
  16620. public function byXPath($value)
  16621. {
  16622. return $this->by('xpath', $value);
  16623. }
  16624. /**
  16625. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16626. */
  16627. public function element(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria)
  16628. {
  16629. $value = $this->postCommand('element', $criteria);
  16630. return PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue(
  16631. $value, $this->getSessionUrl()->descend('element'), $this->driver);
  16632. }
  16633. /**
  16634. * @return array instances of PHPUnit_Extensions_Selenium2TestCase_Element
  16635. */
  16636. public function elements(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria)
  16637. {
  16638. $values = $this->postCommand('elements', $criteria);
  16639. $elements = array();
  16640. foreach ($values as $value) {
  16641. $elements[] =
  16642. PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue(
  16643. $value, $this->getSessionUrl()->descend('element'), $this->driver);
  16644. }
  16645. return $elements;
  16646. }
  16647. /**
  16648. * @param string $strategy
  16649. * @return PHPUnit_Extensions_Selenium2TestCase_ElementCriteria
  16650. */
  16651. public function using($strategy)
  16652. {
  16653. return new PHPUnit_Extensions_Selenium2TestCase_ElementCriteria($strategy);
  16654. }
  16655. /**
  16656. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16657. */
  16658. protected abstract function getSessionUrl();
  16659. /**
  16660. * @param string $strategy supported by JsonWireProtocol element/ command
  16661. * @param string $value
  16662. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16663. */
  16664. private function by($strategy, $value)
  16665. {
  16666. return $this->element($this->using($strategy)->value($value));
  16667. }
  16668. }
  16669. <?php
  16670. /**
  16671. * PHPUnit
  16672. *
  16673. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16674. * All rights reserved.
  16675. *
  16676. * Redistribution and use in source and binary forms, with or without
  16677. * modification, are permitted provided that the following conditions
  16678. * are met:
  16679. *
  16680. * * Redistributions of source code must retain the above copyright
  16681. * notice, this list of conditions and the following disclaimer.
  16682. *
  16683. * * Redistributions in binary form must reproduce the above copyright
  16684. * notice, this list of conditions and the following disclaimer in
  16685. * the documentation and/or other materials provided with the
  16686. * distribution.
  16687. *
  16688. * * Neither the name of Sebastian Bergmann nor the names of his
  16689. * contributors may be used to endorse or promote products derived
  16690. * from this software without specific prior written permission.
  16691. *
  16692. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16693. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16694. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16695. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16696. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16697. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16698. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16699. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16700. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16701. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16702. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16703. * POSSIBILITY OF SUCH DAMAGE.
  16704. *
  16705. * @package PHPUnit_Selenium
  16706. * @author Giorgio Sironi <info@giorgiosironi.com>
  16707. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16708. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16709. * @link http://www.phpunit.de/
  16710. * @since File available since Release 1.2.2
  16711. */
  16712. /**
  16713. * Object representing a <select> element.
  16714. *
  16715. * @package PHPUnit_Selenium
  16716. * @author Giorgio Sironi <info@giorgiosironi.com>
  16717. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16718. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16719. * @version Release: @package_version@
  16720. * @link http://www.phpunit.de/
  16721. * @since Class available since Release 1.2.2
  16722. */
  16723. class PHPUnit_Extensions_Selenium2TestCase_Element_Select
  16724. extends PHPUnit_Extensions_Selenium2TestCase_Element
  16725. {
  16726. /**
  16727. * @return PHPUnit_Extensions_Selenium2TestCase_Element_Select
  16728. */
  16729. public static function fromElement(PHPUnit_Extensions_Selenium2TestCase_Element $element)
  16730. {
  16731. return new self($element->driver, $element->url);
  16732. }
  16733. /**
  16734. * @return string
  16735. */
  16736. public function selectedLabel()
  16737. {
  16738. $selectedOption = $this->selectedOption();
  16739. if ($selectedOption === NULL) {
  16740. return '';
  16741. }
  16742. return $selectedOption->text();
  16743. }
  16744. /**
  16745. * @return string
  16746. */
  16747. public function selectedValue()
  16748. {
  16749. $selectedOption = $this->selectedOption();
  16750. if ($selectedOption === NULL) {
  16751. return '';
  16752. }
  16753. return $selectedOption->value();
  16754. }
  16755. /**
  16756. * @return string
  16757. */
  16758. public function selectedId()
  16759. {
  16760. $selectedOption = $this->selectedOption();
  16761. if ($selectedOption === NULL) {
  16762. return '';
  16763. }
  16764. return $selectedOption->attribute('id');
  16765. }
  16766. /**
  16767. * @return array
  16768. */
  16769. public function selectedLabels()
  16770. {
  16771. $labels = array();
  16772. foreach ($this->selectedOptions() as $option) {
  16773. $labels[] = $option->text();
  16774. }
  16775. return $labels;
  16776. }
  16777. /**
  16778. * @return array
  16779. */
  16780. public function selectedValues()
  16781. {
  16782. $values = array();
  16783. foreach ($this->selectedOptions() as $option) {
  16784. $values[] = $option->value();
  16785. }
  16786. return $values;
  16787. }
  16788. /**
  16789. * @return array
  16790. */
  16791. public function selectedIds()
  16792. {
  16793. $id = array();
  16794. foreach ($this->selectedOptions() as $option) {
  16795. $values[] = $option->attribute('id');
  16796. }
  16797. return $id;
  16798. }
  16799. /**
  16800. * @param string $label the text appearing in the option
  16801. * @return void
  16802. */
  16803. public function selectOptionByLabel($label)
  16804. {
  16805. $toSelect = $this->using('xpath')->value(".//option[.='$label']");
  16806. $this->selectOptionByCriteria($toSelect);
  16807. }
  16808. /**
  16809. * @param string $value the value attribute of the option
  16810. * @return void
  16811. */
  16812. public function selectOptionByValue($value)
  16813. {
  16814. $toSelect = $this->using('xpath')->value(".//option[@value='$value']");
  16815. $this->selectOptionByCriteria($toSelect);
  16816. }
  16817. /**
  16818. * @param PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $localCriteria condiotions for selecting an option
  16819. * @return void
  16820. */
  16821. public function selectOptionByCriteria(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $localCriteria)
  16822. {
  16823. $option = $this->element($localCriteria);
  16824. if (!$option->selected()) {
  16825. $option->click();
  16826. }
  16827. }
  16828. /**
  16829. * @return array
  16830. */
  16831. public function selectOptionValues()
  16832. {
  16833. $options = array();
  16834. foreach ($this->options() as $option) {
  16835. $options[] = $option->value();
  16836. }
  16837. return $options;
  16838. }
  16839. /**
  16840. * @return array
  16841. */
  16842. public function selectOptionLabels()
  16843. {
  16844. $options = array();
  16845. foreach ($this->options() as $option) {
  16846. $options[] = $option->text();
  16847. }
  16848. return $options;
  16849. }
  16850. /***
  16851. * @return array
  16852. */
  16853. private function selectedOptions()
  16854. {
  16855. $options = array();
  16856. foreach ($this->options() as $option) {
  16857. if ($option->selected()) {
  16858. $options[] = $option;
  16859. }
  16860. }
  16861. return $options;
  16862. }
  16863. public function clearSelectedOptions()
  16864. {
  16865. foreach ($this->selectedOptions() as $option) {
  16866. $option->click();
  16867. }
  16868. }
  16869. private function selectedOption()
  16870. {
  16871. foreach ($this->options() as $option) {
  16872. if ($option->selected()) {
  16873. return $option;
  16874. }
  16875. }
  16876. return NULL;
  16877. }
  16878. private function options()
  16879. {
  16880. $onlyTheOptions = $this->using('css selector')->value('option');
  16881. return $this->elements($onlyTheOptions);
  16882. }
  16883. }
  16884. <?php
  16885. /**
  16886. * PHPUnit
  16887. *
  16888. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16889. * All rights reserved.
  16890. *
  16891. * Redistribution and use in source and binary forms, with or without
  16892. * modification, are permitted provided that the following conditions
  16893. * are met:
  16894. *
  16895. * * Redistributions of source code must retain the above copyright
  16896. * notice, this list of conditions and the following disclaimer.
  16897. *
  16898. * * Redistributions in binary form must reproduce the above copyright
  16899. * notice, this list of conditions and the following disclaimer in
  16900. * the documentation and/or other materials provided with the
  16901. * distribution.
  16902. *
  16903. * * Neither the name of Sebastian Bergmann nor the names of his
  16904. * contributors may be used to endorse or promote products derived
  16905. * from this software without specific prior written permission.
  16906. *
  16907. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16908. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16909. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16910. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16911. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16912. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16913. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16914. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16915. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16916. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16917. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16918. * POSSIBILITY OF SUCH DAMAGE.
  16919. *
  16920. * @package PHPUnit_Selenium
  16921. * @author Giorgio Sironi <info@giorgiosironi.com>
  16922. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16923. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16924. * @link http://www.phpunit.de/
  16925. * @since File available since Release 1.2.0
  16926. */
  16927. /**
  16928. * Browser session for Selenium 2: main point of entry for functionality.
  16929. *
  16930. * @package PHPUnit_Selenium
  16931. * @author Giorgio Sironi <info@giorgiosironi.com>
  16932. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16933. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16934. * @version Release: @package_version@
  16935. * @link http://www.phpunit.de/
  16936. * @since Class available since Release 1.2.0
  16937. * @method void acceptAlert() Press OK on an alert, or confirms a dialog
  16938. * @method mixed alertText($value = NULL) Gets the alert dialog text, or sets the text for a prompt dialog
  16939. * @method void back()
  16940. * @method void dismissAlert() Press Cancel on an alert, or does not confirm a dialog
  16941. * @method void doubleclick() Double-clicks at the current mouse coordinates (set by moveto).
  16942. * @method string execute(array $javaScriptCode) Injects arbitrary JavaScript in the page and returns the last. See unit tests for usage
  16943. * @method string executeAsync(array $javaScriptCode) Injects arbitrary JavaScript and wait for the callback (last element of arguments) to be called. See unit tests for usage
  16944. * @method void forward()
  16945. * @method void frame(mixed $element) Changes the focus to a frame in the page (by frameCount of type int, htmlId of type string, htmlName of type string or element of type \PHPUnit_Extensions_Selenium2TestCase_Element)
  16946. * @method void moveto(\PHPUnit_Extensions_Selenium2TestCase_Element $element) Move the mouse by an offset of the specificed element.
  16947. * @method void refresh()
  16948. * @method string source() Returns the HTML source of the page
  16949. * @method string title()
  16950. * @method void|string url($url = NULL)
  16951. * @method void window($name) Changes the focus to another window
  16952. * @method string windowHandle() Retrieves the current window handle
  16953. * @method string windowHandles() Retrieves a list of all available window handles
  16954. * @method string keys() Send a sequence of key strokes to the active element.
  16955. * @method string file($file_path) Upload a local file. Returns the fully qualified path to the transferred file.
  16956. * @method array log(string $type) Get the log for a given log type. Log buffer is reset after each request.
  16957. * @method array logTypes() Get available log types.
  16958. */
  16959. class PHPUnit_Extensions_Selenium2TestCase_Session
  16960. extends PHPUnit_Extensions_Selenium2TestCase_Element_Accessor
  16961. {
  16962. /**
  16963. * @var string the base URL for this session,
  16964. * which all relative URLs will refer to
  16965. */
  16966. private $baseUrl;
  16967. /**
  16968. * @var PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts
  16969. */
  16970. private $timeouts;
  16971. /**
  16972. * @var boolean
  16973. */
  16974. private $stopped = FALSE;
  16975. public function __construct($driver,
  16976. PHPUnit_Extensions_Selenium2TestCase_URL $url,
  16977. PHPUnit_Extensions_Selenium2TestCase_URL $baseUrl,
  16978. PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts $timeouts)
  16979. {
  16980. $this->baseUrl = $baseUrl;
  16981. $this->timeouts = $timeouts;
  16982. parent::__construct($driver, $url);
  16983. }
  16984. /**
  16985. * @return string
  16986. */
  16987. public function id()
  16988. {
  16989. return $this->url->lastSegment();
  16990. }
  16991. protected function initCommands()
  16992. {
  16993. $baseUrl = $this->baseUrl;
  16994. return array(
  16995. 'acceptAlert' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AcceptAlert',
  16996. 'alertText' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AlertText',
  16997. 'back' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  16998. 'click' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Click',
  16999. 'buttondown' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  17000. 'buttonup' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  17001. 'dismissAlert' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_DismissAlert',
  17002. 'doubleclick' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  17003. 'execute' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  17004. 'executeAsync' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  17005. 'forward' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  17006. 'frame' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Frame',
  17007. 'keys' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys',
  17008. 'moveto' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_MoveTo',
  17009. 'refresh' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  17010. 'screenshot' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  17011. 'source' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
  17012. 'title' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
  17013. 'log' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Log',
  17014. 'logTypes' => $this->attributeCommandFactoryMethod('log/types'),
  17015. 'url' => function ($jsonParameters, $commandUrl) use ($baseUrl) {
  17016. return new PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Url($jsonParameters, $commandUrl, $baseUrl);
  17017. },
  17018. 'window' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Window',
  17019. 'windowHandle' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
  17020. 'windowHandles' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
  17021. 'touchDown' => $this->touchCommandFactoryMethod('touch/down'),
  17022. 'touchUp' => $this->touchCommandFactoryMethod('touch/up'),
  17023. 'touchMove' => $this->touchCommandFactoryMethod('touch/move'),
  17024. 'touchScroll' => $this->touchCommandFactoryMethod('touch/scroll'),
  17025. 'flick' => $this->touchCommandFactoryMethod('touch/flick'),
  17026. 'location' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Location',
  17027. 'orientation' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Orientation',
  17028. 'file' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_File'
  17029. );
  17030. }
  17031. private function attributeCommandFactoryMethod($urlSegment)
  17032. {
  17033. $url = $this->url->addCommand($urlSegment);
  17034. return function ($jsonParameters, $commandUrl) use ($url) {
  17035. return new PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute($jsonParameters, $url);
  17036. };
  17037. }
  17038. private function touchCommandFactoryMethod($urlSegment)
  17039. {
  17040. $url = $this->url->addCommand($urlSegment);
  17041. return function ($jsonParameters, $commandUrl) use ($url) {
  17042. return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $url);
  17043. };
  17044. }
  17045. public function __destruct()
  17046. {
  17047. $this->stop();
  17048. }
  17049. /**
  17050. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  17051. */
  17052. public function getSessionUrl()
  17053. {
  17054. return $this->url;
  17055. }
  17056. /**
  17057. * Closed the browser.
  17058. * @return void
  17059. */
  17060. public function stop()
  17061. {
  17062. if ($this->stopped) {
  17063. return;
  17064. }
  17065. try {
  17066. $this->driver->curl('DELETE', $this->url);
  17067. } catch (Exception $e) {
  17068. // sessions which aren't closed because of sharing can time out on the server. In no way trying to close them should make a test fail, as it already finished before arriving here.
  17069. "Closing sessions: " . $e->getMessage() . "\n";
  17070. }
  17071. $this->stopped = TRUE;
  17072. if ($this->stopped) {
  17073. return;
  17074. }
  17075. }
  17076. /**
  17077. * @return PHPUnit_Extensions_Selenium2TestCase_Element_Select
  17078. */
  17079. public function select(PHPUnit_Extensions_Selenium2TestCase_Element $element)
  17080. {
  17081. $tag = $element->name();
  17082. if ($tag !== 'select') {
  17083. throw new InvalidArgumentException("The element is not a `select` tag but a `$tag`.");
  17084. }
  17085. return PHPUnit_Extensions_Selenium2TestCase_Element_Select::fromElement($element);
  17086. }
  17087. /**
  17088. * @param array WebElement JSON object
  17089. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  17090. */
  17091. public function elementFromResponseValue($value)
  17092. {
  17093. return PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue($value, $this->getSessionUrl()->descend('element'), $this->driver);
  17094. }
  17095. /**
  17096. * @param string $id id attribute, e.g. 'container'
  17097. * @return void
  17098. */
  17099. public function clickOnElement($id)
  17100. {
  17101. return $this->element($this->using('id')->value($id))->click();
  17102. }
  17103. public function timeouts()
  17104. {
  17105. return $this->timeouts;
  17106. }
  17107. /**
  17108. * @return string a BLOB of a PNG file
  17109. */
  17110. public function currentScreenshot()
  17111. {
  17112. return base64_decode($this->screenshot());
  17113. }
  17114. /**
  17115. * @return PHPUnit_Extensions_Selenium2TestCase_Window
  17116. */
  17117. public function currentWindow()
  17118. {
  17119. $url = $this->url->descend('window')->descend(trim($this->windowHandle(), '{}'));
  17120. return new PHPUnit_Extensions_Selenium2TestCase_Window($this->driver, $url);
  17121. }
  17122. public function closeWindow()
  17123. {
  17124. $this->driver->curl('DELETE', $this->url->descend('window'));
  17125. }
  17126. /**
  17127. * Get the element on the page that currently has focus.
  17128. *
  17129. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  17130. */
  17131. public function active()
  17132. {
  17133. $command = new PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Active(null, $this->url);
  17134. $response = $this->driver->execute($command);
  17135. return $this->elementFromResponseValue($response->getValue());
  17136. }
  17137. /**
  17138. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie
  17139. */
  17140. public function cookie()
  17141. {
  17142. $url = $this->url->descend('cookie');
  17143. return new PHPUnit_Extensions_Selenium2TestCase_Session_Cookie($this->driver, $url);
  17144. }
  17145. /**
  17146. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Storage
  17147. */
  17148. public function localStorage()
  17149. {
  17150. $url = $this->url->addCommand('localStorage');
  17151. return new PHPUnit_Extensions_Selenium2TestCase_Session_Storage($this->driver, $url);
  17152. }
  17153. public function landscape()
  17154. {
  17155. $this->orientation('LANDSCAPE');
  17156. }
  17157. public function portrait()
  17158. {
  17159. $this->orientation('PORTRAIT');
  17160. }
  17161. }
  17162. <?php
  17163. /**
  17164. * PHPUnit
  17165. *
  17166. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  17167. * All rights reserved.
  17168. *
  17169. * Redistribution and use in source and binary forms, with or without
  17170. * modification, are permitted provided that the following conditions
  17171. * are met:
  17172. *
  17173. * * Redistributions of source code must retain the above copyright
  17174. * notice, this list of conditions and the following disclaimer.
  17175. *
  17176. * * Redistributions in binary form must reproduce the above copyright
  17177. * notice, this list of conditions and the following disclaimer in
  17178. * the documentation and/or other materials provided with the
  17179. * distribution.
  17180. *
  17181. * * Neither the name of Sebastian Bergmann nor the names of his
  17182. * contributors may be used to endorse or promote products derived
  17183. * from this software without specific prior written permission.
  17184. *
  17185. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17186. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17187. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  17188. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17189. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17190. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17191. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17192. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17193. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  17194. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17195. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17196. * POSSIBILITY OF SUCH DAMAGE.
  17197. *
  17198. * @package PHPUnit_Selenium
  17199. * @author Sebastian Bergmann <sebastian@phpunit.de>
  17200. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17201. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17202. * @link http://www.phpunit.de/
  17203. * @since File available since Release 1.0.0
  17204. */
  17205. // By default the code coverage files are written to the same directory
  17206. // that contains the covered sourcecode files. Use this setting to change
  17207. // the default behaviour and set a specific directory to write the files to.
  17208. // If you change the default setting, please make sure to also configure
  17209. // the same directory in phpunit_coverage.php. Also note that the webserver
  17210. // needs write access to the directory.
  17211. if (!isset($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) {
  17212. $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = FALSE;
  17213. }
  17214. if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) &&
  17215. !isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) &&
  17216. extension_loaded('xdebug')) {
  17217. $GLOBALS['PHPUNIT_FILTERED_FILES'] = array(__FILE__);
  17218. xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
  17219. }
  17220. include ('ExitHandler.php');
  17221. PHPUnit_Extensions_SeleniumCommon_ExitHandler::init();
  17222. <?php
  17223. /**
  17224. * PHPUnit
  17225. *
  17226. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  17227. * All rights reserved.
  17228. *
  17229. * Redistribution and use in source and binary forms, with or without
  17230. * modification, are permitted provided that the following conditions
  17231. * are met:
  17232. *
  17233. * * Redistributions of source code must retain the above copyright
  17234. * notice, this list of conditions and the following disclaimer.
  17235. *
  17236. * * Redistributions in binary form must reproduce the above copyright
  17237. * notice, this list of conditions and the following disclaimer in
  17238. * the documentation and/or other materials provided with the
  17239. * distribution.
  17240. *
  17241. * * Neither the name of Sebastian Bergmann nor the names of his
  17242. * contributors may be used to endorse or promote products derived
  17243. * from this software without specific prior written permission.
  17244. *
  17245. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17246. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17247. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  17248. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17249. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17250. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17251. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17252. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17253. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  17254. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17255. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17256. * POSSIBILITY OF SUCH DAMAGE.
  17257. *
  17258. * @package PHPUnit_Selenium
  17259. * @author Sebastian Bergmann <sebastian@phpunit.de>
  17260. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17261. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17262. * @link http://www.phpunit.de/
  17263. * @since File available since Release 1.0.0
  17264. */
  17265. if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) &&
  17266. !isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) &&
  17267. extension_loaded('xdebug')) {
  17268. $GLOBALS['PHPUNIT_FILTERED_FILES'][] = __FILE__;
  17269. $data = xdebug_get_code_coverage();
  17270. xdebug_stop_code_coverage();
  17271. foreach ($GLOBALS['PHPUNIT_FILTERED_FILES'] as $file) {
  17272. unset($data[$file]);
  17273. }
  17274. if (is_string($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']) &&
  17275. is_dir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) {
  17276. $file = $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] .
  17277. DIRECTORY_SEPARATOR . md5($_SERVER['SCRIPT_FILENAME']);
  17278. } else {
  17279. $file = $_SERVER['SCRIPT_FILENAME'];
  17280. }
  17281. file_put_contents(
  17282. $name = $file . '.' . md5(uniqid(rand(), TRUE)) . '.' . $_COOKIE['PHPUNIT_SELENIUM_TEST_ID'],
  17283. serialize($data)
  17284. );
  17285. }
  17286. <?php
  17287. class PHPUnit_Extensions_SeleniumCommon_RemoteCoverage
  17288. {
  17289. public function __construct($coverageScriptUrl, $testId)
  17290. {
  17291. $this->coverageScriptUrl = $coverageScriptUrl;
  17292. $this->testId = $testId;
  17293. }
  17294. public function get()
  17295. {
  17296. if (!empty($this->coverageScriptUrl)) {
  17297. $url = sprintf(
  17298. '%s?PHPUNIT_SELENIUM_TEST_ID=%s',
  17299. $this->coverageScriptUrl,
  17300. urlencode($this->testId)
  17301. );
  17302. $buffer = @file_get_contents($url);
  17303. if ($buffer !== FALSE) {
  17304. $coverageData = unserialize($buffer);
  17305. if (is_array($coverageData)) {
  17306. return $this->matchLocalAndRemotePaths($coverageData);
  17307. } else {
  17308. throw new Exception('Empty or invalid code coverage data received from url "' . $url . '"');
  17309. }
  17310. }
  17311. }
  17312. return array();
  17313. }
  17314. /**
  17315. * @param array $coverage
  17316. * @return array
  17317. * @author Mattis Stordalen Flister <mattis@xait.no>
  17318. */
  17319. protected function matchLocalAndRemotePaths(array $coverage)
  17320. {
  17321. $coverageWithLocalPaths = array();
  17322. foreach ($coverage as $originalRemotePath => $data) {
  17323. $remotePath = $originalRemotePath;
  17324. $separator = $this->findDirectorySeparator($remotePath);
  17325. while (!($localpath = stream_resolve_include_path($remotePath)) &&
  17326. strpos($remotePath, $separator) !== FALSE) {
  17327. $remotePath = substr($remotePath, strpos($remotePath, $separator) + 1);
  17328. }
  17329. if ($localpath && md5_file($localpath) == $data['md5']) {
  17330. $coverageWithLocalPaths[$localpath] = $data['coverage'];
  17331. }
  17332. }
  17333. return $coverageWithLocalPaths;
  17334. }
  17335. /**
  17336. * @param string $path
  17337. * @return string
  17338. * @author Mattis Stordalen Flister <mattis@xait.no>
  17339. */
  17340. protected function findDirectorySeparator($path)
  17341. {
  17342. if (strpos($path, '/') !== FALSE) {
  17343. return '/';
  17344. }
  17345. return '\\';
  17346. }
  17347. }
  17348. <?php
  17349. /**
  17350. * If Ececution was stopped by calling exit();
  17351. * php does not append append.php, so no code coverage date is collected
  17352. * We have to add shutdown handler to append this file manualy.
  17353. * @author Arbuzov <info@whitediver.com>
  17354. *
  17355. */
  17356. class PHPUnit_Extensions_SeleniumCommon_ExitHandler
  17357. {
  17358. /**
  17359. * Register handler.
  17360. * If project have own shutdown hanldler user have to add function to handler
  17361. *
  17362. */
  17363. public static function init()
  17364. {
  17365. register_shutdown_function( array( 'PHPUnit_Extensions_SeleniumCommon_ExitHandler', 'handle' ) );
  17366. }
  17367. /**
  17368. * Manual include apendable files
  17369. */
  17370. public static function handle()
  17371. {
  17372. $execFile = ini_get('auto_append_file');
  17373. if ($execFile!=='') {
  17374. include_once ($execFile);
  17375. }
  17376. }
  17377. }
  17378. <?php
  17379. /**
  17380. * PHPUnit
  17381. *
  17382. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  17383. * All rights reserved.
  17384. *
  17385. * Redistribution and use in source and binary forms, with or without
  17386. * modification, are permitted provided that the following conditions
  17387. * are met:
  17388. *
  17389. * * Redistributions of source code must retain the above copyright
  17390. * notice, this list of conditions and the following disclaimer.
  17391. *
  17392. * * Redistributions in binary form must reproduce the above copyright
  17393. * notice, this list of conditions and the following disclaimer in
  17394. * the documentation and/or other materials provided with the
  17395. * distribution.
  17396. *
  17397. * * Neither the name of Sebastian Bergmann nor the names of his
  17398. * contributors may be used to endorse or promote products derived
  17399. * from this software without specific prior written permission.
  17400. *
  17401. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17402. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17403. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  17404. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17405. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17406. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17407. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17408. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17409. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  17410. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17411. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17412. * POSSIBILITY OF SUCH DAMAGE.
  17413. *
  17414. * @package PHPUnit_Selenium
  17415. * @author Sebastian Bergmann <sebastian@phpunit.de>
  17416. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17417. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17418. * @link http://www.phpunit.de/
  17419. * @since File available since Release 1.0.0
  17420. */
  17421. $directory = realpath(__DIR__);
  17422. while ($directory != '/') {
  17423. $autoloadCandidate = $directory . '/vendor/autoload.php';
  17424. if (file_exists($autoloadCandidate)) {
  17425. require_once $autoloadCandidate;
  17426. break;
  17427. }
  17428. $directory = realpath($directory . '/..');
  17429. }
  17430. // Set this to the directory that contains the code coverage files.
  17431. // It defaults to getcwd(). If you have configured a different directory
  17432. // in prepend.php, you need to configure the same directory here.
  17433. $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = getcwd();
  17434. if (isset($_GET['PHPUNIT_SELENIUM_TEST_ID'])) {
  17435. $facade = new File_Iterator_Facade;
  17436. $files = $facade->getFilesAsArray(
  17437. $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'],
  17438. $_GET['PHPUNIT_SELENIUM_TEST_ID']
  17439. );
  17440. $coverage = array();
  17441. foreach ($files as $file) {
  17442. $data = unserialize(file_get_contents($file));
  17443. unlink($file);
  17444. unset($file);
  17445. $filter = new PHP_CodeCoverage_Filter();
  17446. foreach ($data as $file => $lines) {
  17447. if ($filter->isFile($file)) {
  17448. if (!isset($coverage[$file])) {
  17449. $coverage[$file] = array(
  17450. 'md5' => md5_file($file), 'coverage' => $lines
  17451. );
  17452. } else {
  17453. foreach ($lines as $line => $flag) {
  17454. if (!isset($coverage[$file]['coverage'][$line]) ||
  17455. $flag > $coverage[$file]['coverage'][$line]) {
  17456. $coverage[$file]['coverage'][$line] = $flag;
  17457. }
  17458. }
  17459. }
  17460. }
  17461. }
  17462. }
  17463. print serialize($coverage);
  17464. }
  17465. <?php
  17466. /**
  17467. * PHPUnit
  17468. *
  17469. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  17470. * All rights reserved.
  17471. *
  17472. * Redistribution and use in source and binary forms, with or without
  17473. * modification, are permitted provided that the following conditions
  17474. * are met:
  17475. *
  17476. * * Redistributions of source code must retain the above copyright
  17477. * notice, this list of conditions and the following disclaimer.
  17478. *
  17479. * * Redistributions in binary form must reproduce the above copyright
  17480. * notice, this list of conditions and the following disclaimer in
  17481. * the documentation and/or other materials provided with the
  17482. * distribution.
  17483. *
  17484. * * Neither the name of Sebastian Bergmann nor the names of his
  17485. * contributors may be used to endorse or promote products derived
  17486. * from this software without specific prior written permission.
  17487. *
  17488. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17489. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17490. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  17491. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17492. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17493. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17494. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17495. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17496. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  17497. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17498. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17499. * POSSIBILITY OF SUCH DAMAGE.
  17500. *
  17501. * @package PHPUnit_Selenium
  17502. * @author Giorgio Sironi <info@giorgiosironi.com>
  17503. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17504. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17505. * @link http://www.phpunit.de/
  17506. * @since File available since Release 1.2.6
  17507. */
  17508. /**
  17509. * TestSuite class for a set of tests from a single Testcase Class
  17510. * executed with a particular browser.
  17511. *
  17512. * @package PHPUnit_Selenium
  17513. * @author Giorgio Sironi <info@giorgiosironi.com>
  17514. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17515. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17516. * @version Release: @package_version@
  17517. * @link http://www.phpunit.de/
  17518. * @since Class available since Release 1.2.6
  17519. */
  17520. class PHPUnit_Extensions_SeleniumBrowserSuite extends PHPUnit_Framework_TestSuite
  17521. {
  17522. /**
  17523. * Overriding the default: Selenium suites are always built from a TestCase class.
  17524. * @var boolean
  17525. */
  17526. protected $testCase = TRUE;
  17527. public function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
  17528. {
  17529. return parent::addTestMethod($class, $method);
  17530. }
  17531. public static function fromClassAndBrowser($className, array $browser)
  17532. {
  17533. $browserSuite = new self();
  17534. if (isset($browser['browserName'])) {
  17535. $name = $browser['browserName'];
  17536. } else if (isset($browser['name'])) {
  17537. $name = $browser['name'];
  17538. } else {
  17539. $name = $browser['browser'];
  17540. }
  17541. $browserSuite->setName($className . ': ' . $name);
  17542. return $browserSuite;
  17543. }
  17544. public function setupSpecificBrowser(array $browser)
  17545. {
  17546. $this->browserOnAllTests($this, $browser);
  17547. }
  17548. private function browserOnAllTests(PHPUnit_Framework_TestSuite $suite, array $browser)
  17549. {
  17550. foreach ($suite->tests() as $test) {
  17551. if ($test instanceof PHPUnit_Framework_TestSuite) {
  17552. $this->browserOnAllTests($test, $browser);
  17553. } else {
  17554. $test->setupSpecificBrowser($browser);
  17555. }
  17556. }
  17557. }
  17558. }
  17559. <?php
  17560. /**
  17561. * PHPUnit
  17562. *
  17563. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  17564. * All rights reserved.
  17565. *
  17566. * Redistribution and use in source and binary forms, with or without
  17567. * modification, are permitted provided that the following conditions
  17568. * are met:
  17569. *
  17570. * * Redistributions of source code must retain the above copyright
  17571. * notice, this list of conditions and the following disclaimer.
  17572. *
  17573. * * Redistributions in binary form must reproduce the above copyright
  17574. * notice, this list of conditions and the following disclaimer in
  17575. * the documentation and/or other materials provided with the
  17576. * distribution.
  17577. *
  17578. * * Neither the name of Sebastian Bergmann nor the names of his
  17579. * contributors may be used to endorse or promote products derived
  17580. * from this software without specific prior written permission.
  17581. *
  17582. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17583. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17584. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  17585. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17586. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17587. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17588. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17589. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17590. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  17591. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17592. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17593. * POSSIBILITY OF SUCH DAMAGE.
  17594. *
  17595. * @package PHPUnit_Selenium
  17596. * @author Giorgio Sironi <info@giorgiosironi.com>
  17597. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17598. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17599. * @link http://www.phpunit.de/
  17600. * @since File available since Release 1.2.0
  17601. */
  17602. /**
  17603. * TestCase class that uses Selenium 2
  17604. * (WebDriver API and JsonWire protocol) to provide
  17605. * the functionality required for web testing.
  17606. *
  17607. * @package PHPUnit_Selenium
  17608. * @author Giorgio Sironi <info@giorgiosironi.com>
  17609. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17610. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17611. * @version Release: @package_version@
  17612. * @link http://www.phpunit.de/
  17613. * @since Class available since Release 1.2.0
  17614. * @method void acceptAlert() Press OK on an alert, or confirms a dialog
  17615. * @method mixed alertText() alertText($value = NULL) Gets the alert dialog text, or sets the text for a prompt dialog
  17616. * @method void back()
  17617. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byClassName() byClassName($value)
  17618. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byCssSelector() byCssSelector($value)
  17619. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byId() byId($value)
  17620. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byLinkText() byLinkText($value)
  17621. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byName() byName($value)
  17622. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byTag() byTag($value)
  17623. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byXPath() byXPath($value)
  17624. * @method void click() click(int $button = 0) Click any mouse button (at the coordinates set by the last moveto command).
  17625. * @method void clickOnElement() clickOnElement($id)
  17626. * @method string currentScreenshot() BLOB of the image file
  17627. * @method void dismissAlert() Press Cancel on an alert, or does not confirm a dialog
  17628. * @method void doubleclick() Double clicks (at the coordinates set by the last moveto command).
  17629. * @method \PHPUnit_Extensions_Selenium2TestCase_Element element() element(\PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria) Retrieves an element
  17630. * @method array elements() elements(\PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria) Retrieves an array of Element instances
  17631. * @method string execute() execute($javaScriptCode) Injects arbitrary JavaScript in the page and returns the last
  17632. * @method string executeAsync() executeAsync($javaScriptCode) Injects arbitrary JavaScript and wait for the callback (last element of arguments) to be called
  17633. * @method void forward()
  17634. * @method void frame() frame(mixed $element) Changes the focus to a frame in the page (by frameCount of type int, htmlId of type string, htmlName of type string or element of type \PHPUnit_Extensions_Selenium2TestCase_Element)
  17635. * @method void moveto() moveto(\PHPUnit_Extensions_Selenium2TestCase_Element $element) Move the mouse by an offset of the specificed element.
  17636. * @method void refresh()
  17637. * @method \PHPUnit_Extensions_Selenium2TestCase_Element_Select select() select($element)
  17638. * @method string source() Returns the HTML source of the page
  17639. * @method \PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts timeouts()
  17640. * @method string title()
  17641. * @method void|string url() url($url = NULL)
  17642. * @method PHPUnit_Extensions_Selenium2TestCase_ElementCriteria using() using($strategy) Factory Method for Criteria objects
  17643. * @method void window() window($name) Changes the focus to another window
  17644. * @method string windowHandle() Retrieves the current window handle
  17645. * @method string windowHandles() Retrieves a list of all available window handles
  17646. * @method string keys() Send a sequence of key strokes to the active element.
  17647. * @method string file($file_path) Upload a local file. Returns the fully qualified path to the transferred file.
  17648. * @method array log(string $type) Get the log for a given log type. Log buffer is reset after each request.
  17649. * @method array logTypes() Get available log types.
  17650. * @method void closeWindow() Close the current window.
  17651. * @method void close() Close the current window and clear session data.
  17652. * @method \PHPUnit_Extensions_Selenium2TestCase_Element active() Get the element on the page that currently has focus.
  17653. */
  17654. abstract class PHPUnit_Extensions_Selenium2TestCase extends PHPUnit_Framework_TestCase
  17655. {
  17656. const VERSION = '1.4.2';
  17657. /**
  17658. * @var string override to provide code coverage data from the server
  17659. */
  17660. protected $coverageScriptUrl;
  17661. /**
  17662. * @var PHPUnit_Extensions_Selenium2TestCase_Session
  17663. */
  17664. private $session;
  17665. /**
  17666. * @var array
  17667. */
  17668. private $parameters;
  17669. /**
  17670. * @var PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  17671. */
  17672. protected static $sessionStrategy;
  17673. /**
  17674. * @var PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  17675. */
  17676. protected static $browserSessionStrategy;
  17677. /**
  17678. * @var PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  17679. */
  17680. protected $localSessionStrategy;
  17681. /**
  17682. * @var array
  17683. */
  17684. private static $lastBrowserParams;
  17685. /**
  17686. * @var string
  17687. */
  17688. private $testId;
  17689. /**
  17690. * @var boolean
  17691. */
  17692. private $collectCodeCoverageInformation;
  17693. /**
  17694. * @var PHPUnit_Extensions_Selenium2TestCase_KeysHolder
  17695. */
  17696. private $keysHolder;
  17697. /**
  17698. * @param boolean
  17699. */
  17700. public static function shareSession($shareSession)
  17701. {
  17702. if (!is_bool($shareSession)) {
  17703. throw new InvalidArgumentException("The shared session support can only be switched on or off.");
  17704. }
  17705. if (!$shareSession) {
  17706. self::$sessionStrategy = self::defaultSessionStrategy();
  17707. } else {
  17708. self::$sessionStrategy = new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared(self::defaultSessionStrategy());
  17709. }
  17710. }
  17711. private static function sessionStrategy()
  17712. {
  17713. if (!self::$sessionStrategy) {
  17714. self::$sessionStrategy = self::defaultSessionStrategy();
  17715. }
  17716. return self::$sessionStrategy;
  17717. }
  17718. private static function defaultSessionStrategy()
  17719. {
  17720. return new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated;
  17721. }
  17722. public function __construct($name = NULL, array $data = array(), $dataName = '')
  17723. {
  17724. parent::__construct($name, $data, $dataName);
  17725. $this->parameters = array(
  17726. 'host' => 'localhost',
  17727. 'port' => 4444,
  17728. 'browser' => NULL,
  17729. 'browserName' => NULL,
  17730. 'desiredCapabilities' => array(),
  17731. 'seleniumServerRequestsTimeout' => 60
  17732. );
  17733. $this->keysHolder = new PHPUnit_Extensions_Selenium2TestCase_KeysHolder();
  17734. }
  17735. public function setupSpecificBrowser($params)
  17736. {
  17737. $this->setUpSessionStrategy($params);
  17738. $params = array_merge($this->parameters, $params);
  17739. $this->setHost($params['host']);
  17740. $this->setPort($params['port']);
  17741. $this->setBrowser($params['browserName']);
  17742. $this->parameters['browser'] = $params['browser'];
  17743. $this->setDesiredCapabilities($params['desiredCapabilities']);
  17744. $this->setSeleniumServerRequestsTimeout(
  17745. $params['seleniumServerRequestsTimeout']);
  17746. }
  17747. protected function setUpSessionStrategy($params)
  17748. {
  17749. // This logic enables us to have a session strategy reused for each
  17750. // item in self::$browsers. We don't want them both to share one
  17751. // and we don't want each test for a specific browser to have a
  17752. // new strategy
  17753. if ($params == self::$lastBrowserParams) {
  17754. // do nothing so we use the same session strategy for this
  17755. // browser
  17756. } elseif (isset($params['sessionStrategy'])) {
  17757. $strat = $params['sessionStrategy'];
  17758. if ($strat != "isolated" && $strat != "shared") {
  17759. throw new InvalidArgumentException("Session strategy must be either 'isolated' or 'shared'");
  17760. } elseif ($strat == "isolated") {
  17761. self::$browserSessionStrategy = new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated;
  17762. } else {
  17763. self::$browserSessionStrategy = new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared(self::defaultSessionStrategy());
  17764. }
  17765. } else {
  17766. self::$browserSessionStrategy = self::defaultSessionStrategy();
  17767. }
  17768. self::$lastBrowserParams = $params;
  17769. $this->localSessionStrategy = self::$browserSessionStrategy;
  17770. }
  17771. private function getStrategy()
  17772. {
  17773. if ($this->localSessionStrategy) {
  17774. return $this->localSessionStrategy;
  17775. } else {
  17776. return self::sessionStrategy();
  17777. }
  17778. }
  17779. public function prepareSession()
  17780. {
  17781. try {
  17782. if (!$this->session) {
  17783. $this->session = $this->getStrategy()->session($this->parameters);
  17784. }
  17785. } catch (PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException $e) {
  17786. $this->markTestSkipped("The Selenium Server is not active on host {$this->parameters['host']} at port {$this->parameters['port']}.");
  17787. }
  17788. return $this->session;
  17789. }
  17790. public function run(PHPUnit_Framework_TestResult $result = NULL)
  17791. {
  17792. $this->testId = get_class($this) . '__' . $this->getName();
  17793. if ($result === NULL) {
  17794. $result = $this->createResult();
  17795. }
  17796. $this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
  17797. parent::run($result);
  17798. if ($this->collectCodeCoverageInformation) {
  17799. $coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
  17800. $this->coverageScriptUrl,
  17801. $this->testId
  17802. );
  17803. $result->getCodeCoverage()->append(
  17804. $coverage->get(), $this
  17805. );
  17806. }
  17807. // do not call this before to give the time to the Listeners to run
  17808. $this->getStrategy()->endOfTest($this->session);
  17809. return $result;
  17810. }
  17811. /**
  17812. * @throws RuntimeException
  17813. */
  17814. protected function runTest()
  17815. {
  17816. $this->prepareSession();
  17817. $thrownException = NULL;
  17818. if ($this->collectCodeCoverageInformation) {
  17819. $this->url($this->coverageScriptUrl); // phpunit_coverage.php won't do anything if the cookie isn't set, which is exactly what we want
  17820. $this->session->cookie()->add('PHPUNIT_SELENIUM_TEST_ID', $this->testId)->set();
  17821. }
  17822. try {
  17823. $this->setUpPage();
  17824. $result = parent::runTest();
  17825. if (!empty($this->verificationErrors)) {
  17826. $this->fail(implode("\n", $this->verificationErrors));
  17827. }
  17828. } catch (Exception $e) {
  17829. $thrownException = $e;
  17830. }
  17831. if ($this->collectCodeCoverageInformation) {
  17832. $this->session->cookie()->remove('PHPUNIT_SELENIUM_TEST_ID');
  17833. }
  17834. if (NULL !== $thrownException) {
  17835. throw $thrownException;
  17836. }
  17837. return $result;
  17838. }
  17839. public static function suite($className)
  17840. {
  17841. return PHPUnit_Extensions_SeleniumTestSuite::fromTestCaseClass($className);
  17842. }
  17843. public function onNotSuccessfulTest(Exception $e)
  17844. {
  17845. $this->getStrategy()->notSuccessfulTest();
  17846. parent::onNotSuccessfulTest($e);
  17847. }
  17848. /**
  17849. * Delegate method calls to the Session.
  17850. *
  17851. * @param string $command
  17852. * @param array $arguments
  17853. * @return mixed
  17854. */
  17855. public function __call($command, $arguments)
  17856. {
  17857. if ($this->session === NULL) {
  17858. throw new PHPUnit_Extensions_Selenium2TestCase_Exception("There is currently no active session to execute the '$command' command. You're probably trying to set some option in setUp() with an incorrect setter name. You may consider using setUpPage() instead.");
  17859. }
  17860. $result = call_user_func_array(
  17861. array($this->session, $command), $arguments
  17862. );
  17863. return $result;
  17864. }
  17865. /**
  17866. * @param string $host
  17867. * @throws InvalidArgumentException
  17868. */
  17869. public function setHost($host)
  17870. {
  17871. if (!is_string($host)) {
  17872. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  17873. }
  17874. $this->parameters['host'] = $host;
  17875. }
  17876. public function getHost()
  17877. {
  17878. return $this->parameters['host'];
  17879. }
  17880. /**
  17881. * @param integer $port
  17882. * @throws InvalidArgumentException
  17883. */
  17884. public function setPort($port)
  17885. {
  17886. if (!is_int($port)) {
  17887. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  17888. }
  17889. $this->parameters['port'] = $port;
  17890. }
  17891. public function getPort()
  17892. {
  17893. return $this->parameters['port'];
  17894. }
  17895. /**
  17896. * @param string $browser
  17897. * @throws InvalidArgumentException
  17898. */
  17899. public function setBrowser($browserName)
  17900. {
  17901. if (!is_string($browserName)) {
  17902. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  17903. }
  17904. $this->parameters['browserName'] = $browserName;
  17905. }
  17906. public function getBrowser()
  17907. {
  17908. return $this->parameters['browserName'];
  17909. }
  17910. /**
  17911. * @param string $browserUrl
  17912. * @throws InvalidArgumentException
  17913. */
  17914. public function setBrowserUrl($browserUrl)
  17915. {
  17916. if (!is_string($browserUrl)) {
  17917. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  17918. }
  17919. $this->parameters['browserUrl'] = new PHPUnit_Extensions_Selenium2TestCase_URL($browserUrl);
  17920. }
  17921. public function getBrowserUrl()
  17922. {
  17923. if (isset($this->parameters['browserUrl'])) {
  17924. return $this->parameters['browserUrl'];
  17925. }
  17926. return '';
  17927. }
  17928. /**
  17929. * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
  17930. */
  17931. public function setDesiredCapabilities(array $capabilities)
  17932. {
  17933. $this->parameters['desiredCapabilities'] = $capabilities;
  17934. }
  17935. public function getDesiredCapabilities()
  17936. {
  17937. return $this->parameters['desiredCapabilities'];
  17938. }
  17939. /**
  17940. * @param int $timeout seconds
  17941. */
  17942. public function setSeleniumServerRequestsTimeout($timeout)
  17943. {
  17944. $this->parameters['seleniumServerRequestsTimeout'] = $timeout;
  17945. }
  17946. public function getSeleniumServerRequestsTimeout()
  17947. {
  17948. return $this->parameters['seleniumServerRequestsTimeout'];
  17949. }
  17950. /**
  17951. * Get test id (generated internally)
  17952. * @return string
  17953. */
  17954. public function getTestId()
  17955. {
  17956. return $this->testId;
  17957. }
  17958. /**
  17959. * Get Selenium2 current session id
  17960. * @return string
  17961. */
  17962. public function getSessionId()
  17963. {
  17964. if ($this->session) {
  17965. return $this->session->id();
  17966. }
  17967. return FALSE;
  17968. }
  17969. /**
  17970. * Wait until callback isn't null or timeout occurs
  17971. *
  17972. * @param $callback
  17973. * @param null $timeout
  17974. * @return mixed
  17975. */
  17976. public function waitUntil($callback, $timeout = NULL)
  17977. {
  17978. $waitUntil = new PHPUnit_Extensions_Selenium2TestCase_WaitUntil($this);
  17979. return $waitUntil->run($callback, $timeout);
  17980. }
  17981. /**
  17982. * Sends a special key
  17983. * Deprecated due to issues with IE webdriver. Use keys() method instead
  17984. * @deprecated
  17985. * @param string $name
  17986. * @throws PHPUnit_Extensions_Selenium2TestCase_Exception
  17987. * @see PHPUnit_Extensions_Selenium2TestCase_KeysHolder
  17988. */
  17989. public function keysSpecial($name)
  17990. {
  17991. $names = explode(',', $name);
  17992. foreach ($names as $key) {
  17993. $this->keys($this->keysHolder->specialKey(trim($key)));
  17994. }
  17995. }
  17996. /**
  17997. * setUp method that is called after the session has been prepared.
  17998. * It is possible to use session-specific commands like url() here.
  17999. */
  18000. public function setUpPage()
  18001. {
  18002. }
  18003. }
  18004. <?php
  18005. /*
  18006. * This file is part of the PHP_CodeCoverage package.
  18007. *
  18008. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  18009. *
  18010. * For the full copyright and license information, please view the LICENSE
  18011. * file that was distributed with this source code.
  18012. */
  18013. /**
  18014. * Utility methods.
  18015. *
  18016. * @category PHP
  18017. * @package CodeCoverage
  18018. * @author Sebastian Bergmann <sebastian@phpunit.de>
  18019. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  18020. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  18021. * @link http://github.com/sebastianbergmann/php-code-coverage
  18022. * @since Class available since Release 1.0.0
  18023. */
  18024. class PHP_CodeCoverage_Util
  18025. {
  18026. /**
  18027. * @param float $a
  18028. * @param float $b
  18029. * @return float ($a / $b) * 100
  18030. */
  18031. public static function percent($a, $b, $asString = false, $fixedWidth = false)
  18032. {
  18033. if ($asString && $b == 0) {
  18034. return '';
  18035. }
  18036. if ($b > 0) {
  18037. $percent = ($a / $b) * 100;
  18038. } else {
  18039. $percent = 100;
  18040. }
  18041. if ($asString) {
  18042. if ($fixedWidth) {
  18043. return sprintf('%6.2F%%', $percent);
  18044. }
  18045. return sprintf('%01.2F%%', $percent);
  18046. } else {
  18047. return $percent;
  18048. }
  18049. }
  18050. }
  18051. <?php
  18052. /*
  18053. * This file is part of the PHP_CodeCoverage package.
  18054. *
  18055. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  18056. *
  18057. * For the full copyright and license information, please view the LICENSE
  18058. * file that was distributed with this source code.
  18059. */
  18060. /**
  18061. * Exception class for PHP_CodeCoverage component.
  18062. *
  18063. * @category PHP
  18064. * @package CodeCoverage
  18065. * @author Sebastian Bergmann <sebastian@phpunit.de>
  18066. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  18067. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  18068. * @link http://github.com/sebastianbergmann/php-code-coverage
  18069. * @since Class available since Release 1.1.0
  18070. */
  18071. class PHP_CodeCoverage_Exception extends RuntimeException
  18072. {
  18073. }
  18074. <?php
  18075. /*
  18076. * This file is part of the PHP_CodeCoverage package.
  18077. *
  18078. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  18079. *
  18080. * For the full copyright and license information, please view the LICENSE
  18081. * file that was distributed with this source code.
  18082. */
  18083. use SebastianBergmann\Environment\Runtime;
  18084. /**
  18085. * Base class for PHP_CodeCoverage_Report_Node renderers.
  18086. *
  18087. * @category PHP
  18088. * @package CodeCoverage
  18089. * @author Sebastian Bergmann <sebastian@phpunit.de>
  18090. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  18091. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  18092. * @link http://github.com/sebastianbergmann/php-code-coverage
  18093. * @since Class available since Release 1.1.0
  18094. */
  18095. abstract class PHP_CodeCoverage_Report_HTML_Renderer
  18096. {
  18097. /**
  18098. * @var string
  18099. */
  18100. protected $templatePath;
  18101. /**
  18102. * @var string
  18103. */
  18104. protected $generator;
  18105. /**
  18106. * @var string
  18107. */
  18108. protected $date;
  18109. /**
  18110. * @var integer
  18111. */
  18112. protected $lowUpperBound;
  18113. /**
  18114. * @var integer
  18115. */
  18116. protected $highLowerBound;
  18117. /**
  18118. * @var string
  18119. */
  18120. protected $version;
  18121. /**
  18122. * Constructor.
  18123. *
  18124. * @param string $templatePath
  18125. * @param string $generator
  18126. * @param string $date
  18127. * @param integer $lowUpperBound
  18128. * @param integer $highLowerBound
  18129. */
  18130. public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
  18131. {
  18132. $version = new SebastianBergmann\Version('2.1.3', dirname(dirname(dirname(dirname(__DIR__)))));
  18133. $this->templatePath = $templatePath;
  18134. $this->generator = $generator;
  18135. $this->date = $date;
  18136. $this->lowUpperBound = $lowUpperBound;
  18137. $this->highLowerBound = $highLowerBound;
  18138. $this->version = $version->getVersion();
  18139. }
  18140. /**
  18141. * @param Text_Template $template
  18142. * @param array $data
  18143. * @return string
  18144. */
  18145. protected function renderItemTemplate(Text_Template $template, array $data)
  18146. {
  18147. $numSeparator = '&nbsp;/&nbsp;';
  18148. $classesBar = '&nbsp;';
  18149. $classesLevel = 'None';
  18150. $classesNumber = '&nbsp;';
  18151. if (isset($data['numClasses']) && $data['numClasses'] > 0) {
  18152. $classesLevel = $this->getColorLevel($data['testedClassesPercent']);
  18153. $classesNumber = $data['numTestedClasses'] . $numSeparator .
  18154. $data['numClasses'];
  18155. $classesBar = $this->getCoverageBar(
  18156. $data['testedClassesPercent']
  18157. );
  18158. }
  18159. $methodsBar = '&nbsp;';
  18160. $methodsLevel = 'None';
  18161. $methodsNumber = '&nbsp;';
  18162. if ($data['numMethods'] > 0) {
  18163. $methodsLevel = $this->getColorLevel($data['testedMethodsPercent']);
  18164. $methodsNumber = $data['numTestedMethods'] . $numSeparator .
  18165. $data['numMethods'];
  18166. $methodsBar = $this->getCoverageBar(
  18167. $data['testedMethodsPercent']
  18168. );
  18169. }
  18170. $linesBar = '&nbsp;';
  18171. $linesLevel = 'None';
  18172. $linesNumber = '&nbsp;';
  18173. if ($data['numExecutableLines'] > 0) {
  18174. $linesLevel = $this->getColorLevel($data['linesExecutedPercent']);
  18175. $linesNumber = $data['numExecutedLines'] . $numSeparator .
  18176. $data['numExecutableLines'];
  18177. $linesBar = $this->getCoverageBar(
  18178. $data['linesExecutedPercent']
  18179. );
  18180. }
  18181. $template->setVar(
  18182. array(
  18183. 'icon' => isset($data['icon']) ? $data['icon'] : '',
  18184. 'crap' => isset($data['crap']) ? $data['crap'] : '',
  18185. 'name' => $data['name'],
  18186. 'lines_bar' => $linesBar,
  18187. 'lines_executed_percent' => $data['linesExecutedPercentAsString'],
  18188. 'lines_level' => $linesLevel,
  18189. 'lines_number' => $linesNumber,
  18190. 'methods_bar' => $methodsBar,
  18191. 'methods_tested_percent' => $data['testedMethodsPercentAsString'],
  18192. 'methods_level' => $methodsLevel,
  18193. 'methods_number' => $methodsNumber,
  18194. 'classes_bar' => $classesBar,
  18195. 'classes_tested_percent' => isset($data['testedClassesPercentAsString']) ? $data['testedClassesPercentAsString'] : '',
  18196. 'classes_level' => $classesLevel,
  18197. 'classes_number' => $classesNumber
  18198. )
  18199. );
  18200. return $template->render();
  18201. }
  18202. /**
  18203. * @param Text_Template $template
  18204. * @param PHP_CodeCoverage_Report_Node $node
  18205. */
  18206. protected function setCommonTemplateVariables(Text_Template $template, PHP_CodeCoverage_Report_Node $node)
  18207. {
  18208. $runtime = new Runtime;
  18209. $template->setVar(
  18210. array(
  18211. 'id' => $node->getId(),
  18212. 'full_path' => $node->getPath(),
  18213. 'path_to_root' => $this->getPathToRoot($node),
  18214. 'breadcrumbs' => $this->getBreadcrumbs($node),
  18215. 'date' => $this->date,
  18216. 'version' => $this->version,
  18217. 'runtime_name' => $runtime->getName(),
  18218. 'runtime_version' => $runtime->getVersion(),
  18219. 'runtime_link' => $runtime->getVendorUrl(),
  18220. 'generator' => $this->generator,
  18221. 'low_upper_bound' => $this->lowUpperBound,
  18222. 'high_lower_bound' => $this->highLowerBound
  18223. )
  18224. );
  18225. }
  18226. protected function getBreadcrumbs(PHP_CodeCoverage_Report_Node $node)
  18227. {
  18228. $breadcrumbs = '';
  18229. $path = $node->getPathAsArray();
  18230. $pathToRoot = array();
  18231. $max = count($path);
  18232. if ($node instanceof PHP_CodeCoverage_Report_Node_File) {
  18233. $max--;
  18234. }
  18235. for ($i = 0; $i < $max; $i++) {
  18236. $pathToRoot[] = str_repeat('../', $i);
  18237. }
  18238. foreach ($path as $step) {
  18239. if ($step !== $node) {
  18240. $breadcrumbs .= $this->getInactiveBreadcrumb(
  18241. $step,
  18242. array_pop($pathToRoot)
  18243. );
  18244. } else {
  18245. $breadcrumbs .= $this->getActiveBreadcrumb($step);
  18246. }
  18247. }
  18248. return $breadcrumbs;
  18249. }
  18250. protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node)
  18251. {
  18252. $buffer = sprintf(
  18253. ' <li class="active">%s</li>' . "\n",
  18254. $node->getName()
  18255. );
  18256. if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
  18257. $buffer .= ' <li>(<a href="dashboard.html">Dashboard</a>)</li>' . "\n";
  18258. }
  18259. return $buffer;
  18260. }
  18261. protected function getInactiveBreadcrumb(PHP_CodeCoverage_Report_Node $node, $pathToRoot)
  18262. {
  18263. return sprintf(
  18264. ' <li><a href="%sindex.html">%s</a></li>' . "\n",
  18265. $pathToRoot,
  18266. $node->getName()
  18267. );
  18268. }
  18269. protected function getPathToRoot(PHP_CodeCoverage_Report_Node $node)
  18270. {
  18271. $id = $node->getId();
  18272. $depth = substr_count($id, '/');
  18273. if ($id != 'index' &&
  18274. $node instanceof PHP_CodeCoverage_Report_Node_Directory) {
  18275. $depth++;
  18276. }
  18277. return str_repeat('../', $depth);
  18278. }
  18279. protected function getCoverageBar($percent)
  18280. {
  18281. $level = $this->getColorLevel($percent);
  18282. $template = new Text_Template(
  18283. $this->templatePath . 'coverage_bar.html',
  18284. '{{',
  18285. '}}'
  18286. );
  18287. $template->setVar(array('level' => $level, 'percent' => sprintf("%.2F", $percent)));
  18288. return $template->render();
  18289. }
  18290. /**
  18291. * @param integer $percent
  18292. * @return string
  18293. */
  18294. protected function getColorLevel($percent)
  18295. {
  18296. if ($percent <= $this->lowUpperBound) {
  18297. return 'danger';
  18298. } elseif ($percent > $this->lowUpperBound &&
  18299. $percent < $this->highLowerBound) {
  18300. return 'warning';
  18301. } else {
  18302. return 'success';
  18303. }
  18304. }
  18305. }
  18306. <?php
  18307. /*
  18308. * This file is part of the PHP_CodeCoverage package.
  18309. *
  18310. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  18311. *
  18312. * For the full copyright and license information, please view the LICENSE
  18313. * file that was distributed with this source code.
  18314. */
  18315. /**
  18316. * Renders the dashboard for a PHP_CodeCoverage_Report_Node_Directory node.
  18317. *
  18318. * @category PHP
  18319. * @package CodeCoverage
  18320. * @author Sebastian Bergmann <sebastian@phpunit.de>
  18321. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  18322. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  18323. * @link http://github.com/sebastianbergmann/php-code-coverage
  18324. * @since Class available since Release 1.1.0
  18325. */
  18326. class PHP_CodeCoverage_Report_HTML_Renderer_Dashboard extends PHP_CodeCoverage_Report_HTML_Renderer
  18327. {
  18328. /**
  18329. * @param PHP_CodeCoverage_Report_Node_Directory $node
  18330. * @param string $file
  18331. */
  18332. public function render(PHP_CodeCoverage_Report_Node_Directory $node, $file)
  18333. {
  18334. $classes = $node->getClassesAndTraits();
  18335. $template = new Text_Template(
  18336. $this->templatePath . 'dashboard.html',
  18337. '{{',
  18338. '}}'
  18339. );
  18340. $this->setCommonTemplateVariables($template, $node);
  18341. $baseLink = $node->getId() . '/';
  18342. $complexity = $this->complexity($classes, $baseLink);
  18343. $coverageDistribution = $this->coverageDistribution($classes);
  18344. $insufficientCoverage = $this->insufficientCoverage($classes, $baseLink);
  18345. $projectRisks = $this->projectRisks($classes, $baseLink);
  18346. $template->setVar(
  18347. array(
  18348. 'insufficient_coverage_classes' => $insufficientCoverage['class'],
  18349. 'insufficient_coverage_methods' => $insufficientCoverage['method'],
  18350. 'project_risks_classes' => $projectRisks['class'],
  18351. 'project_risks_methods' => $projectRisks['method'],
  18352. 'complexity_class' => $complexity['class'],
  18353. 'complexity_method' => $complexity['method'],
  18354. 'class_coverage_distribution' => $coverageDistribution['class'],
  18355. 'method_coverage_distribution' => $coverageDistribution['method']
  18356. )
  18357. );
  18358. $template->renderTo($file);
  18359. }
  18360. /**
  18361. * Returns the data for the Class/Method Complexity charts.
  18362. *
  18363. * @param array $classes
  18364. * @param string $baseLink
  18365. * @return array
  18366. */
  18367. protected function complexity(array $classes, $baseLink)
  18368. {
  18369. $result = array('class' => array(), 'method' => array());
  18370. foreach ($classes as $className => $class) {
  18371. foreach ($class['methods'] as $methodName => $method) {
  18372. if ($className != '*') {
  18373. $methodName = $className . '::' . $methodName;
  18374. }
  18375. $result['method'][] = array(
  18376. $method['coverage'],
  18377. $method['ccn'],
  18378. sprintf(
  18379. '<a href="%s">%s</a>',
  18380. str_replace($baseLink, '', $method['link']),
  18381. $methodName
  18382. )
  18383. );
  18384. }
  18385. $result['class'][] = array(
  18386. $class['coverage'],
  18387. $class['ccn'],
  18388. sprintf(
  18389. '<a href="%s">%s</a>',
  18390. str_replace($baseLink, '', $class['link']),
  18391. $className
  18392. )
  18393. );
  18394. }
  18395. return array(
  18396. 'class' => json_encode($result['class']),
  18397. 'method' => json_encode($result['method'])
  18398. );
  18399. }
  18400. /**
  18401. * Returns the data for the Class / Method Coverage Distribution chart.
  18402. *
  18403. * @param array $classes
  18404. * @return array
  18405. */
  18406. protected function coverageDistribution(array $classes)
  18407. {
  18408. $result = array(
  18409. 'class' => array(
  18410. '0%' => 0,
  18411. '0-10%' => 0,
  18412. '10-20%' => 0,
  18413. '20-30%' => 0,
  18414. '30-40%' => 0,
  18415. '40-50%' => 0,
  18416. '50-60%' => 0,
  18417. '60-70%' => 0,
  18418. '70-80%' => 0,
  18419. '80-90%' => 0,
  18420. '90-100%' => 0,
  18421. '100%' => 0
  18422. ),
  18423. 'method' => array(
  18424. '0%' => 0,
  18425. '0-10%' => 0,
  18426. '10-20%' => 0,
  18427. '20-30%' => 0,
  18428. '30-40%' => 0,
  18429. '40-50%' => 0,
  18430. '50-60%' => 0,
  18431. '60-70%' => 0,
  18432. '70-80%' => 0,
  18433. '80-90%' => 0,
  18434. '90-100%' => 0,
  18435. '100%' => 0
  18436. )
  18437. );
  18438. foreach ($classes as $class) {
  18439. foreach ($class['methods'] as $methodName => $method) {
  18440. if ($method['coverage'] == 0) {
  18441. $result['method']['0%']++;
  18442. } elseif ($method['coverage'] == 100) {
  18443. $result['method']['100%']++;
  18444. } else {
  18445. $key = floor($method['coverage'] / 10) * 10;
  18446. $key = $key . '-' . ($key + 10) . '%';
  18447. $result['method'][$key]++;
  18448. }
  18449. }
  18450. if ($class['coverage'] == 0) {
  18451. $result['class']['0%']++;
  18452. } elseif ($class['coverage'] == 100) {
  18453. $result['class']['100%']++;
  18454. } else {
  18455. $key = floor($class['coverage'] / 10) * 10;
  18456. $key = $key . '-' . ($key + 10) . '%';
  18457. $result['class'][$key]++;
  18458. }
  18459. }
  18460. return array(
  18461. 'class' => json_encode(array_values($result['class'])),
  18462. 'method' => json_encode(array_values($result['method']))
  18463. );
  18464. }
  18465. /**
  18466. * Returns the classes / methods with insufficient coverage.
  18467. *
  18468. * @param array $classes
  18469. * @param string $baseLink
  18470. * @return array
  18471. */
  18472. protected function insufficientCoverage(array $classes, $baseLink)
  18473. {
  18474. $leastTestedClasses = array();
  18475. $leastTestedMethods = array();
  18476. $result = array('class' => '', 'method' => '');
  18477. foreach ($classes as $className => $class) {
  18478. foreach ($class['methods'] as $methodName => $method) {
  18479. if ($method['coverage'] < $this->highLowerBound) {
  18480. if ($className != '*') {
  18481. $key = $className . '::' . $methodName;
  18482. } else {
  18483. $key = $methodName;
  18484. }
  18485. $leastTestedMethods[$key] = $method['coverage'];
  18486. }
  18487. }
  18488. if ($class['coverage'] < $this->highLowerBound) {
  18489. $leastTestedClasses[$className] = $class['coverage'];
  18490. }
  18491. }
  18492. asort($leastTestedClasses);
  18493. asort($leastTestedMethods);
  18494. foreach ($leastTestedClasses as $className => $coverage) {
  18495. $result['class'] .= sprintf(
  18496. ' <tr><td><a href="%s">%s</a></td><td class="text-right">%d%%</td></tr>' . "\n",
  18497. str_replace($baseLink, '', $classes[$className]['link']),
  18498. $className,
  18499. $coverage
  18500. );
  18501. }
  18502. foreach ($leastTestedMethods as $methodName => $coverage) {
  18503. list($class, $method) = explode('::', $methodName);
  18504. $result['method'] .= sprintf(
  18505. ' <tr><td><a href="%s"><abbr title="%s">%s</a></a></td><td class="text-right">%d%%</td></tr>' . "\n",
  18506. str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
  18507. $methodName,
  18508. $method,
  18509. $coverage
  18510. );
  18511. }
  18512. return $result;
  18513. }
  18514. /**
  18515. * Returns the project risks according to the CRAP index.
  18516. *
  18517. * @param array $classes
  18518. * @param string $baseLink
  18519. * @return array
  18520. */
  18521. protected function projectRisks(array $classes, $baseLink)
  18522. {
  18523. $classRisks = array();
  18524. $methodRisks = array();
  18525. $result = array('class' => '', 'method' => '');
  18526. foreach ($classes as $className => $class) {
  18527. foreach ($class['methods'] as $methodName => $method) {
  18528. if ($method['coverage'] < $this->highLowerBound &&
  18529. $method['ccn'] > 1) {
  18530. if ($className != '*') {
  18531. $key = $className . '::' . $methodName;
  18532. } else {
  18533. $key = $methodName;
  18534. }
  18535. $methodRisks[$key] = $method['crap'];
  18536. }
  18537. }
  18538. if ($class['coverage'] < $this->highLowerBound &&
  18539. $class['ccn'] > count($class['methods'])) {
  18540. $classRisks[$className] = $class['crap'];
  18541. }
  18542. }
  18543. arsort($classRisks);
  18544. arsort($methodRisks);
  18545. foreach ($classRisks as $className => $crap) {
  18546. $result['class'] .= sprintf(
  18547. ' <tr><td><a href="%s">%s</a></td><td class="text-right">%d</td></tr>' . "\n",
  18548. str_replace($baseLink, '', $classes[$className]['link']),
  18549. $className,
  18550. $crap
  18551. );
  18552. }
  18553. foreach ($methodRisks as $methodName => $crap) {
  18554. list($class, $method) = explode('::', $methodName);
  18555. $result['method'] .= sprintf(
  18556. ' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d</td></tr>' . "\n",
  18557. str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
  18558. $methodName,
  18559. $method,
  18560. $crap
  18561. );
  18562. }
  18563. return $result;
  18564. }
  18565. protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node)
  18566. {
  18567. return sprintf(
  18568. ' <li><a href="index.html">%s</a></li>' . "\n" .
  18569. ' <li class="active">(Dashboard)</li>' . "\n",
  18570. $node->getName()
  18571. );
  18572. }
  18573. }
  18574. <?php
  18575. /*
  18576. * This file is part of the PHP_CodeCoverage package.
  18577. *
  18578. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  18579. *
  18580. * For the full copyright and license information, please view the LICENSE
  18581. * file that was distributed with this source code.
  18582. */
  18583. // @codeCoverageIgnoreStart
  18584. if (!defined('T_TRAIT')) {
  18585. define('T_TRAIT', 1001);
  18586. }
  18587. if (!defined('T_INSTEADOF')) {
  18588. define('T_INSTEADOF', 1002);
  18589. }
  18590. if (!defined('T_CALLABLE')) {
  18591. define('T_CALLABLE', 1003);
  18592. }
  18593. if (!defined('T_FINALLY')) {
  18594. define('T_FINALLY', 1004);
  18595. }
  18596. if (!defined('T_YIELD')) {
  18597. define('T_YIELD', 1005);
  18598. }
  18599. // @codeCoverageIgnoreEnd
  18600. /**
  18601. * Renders a PHP_CodeCoverage_Report_Node_File node.
  18602. *
  18603. * @category PHP
  18604. * @package CodeCoverage
  18605. * @author Sebastian Bergmann <sebastian@phpunit.de>
  18606. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  18607. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  18608. * @link http://github.com/sebastianbergmann/php-code-coverage
  18609. * @since Class available since Release 1.1.0
  18610. */
  18611. class PHP_CodeCoverage_Report_HTML_Renderer_File extends PHP_CodeCoverage_Report_HTML_Renderer
  18612. {
  18613. /**
  18614. * @var integer
  18615. */
  18616. private $htmlspecialcharsFlags;
  18617. /**
  18618. * Constructor.
  18619. *
  18620. * @param string $templatePath
  18621. * @param string $generator
  18622. * @param string $date
  18623. * @param integer $lowUpperBound
  18624. * @param integer $highLowerBound
  18625. */
  18626. public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
  18627. {
  18628. parent::__construct(
  18629. $templatePath,
  18630. $generator,
  18631. $date,
  18632. $lowUpperBound,
  18633. $highLowerBound
  18634. );
  18635. $this->htmlspecialcharsFlags = ENT_COMPAT;
  18636. if (defined('ENT_SUBSTITUTE')) {
  18637. $this->htmlspecialcharsFlags = $this->htmlspecialcharsFlags | ENT_HTML401 | ENT_SUBSTITUTE;
  18638. }
  18639. }
  18640. /**
  18641. * @param PHP_CodeCoverage_Report_Node_File $node
  18642. * @param string $file
  18643. */
  18644. public function render(PHP_CodeCoverage_Report_Node_File $node, $file)
  18645. {
  18646. $template = new Text_Template($this->templatePath . 'file.html', '{{', '}}');
  18647. $template->setVar(
  18648. array(
  18649. 'items' => $this->renderItems($node),
  18650. 'lines' => $this->renderSource($node)
  18651. )
  18652. );
  18653. $this->setCommonTemplateVariables($template, $node);
  18654. $template->renderTo($file);
  18655. }
  18656. /**
  18657. * @param PHP_CodeCoverage_Report_Node_File $node
  18658. * @return string
  18659. */
  18660. protected function renderItems(PHP_CodeCoverage_Report_Node_File $node)
  18661. {
  18662. $template = new Text_Template($this->templatePath . 'file_item.html', '{{', '}}');
  18663. $methodItemTemplate = new Text_Template(
  18664. $this->templatePath . 'method_item.html',
  18665. '{{',
  18666. '}}'
  18667. );
  18668. $items = $this->renderItemTemplate(
  18669. $template,
  18670. array(
  18671. 'name' => 'Total',
  18672. 'numClasses' => $node->getNumClassesAndTraits(),
  18673. 'numTestedClasses' => $node->getNumTestedClassesAndTraits(),
  18674. 'numMethods' => $node->getNumMethods(),
  18675. 'numTestedMethods' => $node->getNumTestedMethods(),
  18676. 'linesExecutedPercent' => $node->getLineExecutedPercent(false),
  18677. 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(),
  18678. 'numExecutedLines' => $node->getNumExecutedLines(),
  18679. 'numExecutableLines' => $node->getNumExecutableLines(),
  18680. 'testedMethodsPercent' => $node->getTestedMethodsPercent(false),
  18681. 'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(),
  18682. 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false),
  18683. 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(),
  18684. 'crap' => '<abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr>'
  18685. )
  18686. );
  18687. $items .= $this->renderFunctionItems(
  18688. $node->getFunctions(),
  18689. $methodItemTemplate
  18690. );
  18691. $items .= $this->renderTraitOrClassItems(
  18692. $node->getTraits(),
  18693. $template,
  18694. $methodItemTemplate
  18695. );
  18696. $items .= $this->renderTraitOrClassItems(
  18697. $node->getClasses(),
  18698. $template,
  18699. $methodItemTemplate
  18700. );
  18701. return $items;
  18702. }
  18703. /**
  18704. * @param array $items
  18705. * @param Text_Template $template
  18706. * @param Text_Template $methodItemTemplate
  18707. * @return string
  18708. */
  18709. protected function renderTraitOrClassItems(array $items, Text_Template $template, Text_Template $methodItemTemplate)
  18710. {
  18711. if (empty($items)) {
  18712. return '';
  18713. }
  18714. $buffer = '';
  18715. foreach ($items as $name => $item) {
  18716. $numMethods = count($item['methods']);
  18717. $numTestedMethods = 0;
  18718. foreach ($item['methods'] as $method) {
  18719. if ($method['executedLines'] == $method['executableLines']) {
  18720. $numTestedMethods++;
  18721. }
  18722. }
  18723. $buffer .= $this->renderItemTemplate(
  18724. $template,
  18725. array(
  18726. 'name' => $name,
  18727. 'numClasses' => 1,
  18728. 'numTestedClasses' => $numTestedMethods == $numMethods ? 1 : 0,
  18729. 'numMethods' => $numMethods,
  18730. 'numTestedMethods' => $numTestedMethods,
  18731. 'linesExecutedPercent' => PHP_CodeCoverage_Util::percent(
  18732. $item['executedLines'],
  18733. $item['executableLines'],
  18734. false
  18735. ),
  18736. 'linesExecutedPercentAsString' => PHP_CodeCoverage_Util::percent(
  18737. $item['executedLines'],
  18738. $item['executableLines'],
  18739. true
  18740. ),
  18741. 'numExecutedLines' => $item['executedLines'],
  18742. 'numExecutableLines' => $item['executableLines'],
  18743. 'testedMethodsPercent' => PHP_CodeCoverage_Util::percent(
  18744. $numTestedMethods,
  18745. $numMethods,
  18746. false
  18747. ),
  18748. 'testedMethodsPercentAsString' => PHP_CodeCoverage_Util::percent(
  18749. $numTestedMethods,
  18750. $numMethods,
  18751. true
  18752. ),
  18753. 'testedClassesPercent' => PHP_CodeCoverage_Util::percent(
  18754. $numTestedMethods == $numMethods ? 1 : 0,
  18755. 1,
  18756. false
  18757. ),
  18758. 'testedClassesPercentAsString' => PHP_CodeCoverage_Util::percent(
  18759. $numTestedMethods == $numMethods ? 1 : 0,
  18760. 1,
  18761. true
  18762. ),
  18763. 'crap' => $item['crap']
  18764. )
  18765. );
  18766. foreach ($item['methods'] as $method) {
  18767. $buffer .= $this->renderFunctionOrMethodItem(
  18768. $methodItemTemplate,
  18769. $method,
  18770. '&nbsp;'
  18771. );
  18772. }
  18773. }
  18774. return $buffer;
  18775. }
  18776. /**
  18777. * @param array $functions
  18778. * @param Text_Template $template
  18779. * @return string
  18780. */
  18781. protected function renderFunctionItems(array $functions, Text_Template $template)
  18782. {
  18783. if (empty($functions)) {
  18784. return '';
  18785. }
  18786. $buffer = '';
  18787. foreach ($functions as $function) {
  18788. $buffer .= $this->renderFunctionOrMethodItem(
  18789. $template,
  18790. $function
  18791. );
  18792. }
  18793. return $buffer;
  18794. }
  18795. /**
  18796. * @param Text_Template $template
  18797. * @return string
  18798. */
  18799. protected function renderFunctionOrMethodItem(Text_Template $template, array $item, $indent = '')
  18800. {
  18801. $numTestedItems = $item['executedLines'] == $item['executableLines'] ? 1 : 0;
  18802. return $this->renderItemTemplate(
  18803. $template,
  18804. array(
  18805. 'name' => sprintf(
  18806. '%s<a href="#%d"><abbr title="%s">%s</abbr></a>',
  18807. $indent,
  18808. $item['startLine'],
  18809. htmlspecialchars($item['signature']),
  18810. isset($item['functionName']) ? $item['functionName'] : $item['methodName']
  18811. ),
  18812. 'numMethods' => 1,
  18813. 'numTestedMethods' => $numTestedItems,
  18814. 'linesExecutedPercent' => PHP_CodeCoverage_Util::percent(
  18815. $item['executedLines'],
  18816. $item['executableLines'],
  18817. false
  18818. ),
  18819. 'linesExecutedPercentAsString' => PHP_CodeCoverage_Util::percent(
  18820. $item['executedLines'],
  18821. $item['executableLines'],
  18822. true
  18823. ),
  18824. 'numExecutedLines' => $item['executedLines'],
  18825. 'numExecutableLines' => $item['executableLines'],
  18826. 'testedMethodsPercent' => PHP_CodeCoverage_Util::percent(
  18827. $numTestedItems,
  18828. 1,
  18829. false
  18830. ),
  18831. 'testedMethodsPercentAsString' => PHP_CodeCoverage_Util::percent(
  18832. $numTestedItems,
  18833. 1,
  18834. true
  18835. ),
  18836. 'crap' => $item['crap']
  18837. )
  18838. );
  18839. }
  18840. /**
  18841. * @param PHP_CodeCoverage_Report_Node_File $node
  18842. * @return string
  18843. */
  18844. protected function renderSource(PHP_CodeCoverage_Report_Node_File $node)
  18845. {
  18846. $coverageData = $node->getCoverageData();
  18847. $testData = $node->getTestData();
  18848. $codeLines = $this->loadFile($node->getPath());
  18849. $lines = '';
  18850. $i = 1;
  18851. foreach ($codeLines as $line) {
  18852. $trClass = '';
  18853. $popoverContent = '';
  18854. $popoverTitle = '';
  18855. if (array_key_exists($i, $coverageData)) {
  18856. $numTests = count($coverageData[$i]);
  18857. if ($coverageData[$i] === null) {
  18858. $trClass = ' class="warning"';
  18859. } elseif ($numTests == 0) {
  18860. $trClass = ' class="danger"';
  18861. } else {
  18862. $lineCss = 'covered-by-large-tests';
  18863. $popoverContent = '<ul>';
  18864. if ($numTests > 1) {
  18865. $popoverTitle = $numTests . ' tests cover line ' . $i;
  18866. } else {
  18867. $popoverTitle = '1 test covers line ' . $i;
  18868. }
  18869. foreach ($coverageData[$i] as $test) {
  18870. if ($lineCss == 'covered-by-large-tests' && $testData[$test]['size'] == 'medium') {
  18871. $lineCss = 'covered-by-medium-tests';
  18872. } elseif ($testData[$test]['size'] == 'small') {
  18873. $lineCss = 'covered-by-small-tests';
  18874. }
  18875. switch ($testData[$test]['status']) {
  18876. case 0:
  18877. switch ($testData[$test]['size']) {
  18878. case 'small':
  18879. $testCSS = ' class="covered-by-small-tests"';
  18880. break;
  18881. case 'medium':
  18882. $testCSS = ' class="covered-by-medium-tests"';
  18883. break;
  18884. default:
  18885. $testCSS = ' class="covered-by-large-tests"';
  18886. break;
  18887. }
  18888. break;
  18889. case 1:
  18890. case 2:
  18891. $testCSS = ' class="warning"';
  18892. break;
  18893. case 3:
  18894. $testCSS = ' class="danger"';
  18895. break;
  18896. case 4:
  18897. $testCSS = ' class="danger"';
  18898. break;
  18899. default:
  18900. $testCSS = '';
  18901. }
  18902. $popoverContent .= sprintf(
  18903. '<li%s>%s</li>',
  18904. $testCSS,
  18905. htmlspecialchars($test)
  18906. );
  18907. }
  18908. $popoverContent .= '</ul>';
  18909. $trClass = ' class="' . $lineCss . ' popin"';
  18910. }
  18911. }
  18912. if (!empty($popoverTitle)) {
  18913. $popover = sprintf(
  18914. ' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"',
  18915. $popoverTitle,
  18916. htmlspecialchars($popoverContent)
  18917. );
  18918. } else {
  18919. $popover = '';
  18920. }
  18921. $lines .= sprintf(
  18922. ' <tr%s%s><td><div align="right"><a name="%d"></a><a href="#%d">%d</a></div></td><td class="codeLine">%s</td></tr>' . "\n",
  18923. $trClass,
  18924. $popover,
  18925. $i,
  18926. $i,
  18927. $i,
  18928. $line
  18929. );
  18930. $i++;
  18931. }
  18932. return $lines;
  18933. }
  18934. /**
  18935. * @param string $file
  18936. * @return array
  18937. */
  18938. protected function loadFile($file)
  18939. {
  18940. $buffer = file_get_contents($file);
  18941. $tokens = token_get_all($buffer);
  18942. $result = array('');
  18943. $i = 0;
  18944. $stringFlag = false;
  18945. $fileEndsWithNewLine = substr($buffer, -1) == "\n";
  18946. unset($buffer);
  18947. foreach ($tokens as $j => $token) {
  18948. if (is_string($token)) {
  18949. if ($token === '"' && $tokens[$j - 1] !== '\\') {
  18950. $result[$i] .= sprintf(
  18951. '<span class="string">%s</span>',
  18952. htmlspecialchars($token)
  18953. );
  18954. $stringFlag = !$stringFlag;
  18955. } else {
  18956. $result[$i] .= sprintf(
  18957. '<span class="keyword">%s</span>',
  18958. htmlspecialchars($token)
  18959. );
  18960. }
  18961. continue;
  18962. }
  18963. list ($token, $value) = $token;
  18964. $value = str_replace(
  18965. array("\t", ' '),
  18966. array('&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;'),
  18967. htmlspecialchars($value, $this->htmlspecialcharsFlags)
  18968. );
  18969. if ($value === "\n") {
  18970. $result[++$i] = '';
  18971. } else {
  18972. $lines = explode("\n", $value);
  18973. foreach ($lines as $jj => $line) {
  18974. $line = trim($line);
  18975. if ($line !== '') {
  18976. if ($stringFlag) {
  18977. $colour = 'string';
  18978. } else {
  18979. switch ($token) {
  18980. case T_INLINE_HTML:
  18981. $colour = 'html';
  18982. break;
  18983. case T_COMMENT:
  18984. case T_DOC_COMMENT:
  18985. $colour = 'comment';
  18986. break;
  18987. case T_ABSTRACT:
  18988. case T_ARRAY:
  18989. case T_AS:
  18990. case T_BREAK:
  18991. case T_CALLABLE:
  18992. case T_CASE:
  18993. case T_CATCH:
  18994. case T_CLASS:
  18995. case T_CLONE:
  18996. case T_CONTINUE:
  18997. case T_DEFAULT:
  18998. case T_ECHO:
  18999. case T_ELSE:
  19000. case T_ELSEIF:
  19001. case T_EMPTY:
  19002. case T_ENDDECLARE:
  19003. case T_ENDFOR:
  19004. case T_ENDFOREACH:
  19005. case T_ENDIF:
  19006. case T_ENDSWITCH:
  19007. case T_ENDWHILE:
  19008. case T_EXIT:
  19009. case T_EXTENDS:
  19010. case T_FINAL:
  19011. case T_FINALLY:
  19012. case T_FOREACH:
  19013. case T_FUNCTION:
  19014. case T_GLOBAL:
  19015. case T_IF:
  19016. case T_IMPLEMENTS:
  19017. case T_INCLUDE:
  19018. case T_INCLUDE_ONCE:
  19019. case T_INSTANCEOF:
  19020. case T_INSTEADOF:
  19021. case T_INTERFACE:
  19022. case T_ISSET:
  19023. case T_LOGICAL_AND:
  19024. case T_LOGICAL_OR:
  19025. case T_LOGICAL_XOR:
  19026. case T_NAMESPACE:
  19027. case T_NEW:
  19028. case T_PRIVATE:
  19029. case T_PROTECTED:
  19030. case T_PUBLIC:
  19031. case T_REQUIRE:
  19032. case T_REQUIRE_ONCE:
  19033. case T_RETURN:
  19034. case T_STATIC:
  19035. case T_THROW:
  19036. case T_TRAIT:
  19037. case T_TRY:
  19038. case T_UNSET:
  19039. case T_USE:
  19040. case T_VAR:
  19041. case T_WHILE:
  19042. case T_YIELD:
  19043. $colour = 'keyword';
  19044. break;
  19045. default:
  19046. $colour = 'default';
  19047. }
  19048. }
  19049. $result[$i] .= sprintf(
  19050. '<span class="%s">%s</span>',
  19051. $colour,
  19052. $line
  19053. );
  19054. }
  19055. if (isset($lines[$jj + 1])) {
  19056. $result[++$i] = '';
  19057. }
  19058. }
  19059. }
  19060. }
  19061. if ($fileEndsWithNewLine) {
  19062. unset($result[count($result)-1]);
  19063. }
  19064. return $result;
  19065. }
  19066. }
  19067. <!DOCTYPE html>
  19068. <html lang="en">
  19069. <head>
  19070. <meta charset="UTF-8">
  19071. <title>Dashboard for {{full_path}}</title>
  19072. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  19073. <link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
  19074. <link href="{{path_to_root}}css/nv.d3.min.css" rel="stylesheet">
  19075. <link href="{{path_to_root}}css/style.css" rel="stylesheet">
  19076. <!--[if lt IE 9]>
  19077. <script src="{{path_to_root}}js/html5shiv.min.js"></script>
  19078. <script src="{{path_to_root}}js/respond.min.js"></script>
  19079. <![endif]-->
  19080. </head>
  19081. <body>
  19082. <header>
  19083. <div class="container">
  19084. <div class="row">
  19085. <div class="col-md-12">
  19086. <ol class="breadcrumb">
  19087. {{breadcrumbs}}
  19088. </ol>
  19089. </div>
  19090. </div>
  19091. </div>
  19092. </header>
  19093. <div class="container">
  19094. <div class="row">
  19095. <div class="col-md-12">
  19096. <h2>Classes</h2>
  19097. </div>
  19098. </div>
  19099. <div class="row">
  19100. <div class="col-md-6">
  19101. <h3>Coverage Distribution</h3>
  19102. <div id="classCoverageDistribution" style="height: 300px;">
  19103. <svg></svg>
  19104. </div>
  19105. </div>
  19106. <div class="col-md-6">
  19107. <h3>Complexity</h3>
  19108. <div id="classComplexity" style="height: 300px;">
  19109. <svg></svg>
  19110. </div>
  19111. </div>
  19112. </div>
  19113. <div class="row">
  19114. <div class="col-md-6">
  19115. <h3>Insufficient Coverage</h3>
  19116. <div class="scrollbox">
  19117. <table class="table">
  19118. <thead>
  19119. <tr>
  19120. <th>Class</th>
  19121. <th class="text-right">Coverage</th>
  19122. </tr>
  19123. </thead>
  19124. <tbody>
  19125. {{insufficient_coverage_classes}}
  19126. </tbody>
  19127. </table>
  19128. </div>
  19129. </div>
  19130. <div class="col-md-6">
  19131. <h3>Project Risks</h3>
  19132. <div class="scrollbox">
  19133. <table class="table">
  19134. <thead>
  19135. <tr>
  19136. <th>Class</th>
  19137. <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
  19138. </tr>
  19139. </thead>
  19140. <tbody>
  19141. {{project_risks_classes}}
  19142. </tbody>
  19143. </table>
  19144. </div>
  19145. </div>
  19146. </div>
  19147. <div class="row">
  19148. <div class="col-md-12">
  19149. <h2>Methods</h2>
  19150. </div>
  19151. </div>
  19152. <div class="row">
  19153. <div class="col-md-6">
  19154. <h3>Coverage Distribution</h3>
  19155. <div id="methodCoverageDistribution" style="height: 300px;">
  19156. <svg></svg>
  19157. </div>
  19158. </div>
  19159. <div class="col-md-6">
  19160. <h3>Complexity</h3>
  19161. <div id="methodComplexity" style="height: 300px;">
  19162. <svg></svg>
  19163. </div>
  19164. </div>
  19165. </div>
  19166. <div class="row">
  19167. <div class="col-md-6">
  19168. <h3>Insufficient Coverage</h3>
  19169. <div class="scrollbox">
  19170. <table class="table">
  19171. <thead>
  19172. <tr>
  19173. <th>Method</th>
  19174. <th class="text-right">Coverage</th>
  19175. </tr>
  19176. </thead>
  19177. <tbody>
  19178. {{insufficient_coverage_methods}}
  19179. </tbody>
  19180. </table>
  19181. </div>
  19182. </div>
  19183. <div class="col-md-6">
  19184. <h3>Project Risks</h3>
  19185. <div class="scrollbox">
  19186. <table class="table">
  19187. <thead>
  19188. <tr>
  19189. <th>Method</th>
  19190. <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
  19191. </tr>
  19192. </thead>
  19193. <tbody>
  19194. {{project_risks_methods}}
  19195. </tbody>
  19196. </table>
  19197. </div>
  19198. </div>
  19199. </div>
  19200. <footer>
  19201. <hr/>
  19202. <p>
  19203. <small>Generated by <a href="http://github.com/sebastianbergmann/php-code-coverage" target="_top">PHP_CodeCoverage {{version}}</a> using <a href="{{runtime_link}}" target="_top">{{runtime_name}} {{runtime_version}}</a>{{generator}} at {{date}}.</small>
  19204. </p>
  19205. </footer>
  19206. </div>
  19207. <script src="{{path_to_root}}js/jquery.min.js" type="text/javascript"></script>
  19208. <script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
  19209. <script src="{{path_to_root}}js/holder.min.js" type="text/javascript"></script>
  19210. <script src="{{path_to_root}}js/d3.min.js" type="text/javascript"></script>
  19211. <script src="{{path_to_root}}js/nv.d3.min.js" type="text/javascript"></script>
  19212. <script type="text/javascript">
  19213. $(document).ready(function() {
  19214. nv.addGraph(function() {
  19215. var chart = nv.models.multiBarChart();
  19216. chart.tooltips(false)
  19217. .showControls(false)
  19218. .showLegend(false)
  19219. .reduceXTicks(false)
  19220. .staggerLabels(true)
  19221. .yAxis.tickFormat(d3.format('d'));
  19222. d3.select('#classCoverageDistribution svg')
  19223. .datum(getCoverageDistributionData({{class_coverage_distribution}}, "Class Coverage"))
  19224. .transition().duration(500).call(chart);
  19225. nv.utils.windowResize(chart.update);
  19226. return chart;
  19227. });
  19228. nv.addGraph(function() {
  19229. var chart = nv.models.multiBarChart();
  19230. chart.tooltips(false)
  19231. .showControls(false)
  19232. .showLegend(false)
  19233. .reduceXTicks(false)
  19234. .staggerLabels(true)
  19235. .yAxis.tickFormat(d3.format('d'));
  19236. d3.select('#methodCoverageDistribution svg')
  19237. .datum(getCoverageDistributionData({{method_coverage_distribution}}, "Method Coverage"))
  19238. .transition().duration(500).call(chart);
  19239. nv.utils.windowResize(chart.update);
  19240. return chart;
  19241. });
  19242. function getCoverageDistributionData(data, label) {
  19243. var labels = [
  19244. '0%',
  19245. '0-10%',
  19246. '10-20%',
  19247. '20-30%',
  19248. '30-40%',
  19249. '40-50%',
  19250. '50-60%',
  19251. '60-70%',
  19252. '70-80%',
  19253. '80-90%',
  19254. '90-100%',
  19255. '100%'
  19256. ];
  19257. var values = [];
  19258. $.each(labels, function(key) {
  19259. values.push({x: labels[key], y: data[key]});
  19260. });
  19261. return [
  19262. {
  19263. key: label,
  19264. values: values,
  19265. color: "#4572A7"
  19266. }
  19267. ];
  19268. }
  19269. nv.addGraph(function() {
  19270. var chart = nv.models.scatterChart()
  19271. .showDistX(true)
  19272. .showDistY(true)
  19273. .showLegend(false)
  19274. .forceX([0, 100]);
  19275. chart.scatter.onlyCircles(false);
  19276. chart.tooltipContent(function(key, y, e, graph) {
  19277. return '<p>' + graph.point.class + '</p>';
  19278. });
  19279. chart.xAxis.axisLabel('Code Coverage (in percent)');
  19280. chart.yAxis.axisLabel('Cyclomatic Complexity');
  19281. d3.select('#classComplexity svg')
  19282. .datum(getComplexityData({{complexity_class}}, 'Class Complexity'))
  19283. .transition()
  19284. .duration(500)
  19285. .call(chart);
  19286. nv.utils.windowResize(chart.update);
  19287. return chart;
  19288. });
  19289. nv.addGraph(function() {
  19290. var chart = nv.models.scatterChart()
  19291. .showDistX(true)
  19292. .showDistY(true)
  19293. .showLegend(false)
  19294. .forceX([0, 100]);
  19295. chart.scatter.onlyCircles(false);
  19296. chart.tooltipContent(function(key, y, e, graph) {
  19297. return '<p>' + graph.point.class + '</p>';
  19298. });
  19299. chart.xAxis.axisLabel('Code Coverage (in percent)');
  19300. chart.yAxis.axisLabel('Method Complexity');
  19301. d3.select('#methodComplexity svg')
  19302. .datum(getComplexityData({{complexity_method}}, 'Method Complexity'))
  19303. .transition()
  19304. .duration(500)
  19305. .call(chart);
  19306. nv.utils.windowResize(chart.update);
  19307. return chart;
  19308. });
  19309. function getComplexityData(data, label) {
  19310. var values = [];
  19311. $.each(data, function(key) {
  19312. var value = Math.round(data[key][0]*100) / 100;
  19313. values.push({
  19314. x: value,
  19315. y: data[key][1],
  19316. class: data[key][2],
  19317. size: 0.05,
  19318. shape: 'diamond'
  19319. });
  19320. });
  19321. return [
  19322. {
  19323. key: label,
  19324. values: values,
  19325. color: "#4572A7"
  19326. }
  19327. ];
  19328. }
  19329. });
  19330. </script>
  19331. </body>
  19332. </html>
  19333. <!DOCTYPE html>
  19334. <html lang="en">
  19335. <head>
  19336. <meta charset="UTF-8">
  19337. <title>Code Coverage for {{full_path}}</title>
  19338. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  19339. <link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
  19340. <link href="{{path_to_root}}css/style.css" rel="stylesheet">
  19341. <!--[if lt IE 9]>
  19342. <script src="{{path_to_root}}js/html5shiv.min.js"></script>
  19343. <script src="{{path_to_root}}js/respond.min.js"></script>
  19344. <![endif]-->
  19345. </head>
  19346. <body>
  19347. <header>
  19348. <div class="container">
  19349. <div class="row">
  19350. <div class="col-md-12">
  19351. <ol class="breadcrumb">
  19352. {{breadcrumbs}}
  19353. </ol>
  19354. </div>
  19355. </div>
  19356. </div>
  19357. </header>
  19358. <div class="container">
  19359. <table class="table table-bordered">
  19360. <thead>
  19361. <tr>
  19362. <td>&nbsp;</td>
  19363. <td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
  19364. </tr>
  19365. <tr>
  19366. <td>&nbsp;</td>
  19367. <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
  19368. <td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
  19369. <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
  19370. </tr>
  19371. </thead>
  19372. <tbody>
  19373. {{items}}
  19374. </tbody>
  19375. </table>
  19376. <footer>
  19377. <hr/>
  19378. <h4>Legend</h4>
  19379. <p>
  19380. <span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
  19381. <span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
  19382. <span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
  19383. </p>
  19384. <p>
  19385. <small>Generated by <a href="http://github.com/sebastianbergmann/php-code-coverage" target="_top">PHP_CodeCoverage {{version}}</a> using <a href="{{runtime_link}}" target="_top">{{runtime_name}} {{runtime_version}}</a>{{generator}} at {{date}}.</small>
  19386. </p>
  19387. </footer>
  19388. </div>
  19389. <script src="{{path_to_root}}js/jquery.min.js" type="text/javascript"></script>
  19390. <script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
  19391. <script src="{{path_to_root}}js/holder.min.js" type="text/javascript"></script>
  19392. </body>
  19393. </html>
  19394. <div class="progress">
  19395. <div class="progress-bar progress-bar-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
  19396. <span class="sr-only">{{percent}}% covered ({{level}})</span>
  19397. </div>
  19398. </div>
  19399. /*!
  19400. * Bootstrap v3.3.4 (http://getbootstrap.com)
  19401. * Copyright 2011-2015 Twitter, Inc.
  19402. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  19403. */
  19404. if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.4",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.4",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.4",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.4",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport),this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(n).addClass(h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.4",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.4",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){
  19405. var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.4",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a(document.body).height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new l;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function S(){ta.event.preventDefault()}function k(){for(var n,t=ta.event;n=t.sourceEvent;)t=n;return t}function E(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=ta.event;u.target=n,ta.event=u,t[u.type].apply(e,r)}finally{ta.event=i}}},t}function A(n){return ya(n,_a),n}function N(n){return"function"==typeof n?n:function(){return Ma(n,this)}}function C(n){return"function"==typeof n?n:function(){return xa(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ta.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function q(n){return n.trim().replace(/\s+/g," ")}function L(n){return new RegExp("(?:^|\\s+)"+ta.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=T(n).map(D);var u=n.length;return"function"==typeof t?r:e}function D(n){var t=L(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",q(u+" "+n))):e.setAttribute("class",q(u.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e?t.createElementNS(e,n):t.createElement(n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ta.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return ba(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,ra(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+ta.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=$;a>0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n.toLowerCase()))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Qa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ga(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=sc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=N[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&cc!==jt,o=new(i?jt:cc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&dc.hasOwnProperty(n.type)&&dc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=Da,t=t*Da/2+qa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])<Ca&&ga(n[1]-t[1])<Ca}function _e(n,t){n*=Da;var e=Math.cos(t*=Da);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++xc,_c+=(n-_c)/xc,wc+=(t-wc)/xc,Sc+=(e-Sc)/xc}function Se(){function n(n,u){n*=Da;var i=Math.cos(u*=Da),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);bc+=l,kc+=l*(t+(t=o)),Ec+=l*(e+(e=a)),Ac+=l*(r+(r=c)),we(t,e,r)}var t,e,r;qc.point=function(u,i){u*=Da;var o=Math.cos(i*=Da);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),qc.point=n,we(t,e,r)}}function ke(){qc.point=_e}function Ee(){function n(n,t){n*=Da;var e=Math.cos(t*=Da),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-nt(g)/h,v=Math.atan2(h,g);Nc+=p*l,Cc+=p*s,zc+=p*f,bc+=v,kc+=v*(r+(r=o)),Ec+=v*(u+(u=a)),Ac+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;qc.point=function(o,a){t=o,e=a,qc.point=n,o*=Da;var c=Math.cos(a*=Da);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},qc.lineEnd=function(){n(t,e),qc.lineEnd=ke,qc.point=_e}}function Ae(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ne(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(be(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function qe(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);x.point(e[0],e[1])}function f(){x.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)<Ca?(n.point(e,r=(r+o)/2>0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)<Ca&&(e-=u*Ca),ga(i-a)<Ca&&(i-=a*Ca),r=Ue(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Ue(n,t,e,r){var u,i,o=Math.sin(n-e);return ga(o)>Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]<t[0]?qa:-qa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Fe(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;yc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)<Ca,C=N||Ca>A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)<Ca?k:E):k<=b[1]&&b[1]<=E:A>qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)<Ca?u>0?0:3:ga(r[0]-e)<Ca?u>0?2:1:ga(r[1]-t)<Ca?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c
  19406. },polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)<Ca||ga(r-h)<Ca?(r+h)/2:Math.atan2(_,b),A=n(E,k),N=A[0],C=A[1],z=N-t,q=C-e,L=M*z-y*q;(L*L/x>i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)<Ca?ar:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-K(u)*Math.sqrt(n*n+e*e)]},e)}function Sr(n,t){return[n,Math.log(Math.tan(qa/4+t/2))]}function kr(n){var t,e=ur(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=qa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Er(n,t){return[Math.log(Math.tan(qa/4+t/2)),-n]}function Ar(n){return n[0]}function Nr(n){return n[1]}function Cr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)<Ca&&ga(r-c.circle.cy)<Ca;)i=c.P,a.unshift(c),Pr(c),c=i;a.unshift(c),Xr(c);for(var l=o;l.circle&&ga(e-l.circle.x)<Ca&&ga(r-l.circle.cy)<Ca;)o=l.N,a.push(l),Pr(l),l=o;a.push(l),Xr(l);var s,f=a.length;for(s=1;f>s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)<Ca&&p-u>Ca?{x:f,y:ga(t-f)<Ca?e:p}:ga(u-p)<Ca&&h-r>Ca?{x:ga(e-p)<Ca?t:h,y:p}:ga(r-h)<Ca&&u-g>Ca?{x:h,y:ga(t-h)<Ca?e:g}:ga(u-g)<Ca&&r-f>Ca?{x:ga(e-g)<Ca?t:f,y:g}:null),i.site,null)),++c)}function Yr(n,t){return t.angle-n.angle}function Zr(){tu(this),this.x=this.y=this.arc=this.site=this.cy=null}function Vr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,l=r.y-a,s=i.x-o,f=i.y-a,h=2*(c*f-l*s);if(!(h>=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.y<M.y||m.y===M.y&&m.x<=M.x){if(!M.L){y=M.P;break}M=M.L}else{if(!M.R){y=M;break}M=M.R}tl.insert(y,m),y||(nl=m)}}}}function Xr(n){var t=n.circle;t&&(t.P||(nl=t.N),tl.remove(t),rl.push(t),tu(t),n.circle=null)}function $r(n){for(var t,e=Gc,r=Oe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Br(t,n)||!r(t)||ga(t.a.x-t.b.x)<Ca&&ga(t.a.y-t.b.y)<Ca)&&(t.a=t.b=null,e.splice(u,1))}function Br(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],l=t[1][1],s=n.l,f=n.r,h=s.x,g=s.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.y<c)return}else i={x:d,y:l};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.y<c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Wr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Jr(n,t,e,r){var u=new Wr(n,t);return Gc.push(u),e&&Kr(u,n,t,e),r&&Kr(u,t,n,r),Kc[n.i].edges.push(new Qr(u,n,t)),Kc[t.i].edges.push(new Qr(u,t,n)),u}function Gr(n,t,e){var r=new Wr(n,null);return r.a=t,r.b=e,Gc.push(r),r}function Kr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Qr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function nu(){this._=null}function tu(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function eu(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ru(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function uu(n){for(;n.L;)n=n.L;return n}function iu(n,t){var e,r,u,i=n.sort(ou).pop();for(Gc=[],Kc=new Array(n.length),Qc=new nu,tl=new nu;;)if(u=nl,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Kc[i.i]=new Or(i),jr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;Ur(u.arc)}t&&($r(t),Ir(t));var o={cells:Kc,edges:Gc};return Qc=tl=Gc=Kc=null,o}function ou(n,t){return t.y-n.y||t.x-n.x}function au(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function cu(n){return n.x}function lu(n){return n.y}function su(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function fu(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&fu(n,c[0],e,r,o,a),c[1]&&fu(n,c[1],o,r,u,a),c[2]&&fu(n,c[2],e,a,o,i),c[3]&&fu(n,c[3],o,a,u,i)}}function hu(n,t,e,r,u,i,o){var a,c=1/0;return function l(n,s,f,h,g){if(!(s>i||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return i<t.length&&(u=t.slice(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Pa,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Pa:0}function Uu(n,t){return n[0]*t[0]+n[1]*t[1]}function ju(n){var t=Math.sqrt(Uu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Fu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Hu(n,t){var e,r=[],u=[],i=ta.transform(n),o=ta.transform(t),a=i.translate,c=o.translate,l=i.rotate,s=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:vu(a[0],c[0])},{i:3,x:vu(a[1],c[1])})):r.push(c[0]||c[1]?"translate("+c+")":""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Ou(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Iu(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Yu(n){for(var t=n.source,e=n.target,r=Vu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Zu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Vu(n,t){if(n===t)return n;for(var e=Zu(n),r=Zu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Xu(n){n.fixed|=2}function $u(n){n.fixed&=-7}function Bu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Wu(n){n.fixed&=-5}function Ju(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Ju(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,u+=l*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Gu(n,t){return ta.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=ri,n}function Ku(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function ni(n){return n.children}function ti(n){return n.value}function ei(n,t){return t.value-n.value}function ri(n){return ta.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function ui(n){return n.x}function ii(n){return n.y}function oi(n,t,e){n.y0=t,n.y=e}function ai(n){return ta.range(n.length)}function ci(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function li(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?mi(r,u=a):mi(r=c,u),o--):(di(r,i),u=i,t(i))}var m=(s+f)/2,y=(h+g)/2,M=0;for(o=0;l>o;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)_i(u[i],t,e,r)}function wi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),l=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+l*i,e.y=n.y+c*i-l*u}else e.x=n.x+r,e.y=n.y}function Si(n,t){return n.parent==t.parent?1:2}function ki(n){var t=n.children;return t.length?t[0]:n.t}function Ei(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ai(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Ni(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=ta.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ii(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++<s;)for(var h=f-1;h>0;h--)o.push(i(l)*h);for(l=0;o[l]<a;l++);for(s=o.length;o[s-1]>c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++o<a;)u.has(i=r[o])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,o=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=(c+l)/2,0):(l-c)/(n.length-1+a);return i=r(c+s*a/2,s),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=l=Math.round((c+l)/2),0):(l-c)/(n.length-1+a)|0;return i=r(c+Math.round(s*a/2+(l-c-(n.length-1+a)*s)/2),s),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=(f-s)/(n.length-a+2*c);return i=r(s+h*c,h),l&&i.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=Math.floor((f-s)/(n.length-a+2*c));return i=r(s+Math.round((f-s-(n.length-a)*h)/2),h),l&&i.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Pi(t.a[0])},e.copy=function(){return Qi(n,t)},e.domain(n)}function no(n,t){function i(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ta.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ta.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(u).sort(e),i()):n},o.range=function(n){return arguments.length?(t=n,i()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return no(n,t)},i()}function to(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f<h;)u.call(this,c=t[f],f)?s.push([+g.call(this,c,f),+p.call(this,c,f)]):s.length&&(o(),s=[]);return s.length&&o(),l.length?l.join(""):null}var e=Ar,r=Nr,u=Ne,i=go,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=El.get(n)||go).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function go(n){return n.join("L")}function po(n){return go(n)+"Z"}function vo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function yo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function Mo(n,t){return n.length<4?go(n):n[1]+_o(n.slice(1,-1),wo(n,t))}function xo(n,t){return n.length<3?go(n):n[0]+_o((n.push(n[0]),n),wo([n[n.length-2]].concat(n,[n[1]]),t))}function bo(n,t){return n.length<3?go(n):n[0]+_o(n,wo(n,t))}function _o(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return go(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l<t.length;l++,c++)i=n[c],a=t[l],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var s=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+s[0]+","+s[1]}return r}function wo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function So(n){if(n.length<3)return go(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",No(Cl,o),",",No(Cl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Co(c,o,a);return n.pop(),c.push("L",r),c.join("")}function ko(n){if(n.length<4)return go(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(No(Cl,i)+","+No(Cl,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Co(e,i,o);return e.join("")}function Eo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[No(Cl,o),",",No(Cl,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Co(t,o,a);return t.join("")}function Ao(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,l=-1;++l<=e;)r=n[l],u=l/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return So(n)}function No(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Co(n,t,e){n.push("C",No(Al,t),",",No(Al,e),",",No(Nl,t),",",No(Nl,e),",",No(Cl,t),",",No(Cl,e))}function zo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function qo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=zo(u,i);++t<e;)r[t]=(o+(o=zo(u=i,i=n[t+1])))/2;return r[t]=o,r}function Lo(n){for(var t,e,r,u,i=[],o=qo(n),a=-1,c=n.length-1;++a<c;)t=zo(n[a],n[a+1]),ga(t)<Ca?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]-Ra,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Do(n){function t(t){function c(){v.push("M",a(n(m),f),s,l(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,M=t.length,x=Et(e),b=Et(u),_=e===r?function(){return g}:Et(r),w=u===i?function(){return p}:Et(i);++y<M;)o.call(this,h=t[y],y)?(d.push([g=+x.call(this,h,y),p=+b.call(this,h,y)]),m.push([+_.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ar,r=Ar,u=0,i=Nr,o=Ne,a=go,c=a.key,l=a,s="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r
  19407. },t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=El.get(n)||go).key,l=a.reverse||a,s=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Po(n){return n.radius}function Uo(n){return[n.x,n.y]}function jo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Ra;return[e*Math.cos(r),e*Math.sin(r)]}}function Fo(){return 64}function Ho(){return"circle"}function Oo(n){var t=Math.sqrt(n/qa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Io(n){return function(){var t,e;(t=this[n])&&(e=t[t.active])&&(--t.count?delete t[t.active]:delete this[n],t.active+=.5,e.event&&e.event.interrupt.call(this,this.__data__,e.index))}}function Yo(n,t,e){return ya(n,Pl),n.namespace=t,n.id=e,n}function Zo(n,t,e,r){var u=n.id,i=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[i][u].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[i][u].tween.set(t,e)}))}function Vo(n){return null==n&&(n=""),function(){this.textContent=n}}function Xo(n){return null==n?"__transition__":"__transition_"+n+"__"}function $o(n,t,e,r,u){var i=n[e]||(n[e]={active:0,count:0}),o=i[r];if(!o){var a=u.time;o=i[r]={tween:new l,time:a,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++i.count,ta.timer(function(u){function c(e){if(i.active>r)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]<Vl[i]/u?i-1:i]:[Bl,Vi(n,e)[2]]}return r.invert=function(t){return Ko(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Ko)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Ko(+e+1),t).length}var i=r.domain(),o=Pi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Fi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.5"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o;)if(null!=(r=n[i])&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o<i;)u(e=+n[o])&&(r+=e);else for(;++o<i;)u(e=+t.call(n,n[o],o))&&(r+=e);return r},ta.mean=function(n,t){var e,i=0,o=n.length,a=-1,c=o;if(1===arguments.length)for(;++a<o;)u(e=r(n[a]))?i+=e:--c;else for(;++a<o;)u(e=r(t.call(n,n[a],a)))?i+=e:--c;return c?i/c:void 0},ta.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},ta.median=function(n,t){var i,o=[],a=n.length,c=-1;if(1===arguments.length)for(;++c<a;)u(i=r(n[c]))&&o.push(i);else for(;++c<a;)u(i=r(t.call(n,n[c],c)))&&o.push(i);return o.length?ta.quantile(o.sort(e),.5):void 0},ta.variance=function(n,t){var e,i,o=n.length,a=0,c=0,l=-1,s=0;if(1===arguments.length)for(;++l<o;)u(e=r(n[l]))&&(i=e-a,a+=i/++s,c+=i*(e-a));else for(;++l<o;)u(e=r(t.call(n,n[l],l)))&&(i=e-a,a+=i/++s,c+=i*(e-a));return s>1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n<t;)for(var r,u=-1,i=e[n]=new Array(r);++u<r;)i[u]=arguments[u][n];return e},ta.transpose=function(n){return ta.zip.apply(ta,n)},ta.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ta.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ta.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ta.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)<t;)u.push(r/i);return u},ta.map=function(n,t){var e=new l;if(n instanceof l)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,u=-1,i=n.length;if(1===arguments.length)for(;++u<i;)e.set(u,n[u]);else for(;++u<i;)e.set(t.call(n,r=n[u],u),r)}else for(var o in n)e.set(o,n[o]);return e};var pa="__proto__",va="\x00";c(l,{has:h,get:function(n){return this._[s(n)]},set:function(n,t){return this._[s(n)]=t},remove:g,keys:p,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:f(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t),this._[t])}}),ta.nest=function(){function n(t,o,a){if(a>=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g<p;)(h=d.get(c=v(s=o[g])))?h.push(s):d.set(c,[s]);return t?(s=t(),f=function(e,r){s.set(e,n(t,r,a))}):(s={},f=function(e,r){s[e]=n(t,r,a)}),d.forEach(f),s}function t(n,e){if(e>=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=M(n,t,t[e]);return n};var da=["webkit","ms","moz","Moz","o","O"];ta.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,l=r.length;++c<l;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return A(i)},_a.selectAll=function(n){var t,e,r=[];n=C(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=ra(n.call(e,e.__data__,a,u))),t.parentNode=e);return A(r)};var wa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ta.ns={prefix:wa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!L(n[u]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},_a.style=function(n,e,r){var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++r<o;)m.has(d=t.call(u=n[r],u.__data__,r))?v[r]=u:m.set(d,u),y[r]=d;for(r=-1;++r<f;)(u=m.get(d=t.call(e,i=e[r],r)))?u!==!0&&(g[r]=u,u.__data__=i):p[r]=H(i),m.set(d,!0);for(r=-1;++r<o;)m.get(y[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=H(i);for(;f>r;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++i<o;)(u=r[i])&&(n[i]=u.__data__);return n}var a=Z([]),c=A([]),s=A([]);if("function"==typeof n)for(;++i<o;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<o;)e(r=this[i],n);return c.enter=function(){return a},c.exit=function(){return s},c},_a.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},_a.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},_a.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},_a.call=function(n){var t=ra(arguments);return n.apply(t[0]=this,t),this},_a.empty=function(){return!this.node()},_a.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var l=-1,s=u.length;++l<s;)(i=u[l])?(t.push(r[l]=e=n.call(u.parentNode,i.__data__,l,a)),e.__data__=i.__data__):t.push(null)}return A(o)},Sa.insert=function(n,t){return arguments.length<2&&(t=V(this)),_a.insert.call(this,n,t)},ta.select=function(t){var e;return"string"==typeof t?(e=[Ma(t,ua)],e.parentNode=ua.documentElement):(e=[t],e.parentNode=n(t)),A([e])},ta.selectAll=function(n){var t;return"string"==typeof n?(t=ra(xa(n,ua)),t.parentNode=ua.documentElement):(t=n,t.parentNode=null),A([t])},_a.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||n({type:"zoomend"}),d=null}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(v=e(d=m||ta.mouse(this)),Dl.call(this),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++<l;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}s=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++s):10===r&&(u=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;l>s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t
  19408. },reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)se(e[r].geometry,t)}},dc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){fe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)fe(e[r],t,0)},Polygon:function(n,t){he(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)he(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)se(e[r],t)}};ta.geo.area=function(n){return mc=0,ta.geo.stream(n,Mc),mc};var mc,yc=new ce,Mc={sphere:function(){mc+=4*qa},point:b,lineStart:b,lineEnd:b,polygonStart:function(){yc.reset(),Mc.lineStart=ge},polygonEnd:function(){var n=2*yc;mc+=0>n?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var s,f,h,g,p,v,d,m,y,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=u,b.lineStart=i,b.lineEnd=o,y=0,Mc.polygonStart()},polygonEnd:function(){Mc.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>yc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t<s.length-h;++t)g.push(n[a[s[t]][2]]);return g}var e=Ar,r=Nr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ta.geom.polygon=function(n){return ya(n,Jc),n};var Jc=ta.geom.polygon.prototype=[];Jc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Jc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Jc.clip=function(n){for(var t,e,r,u,i,o,a=Tr(n),c=-1,l=this.length-Tr(this),s=this[l-1];++c<l;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],qr(o,s,u)?(qr(i,s,u)||n.push(Lr(i,o,s,u)),n.push(o)):qr(i,s,u)&&n.push(Lr(i,o,s,u)),i=o;a&&n.push(n[0]),s=u}return n};var Gc,Kc,Qc,nl,tl,el=[],rl=[];Or.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Yr),t.length},Qr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},nu.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=uu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(eu(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ru(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(ru(this,e),n=e,e=n.U),e.C=!1,r.C=!0,eu(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?uu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,eu(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ru(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,eu(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,ru(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,eu(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,ru(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},ta.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return iu(e(n),a).cells.forEach(function(e,a){var c=e.edges,l=e.site,s=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):l.x>=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c<l;)u=s,i=f,s=a[c].edge,f=s.l===o?s.r:s.l,r<i.i&&r<f.i&&au(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=Et(r=n),t):r},t.y=function(n){return arguments.length?(o=Et(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?ul:n,t):a===ul?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===ul?null:a&&a[1]},t)};var ul=[[-1e6,-1e6],[1e6,1e6]];ta.geom.delaunay=function(n){return ta.geom.voronoi().triangles(n)},ta.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,s=n.y;if(null!=c)if(ga(c-e)+ga(s-r)<.01)l(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,l(n,f,c,s,u,i,o,a),l(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,u,i,o,a)}function l(n,t,e,r,u,o,a,c){var l=.5*(u+a),s=.5*(o+c),f=e>=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.x<v&&(v=s.x),s.y<d&&(d=s.y),s.x>m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=s=null,k}var o,a=Ar,c=Nr;return(o=arguments.length)?(a=cu,c=lu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},ta.interpolateRgb=gu,ta.interpolateObject=pu,ta.interpolateNumber=vu,ta.interpolateString=du;var il=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,ol=new RegExp(il.source,"g");ta.interpolate=mu,ta.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ga.has(t)||/^(#|rgb\(|hsl\()/.test(t)?gu:du:t instanceof ot?gu:Array.isArray(t)?yu:"object"===e&&isNaN(t)?pu:vu)(n,t)}],ta.interpolateArray=yu;var al=function(){return y},cl=ta.map({linear:al,poly:ku,quad:function(){return _u},cubic:function(){return wu},sin:function(){return Eu},exp:function(){return Au},circle:function(){return Nu},elastic:Cu,back:zu,bounce:function(){return qu}}),ll=ta.map({"in":y,out:xu,"in-out":bu,"out-in":function(n){return bu(xu(n))}});ta.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Yu(n[e]));return t}},ta.layout.chord=function(){function n(){var n,l,f,h,g,p={},v=[],d=ta.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(l=0,g=-1;++g<i;)l+=u[h][g];v.push(l),m.push(ta.range(i)),n+=l}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(La-s*i)/n,l=0,h=-1;++h<i;){for(f=l,g=-1;++g<i;){var y=d[h],M=m[y][g],x=u[y][M],b=l,_=l+=x*n;p[y+"-"+M]={index:y,subindex:M,startAngle:b,endAngle:_,value:x}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/n},l+=s}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,l={},s=0;return l.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,l):u},l.padding=function(n){return arguments.length?(s=n,e=r=null,l):s},l.sortGroups=function(n){return arguments.length?(o=n,e=r=null,l):o},l.sortSubgroups=function(n){return arguments.length?(a=n,e=null,l):a},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},ta.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e<b;)a=m[e],a.x+=(y-a.x)*d,a.y+=(x-a.y)*d;if(g)for(Ju(t=ta.geom.quadtree(m),r,o),e=-1;++e<b;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<b;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(M=n,a):M},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++a<l;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,s=M.length,p=l[0],v=l[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++l<o;)n(a=i[l],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=ta.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Gu(e,r)},ta.layout.pie=function(){function n(o){var a,c=o.length,l=o.map(function(e,r){return+t.call(n,e,r)}),s=+("function"==typeof r?r.apply(this,arguments):r),f=("function"==typeof u?u.apply(this,arguments):u)-s,h=Math.min(Math.abs(f)/c,+("function"==typeof i?i.apply(this,arguments):i)),g=h*(0>f?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=l[i],a>=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++i<o;)u=n[i],u.x=a,u.y=l,u.dy=s,a+=u.dx=Math.min(e.x+e.dx-a,s?c(u.area/s):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);++i<o;)u=n[i],u.x=a,u.y=l,u.dx=s,l+=u.dy=Math.min(e.y+e.dy-l,s?c(u.area/s):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=ta.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=Ri,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));
  19409. return i.size=function(n){return arguments.length?(l=n,i):l},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ri(t):Di(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Di(t,n)}if(!arguments.length)return s;var r;return f=null==(s=n)?Ri:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Gu(i,a)},ta.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++a<c;){i.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(e=l[s])&&$o(e,s,u,r,o),t.push(e)}return Yo(i,u,r)},_a.interrupt=function(n){return this.each(null==n?Dl:Io(Xo(n)))};var Tl,Rl,Dl=Io(Xo()),Pl=[],Ul=0;Pl.call=_a.call,Pl.empty=_a.empty,Pl.node=_a.node,Pl.size=_a.size,ta.transition=function(n,t){return n&&n.transition?Tl?n.transition(t):n:ta.selection().transition(n)},ta.transition.prototype=Pl,Pl.select=function(n){var t,e,r,u=this.id,i=this.namespace,o=[];n=N(n);for(var a=-1,c=this.length;++a<c;){o.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(r=l[s])&&(e=n.call(r,r.__data__,s,a))?("__data__"in r&&(e.__data__=r.__data__),$o(e,s,i,u,r[i][u]),t.push(e)):t.push(null)}return Yo(o,i,u)},Pl.selectAll=function(n){var t,e,r,u,i,o=this.id,a=this.namespace,c=[];n=C(n);for(var l=-1,s=this.length;++l<s;)for(var f=this[l],h=-1,g=f.length;++h<g;)if(r=f[h]){i=r[a][o],e=n.call(r,r.__data__,h,l),c.push(t=[]);for(var p=-1,v=e.length;++p<v;)(u=e[p])&&$o(u,p,a,o,i),t.push(u)}return Yo(c,a,o)},Pl.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]<M[0])],q[1]=h[+(n[1]<M[1])]):M=null),A&&m(n,l,0)&&(r(k),t=!0),N&&m(n,s,1)&&(u(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,i=Ui(t),c=i[0],l=i[1],s=q[e],v=e?h:f,d=v[1]-v[0];return C&&(c-=s,l-=d+s),r=(e?p:g)?Math.max(c,Math.min(l,n[e])):n[e],C?u=(r+=s)+d:(M&&(s=Math.max(c,Math.min(l,2*M[e]-r))),r>s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}();/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
  19410. * Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
  19411. * */
  19412. !function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);/**
  19413. * @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
  19414. */
  19415. !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document);/*!
  19416. Holder - client side image placeholders
  19417. Version 2.7.1+6hydf
  19418. © 2015 Ivan Malopinsky - http://imsky.co
  19419. Site: http://holderjs.com
  19420. Issues: https://github.com/imsky/holder/issues
  19421. License: http://opensource.org/licenses/MIT
  19422. */
  19423. !function(a){if(a.document){var b=a.document;b.querySelectorAll||(b.querySelectorAll=function(c){var d,e=b.createElement("style"),f=[];for(b.documentElement.firstChild.appendChild(e),b._qsa=[],e.styleSheet.cssText=c+"{x-qsa:expression(document._qsa && document._qsa.push(this))}",a.scrollBy(0,0),e.parentNode.removeChild(e);b._qsa.length;)d=b._qsa.shift(),d.style.removeAttribute("x-qsa"),f.push(d);return b._qsa=null,f}),b.querySelector||(b.querySelector=function(a){var c=b.querySelectorAll(a);return c.length?c[0]:null}),b.getElementsByClassName||(b.getElementsByClassName=function(a){return a=String(a).replace(/^|\s+/g,"."),b.querySelectorAll(a)}),Object.keys||(Object.keys=function(a){if(a!==Object(a))throw TypeError("Object.keys called on non-object");var b,c=[];for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&c.push(b);return c}),function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";a.atob=a.atob||function(a){a=String(a);var c,d=0,e=[],f=0,g=0;if(a=a.replace(/\s/g,""),a.length%4===0&&(a=a.replace(/=+$/,"")),a.length%4===1)throw Error("InvalidCharacterError");if(/[^+/0-9A-Za-z]/.test(a))throw Error("InvalidCharacterError");for(;d<a.length;)c=b.indexOf(a.charAt(d)),f=f<<6|c,g+=6,24===g&&(e.push(String.fromCharCode(f>>16&255)),e.push(String.fromCharCode(f>>8&255)),e.push(String.fromCharCode(255&f)),g=0,f=0),d+=1;return 12===g?(f>>=4,e.push(String.fromCharCode(255&f))):18===g&&(f>>=2,e.push(String.fromCharCode(f>>8&255)),e.push(String.fromCharCode(255&f))),e.join("")},a.btoa=a.btoa||function(a){a=String(a);var c,d,e,f,g,h,i,j=0,k=[];if(/[^\x00-\xFF]/.test(a))throw Error("InvalidCharacterError");for(;j<a.length;)c=a.charCodeAt(j++),d=a.charCodeAt(j++),e=a.charCodeAt(j++),f=c>>2,g=(3&c)<<4|d>>4,h=(15&d)<<2|e>>6,i=63&e,j===a.length+2?(h=64,i=64):j===a.length+1&&(i=64),k.push(b.charAt(f),b.charAt(g),b.charAt(h),b.charAt(i));return k.join("")}}(a),Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(a){var b=this.__proto__||this.constructor.prototype;return a in this&&(!(a in b)||b[a]!==this[a])}),function(){if("performance"in a==!1&&(a.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in a.performance==!1){var b=Date.now();performance.timing&&performance.timing.navigationStart&&(b=performance.timing.navigationStart),a.performance.now=function(){return Date.now()-b}}}(),a.requestAnimationFrame||(a.webkitRequestAnimationFrame?!function(a){a.requestAnimationFrame=function(b){return webkitRequestAnimationFrame(function(){b(a.performance.now())})},a.cancelAnimationFrame=webkitCancelAnimationFrame}(a):a.mozRequestAnimationFrame?!function(a){a.requestAnimationFrame=function(b){return mozRequestAnimationFrame(function(){b(a.performance.now())})},a.cancelAnimationFrame=mozCancelAnimationFrame}(a):!function(a){a.requestAnimationFrame=function(b){return a.setTimeout(b,1e3/60)},a.cancelAnimationFrame=a.clearTimeout}(a))}}(this),function(a,b){"object"==typeof exports&&"object"==typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):"object"==typeof exports?exports.Holder=b():a.Holder=b()}(this,function(){return function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){(function(b){function d(a,b,c,d){var f=e(c.substr(c.lastIndexOf(a.domain)),a);f&&h({mode:null,el:d,flags:f,engineSettings:b})}function e(a,b){var c={theme:B(J.settings.themes.gray,null),stylesheets:b.stylesheets,instanceOptions:b};return a.match(/([\d]+p?)x([\d]+p?)(?:\?|$)/)?f(a,c):g(a,c)}function f(a,b){var c=a.split("?"),d=c[0].split("/");b.holderURL=a;var e=d[1],f=e.match(/([\d]+p?)x([\d]+p?)/);if(!f)return!1;if(b.fluid=-1!==e.indexOf("p"),b.dimensions={width:f[1].replace("p","%"),height:f[2].replace("p","%")},2===c.length){var g=A.parse(c[1]);if(g.bg&&(b.theme.background=(-1===g.bg.indexOf("#")?"#":"")+g.bg),g.fg&&(b.theme.foreground=(-1===g.fg.indexOf("#")?"#":"")+g.fg),g.theme&&b.instanceOptions.themes.hasOwnProperty(g.theme)&&(b.theme=B(b.instanceOptions.themes[g.theme],null)),g.text&&(b.text=g.text),g.textmode&&(b.textmode=g.textmode),g.size&&(b.size=g.size),g.font&&(b.font=g.font),g.align&&(b.align=g.align),b.nowrap=z.truthy(g.nowrap),b.auto=z.truthy(g.auto),z.truthy(g.random)){J.vars.cache.themeKeys=J.vars.cache.themeKeys||Object.keys(b.instanceOptions.themes);var h=J.vars.cache.themeKeys[0|Math.random()*J.vars.cache.themeKeys.length];b.theme=B(b.instanceOptions.themes[h],null)}}return b}function g(a,b){var c=!1,d=String.fromCharCode(11),e=a.replace(/([^\\])\//g,"$1"+d).split(d),f=/%[0-9a-f]{2}/gi,g=b.instanceOptions;b.holderURL=[];for(var h=e.length,i=0;h>i;i++){var j=e[i];if(j.match(f))try{j=decodeURIComponent(j)}catch(k){j=e[i]}var l=!1;if(J.flags.dimensions.match(j))c=!0,b.dimensions=J.flags.dimensions.output(j),l=!0;else if(J.flags.fluid.match(j))c=!0,b.dimensions=J.flags.fluid.output(j),b.fluid=!0,l=!0;else if(J.flags.textmode.match(j))b.textmode=J.flags.textmode.output(j),l=!0;else if(J.flags.colors.match(j)){var m=J.flags.colors.output(j);b.theme=B(b.theme,m),l=!0}else if(g.themes[j])g.themes.hasOwnProperty(j)&&(b.theme=B(g.themes[j],null)),l=!0;else if(J.flags.font.match(j))b.font=J.flags.font.output(j),l=!0;else if(J.flags.auto.match(j))b.auto=!0,l=!0;else if(J.flags.text.match(j))b.text=J.flags.text.output(j),l=!0;else if(J.flags.size.match(j))b.size=J.flags.size.output(j),l=!0;else if(J.flags.random.match(j)){null==J.vars.cache.themeKeys&&(J.vars.cache.themeKeys=Object.keys(g.themes));var n=J.vars.cache.themeKeys[0|Math.random()*J.vars.cache.themeKeys.length];b.theme=B(g.themes[n],null),l=!0}l&&b.holderURL.push(j)}return b.holderURL.unshift(g.domain),b.holderURL=b.holderURL.join("/"),c?b:!1}function h(a){var b=a.mode,c=a.el,d=a.flags,e=a.engineSettings,f=d.dimensions,g=d.theme,h=f.width+"x"+f.height;if(b=null==b?d.fluid?"fluid":"image":b,null!=d.text&&(g.text=d.text,"object"===c.nodeName.toLowerCase())){for(var j=g.text.split("\\n"),k=0;k<j.length;k++)j[k]=z.encodeHtmlEntity(j[k]);g.text=j.join("\\n")}var n=d.holderURL,o=B(e,null);if(d.font&&(g.font=d.font,!o.noFontFallback&&"img"===c.nodeName.toLowerCase()&&J.setup.supportsCanvas&&"svg"===o.renderer&&(o=B(o,{renderer:"canvas"}))),d.font&&"canvas"==o.renderer&&(o.reRender=!0),"background"==b)null==c.getAttribute("data-background-src")&&r(c,{"data-background-src":n});else{var p={};p[J.vars.dataAttr]=n,r(c,p)}d.theme=g,c.holderData={flags:d,engineSettings:o},("image"==b||"fluid"==b)&&r(c,{alt:g.text?g.text+" ["+h+"]":h});var q={mode:b,el:c,holderSettings:{dimensions:f,theme:g,flags:d},engineSettings:o};"image"==b?("html"!=o.renderer&&d.auto||(c.style.width=f.width+"px",c.style.height=f.height+"px"),"html"==o.renderer?c.style.backgroundColor=g.background:(i(q),"exact"==d.textmode&&(c.holderData.resizeUpdate=!0,J.vars.resizableImages.push(c),l(c)))):"background"==b&&"html"!=o.renderer?i(q):"fluid"==b&&(c.holderData.resizeUpdate=!0,"%"==f.height.slice(-1)?c.style.height=f.height:null!=d.auto&&d.auto||(c.style.height=f.height+"px"),"%"==f.width.slice(-1)?c.style.width=f.width:null!=d.auto&&d.auto||(c.style.width=f.width+"px"),("inline"==c.style.display||""===c.style.display||"none"==c.style.display)&&(c.style.display="block"),m(c),"html"==o.renderer?c.style.backgroundColor=g.background:(J.vars.resizableImages.push(c),l(c)))}function i(a){function c(){var b=null;switch(h.renderer){case"canvas":b=L(k,a);break;case"svg":b=M(k,a);break;default:throw"Holder: invalid renderer: "+h.renderer}return b}var d=null,e=a.mode,f=a.holderSettings,g=a.el,h=a.engineSettings;switch(h.renderer){case"svg":if(!J.setup.supportsSVG)return;break;case"canvas":if(!J.setup.supportsCanvas)return;break;default:return}var i={width:f.dimensions.width,height:f.dimensions.height,theme:f.theme,flags:f.flags},k=j(i);if(d=c(),null==d)throw"Holder: couldn't render placeholder";"background"==e?(g.style.backgroundImage="url("+d+")",g.style.backgroundSize=i.width+"px "+i.height+"px"):("img"===g.nodeName.toLowerCase()?r(g,{src:d}):"object"===g.nodeName.toLowerCase()&&(r(g,{data:d}),r(g,{type:"image/svg+xml"})),h.reRender&&b.setTimeout(function(){var a=c();if(null==a)throw"Holder: couldn't render placeholder";"img"===g.nodeName.toLowerCase()?r(g,{src:a}):"object"===g.nodeName.toLowerCase()&&(r(g,{data:a}),r(g,{type:"image/svg+xml"}))},100)),r(g,{"data-holder-rendered":!0})}function j(a){function b(a,b,c,d){b.width=c,b.height=d,a.width=Math.max(a.width,b.width),a.height+=b.height}var c=J.defaults.size;switch(parseFloat(a.theme.size)?c=a.theme.size:parseFloat(a.flags.size)&&(c=a.flags.size),a.font={family:a.theme.font?a.theme.font:"Arial, Helvetica, Open Sans, sans-serif",size:k(a.width,a.height,c),units:a.theme.units?a.theme.units:J.defaults.units,weight:a.theme.fontweight?a.theme.fontweight:"bold"},a.text=a.theme.text||Math.floor(a.width)+"x"+Math.floor(a.height),a.noWrap=a.theme.nowrap||a.flags.nowrap,a.align=a.theme.align||a.flags.align||"center",a.flags.textmode){case"literal":a.text=a.flags.dimensions.width+"x"+a.flags.dimensions.height;break;case"exact":if(!a.flags.exactDimensions)break;a.text=Math.floor(a.flags.exactDimensions.width)+"x"+Math.floor(a.flags.exactDimensions.height)}var d=new y({width:a.width,height:a.height}),e=d.Shape,f=new e.Rect("holderBg",{fill:a.theme.background});f.resize(a.width,a.height),d.root.add(f);var g=new e.Group("holderTextGroup",{text:a.text,align:a.align,font:a.font,fill:a.theme.foreground});g.moveTo(null,null,1),d.root.add(g);var h=g.textPositionData=K(d);if(!h)throw"Holder: staging fallback not supported yet.";g.properties.leading=h.boundingBox.height;var i=null,j=null,l=a.width*J.setup.lineWrapRatio,m=l;if(h.lineCount>1){var n,o=0,p=0,q=0;j=new e.Group("line"+q),("left"===a.align||"right"===a.align)&&(m=a.width*(1-2*(1-J.setup.lineWrapRatio)));for(var r=0;r<h.words.length;r++){var s=h.words[r];i=new e.Text(s.text);var t="\\n"==s.text;!a.noWrap&&(o+s.width>=m||t===!0)&&(b(g,j,o,g.properties.leading),g.add(j),o=0,p+=g.properties.leading,q+=1,j=new e.Group("line"+q),j.y=p),t!==!0&&(i.moveTo(o,0),o+=h.spaceWidth+s.width,j.add(i))}if(b(g,j,o,g.properties.leading),g.add(j),"left"===a.align)g.moveTo(a.width-l,null,null);else if("right"===a.align){for(n in g.children)j=g.children[n],j.moveTo(a.width-j.width,null,null);g.moveTo(0-(a.width-l),null,null)}else{for(n in g.children)j=g.children[n],j.moveTo((g.width-j.width)/2,null,null);g.moveTo((a.width-g.width)/2,null,null)}g.moveTo(null,(a.height-g.height)/2,null),(a.height-g.height)/2<0&&g.moveTo(null,0,null)}else i=new e.Text(a.text),j=new e.Group("line0"),j.add(i),g.add(j),"left"===a.align?g.moveTo(a.width-l,null,null):"right"===a.align?g.moveTo(0-(a.width-l),null,null):g.moveTo((a.width-h.boundingBox.width)/2,null,null),g.moveTo(null,(a.height-h.boundingBox.height)/2,null);return d}function k(a,b,c){var d=parseInt(a,10),e=parseInt(b,10),f=Math.max(d,e),g=Math.min(d,e),h=.8*Math.min(g,f*J.defaults.scale);return Math.round(Math.max(c,h))}function l(a){var b;b=null==a||null==a.nodeType?J.vars.resizableImages:[a];for(var c=0,d=b.length;d>c;c++){var e=b[c];if(e.holderData){var f=e.holderData.flags,g=D(e);if(g){if(!e.holderData.resizeUpdate)continue;if(f.fluid&&f.auto){var h=e.holderData.fluidConfig;switch(h.mode){case"width":g.height=g.width/h.ratio;break;case"height":g.width=g.height*h.ratio}}var j={mode:"image",holderSettings:{dimensions:g,theme:f.theme,flags:f},el:e,engineSettings:e.holderData.engineSettings};"exact"==f.textmode&&(f.exactDimensions=g,j.holderSettings.dimensions=f.dimensions),i(j)}else p(e)}}}function m(a){if(a.holderData){var b=D(a);if(b){var c=a.holderData.flags,d={fluidHeight:"%"==c.dimensions.height.slice(-1),fluidWidth:"%"==c.dimensions.width.slice(-1),mode:null,initialDimensions:b};d.fluidWidth&&!d.fluidHeight?(d.mode="width",d.ratio=d.initialDimensions.width/parseFloat(c.dimensions.height)):!d.fluidWidth&&d.fluidHeight&&(d.mode="height",d.ratio=parseFloat(c.dimensions.width)/d.initialDimensions.height),a.holderData.fluidConfig=d}else p(a)}}function n(){for(var a,c=[],d=Object.keys(J.vars.invisibleImages),e=0,f=d.length;f>e;e++)a=J.vars.invisibleImages[d[e]],D(a)&&"img"==a.nodeName.toLowerCase()&&(c.push(a),delete J.vars.invisibleImages[d[e]]);c.length&&I.run({images:c}),b.requestAnimationFrame(n)}function o(){J.vars.visibilityCheckStarted||(b.requestAnimationFrame(n),J.vars.visibilityCheckStarted=!0)}function p(a){a.holderData.invisibleId||(J.vars.invisibleId+=1,J.vars.invisibleImages["i"+J.vars.invisibleId]=a,a.holderData.invisibleId=J.vars.invisibleId)}function q(a,b){return null==b?document.createElement(a):document.createElementNS(b,a)}function r(a,b){for(var c in b)a.setAttribute(c,b[c])}function s(a,b,c){var d,e;null==a?(a=q("svg",E),d=q("defs",E),e=q("style",E),r(e,{type:"text/css"}),d.appendChild(e),a.appendChild(d)):e=a.querySelector("style"),a.webkitMatchesSelector&&a.setAttribute("xmlns",E);for(var f=0;f<a.childNodes.length;f++)a.childNodes[f].nodeType===F&&a.removeChild(a.childNodes[f]);for(;e.childNodes.length;)e.removeChild(e.childNodes[0]);return r(a,{width:b,height:c,viewBox:"0 0 "+b+" "+c,preserveAspectRatio:"none"}),a}function t(a,c){if(b.XMLSerializer){var d=new XMLSerializer,e="",f=c.stylesheets;if(c.svgXMLStylesheet){for(var g=u(),h=f.length-1;h>=0;h--){var i=g.createProcessingInstruction("xml-stylesheet",'href="'+f[h]+'" rel="stylesheet"');g.insertBefore(i,g.firstChild)}g.removeChild(g.documentElement),e=d.serializeToString(g)}var j=d.serializeToString(a);return j=j.replace(/\&amp;(\#[0-9]{2,}\;)/g,"&$1"),e+j}}function u(){return b.DOMParser?(new DOMParser).parseFromString("<xml />","application/xml"):void 0}function v(a){J.vars.debounceTimer||a.call(this),J.vars.debounceTimer&&b.clearTimeout(J.vars.debounceTimer),J.vars.debounceTimer=b.setTimeout(function(){J.vars.debounceTimer=null,a.call(this)},J.setup.debounce)}function w(){v(function(){l(null)})}var x=c(1),y=c(2),z=c(3),A=c(4),B=z.extend,C=z.getNodeArray,D=z.dimensionCheck,E="http://www.w3.org/2000/svg",F=8,G="2.7.1",H="\nCreated with Holder.js "+G+".\nLearn more at http://holderjs.com\n(c) 2012-2015 Ivan Malopinsky - http://imsky.co\n",I={version:G,addTheme:function(a,b){return null!=a&&null!=b&&(J.settings.themes[a]=b),delete J.vars.cache.themeKeys,this},addImage:function(a,b){var c=document.querySelectorAll(b);if(c.length)for(var d=0,e=c.length;e>d;d++){var f=q("img"),g={};g[J.vars.dataAttr]=a,r(f,g),c[d].appendChild(f)}return this},setResizeUpdate:function(a,b){a.holderData&&(a.holderData.resizeUpdate=!!b,a.holderData.resizeUpdate&&l(a))},run:function(a){a=a||{};var c={},f=B(J.settings,a);J.vars.preempted=!0,J.vars.dataAttr=f.dataAttr||J.vars.dataAttr,c.renderer=f.renderer?f.renderer:J.setup.renderer,-1===J.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=J.setup.supportsSVG?"svg":J.setup.supportsCanvas?"canvas":"html");var g=C(f.images),i=C(f.bgnodes),j=C(f.stylenodes),k=C(f.objects);c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=f.noFontFallback?f.noFontFallback:!1;for(var l=0;l<j.length;l++){var m=j[l];if(m.attributes.rel&&m.attributes.href&&"stylesheet"==m.attributes.rel.value){var n=m.attributes.href.value,o=q("a");o.href=n;var p=o.protocol+"//"+o.host+o.pathname+o.search;c.stylesheets.push(p)}}for(l=0;l<i.length;l++)if(b.getComputedStyle){var r=b.getComputedStyle(i[l],null).getPropertyValue("background-image"),s=i[l].getAttribute("data-background-src"),t=null;t=null==s?r:s;var u=null,v="?"+f.domain+"/";if(0===t.indexOf(v))u=t.slice(1);else if(-1!=t.indexOf(v)){var w=t.substr(t.indexOf(v)).slice(1),x=w.match(/([^\"]*)"?\)/);null!=x&&(u=x[1])}if(null!=u){var y=e(u,f);y&&h({mode:"background",el:i[l],flags:y,engineSettings:c})}}for(l=0;l<k.length;l++){var A=k[l],D={};try{D.data=A.getAttribute("data"),D.dataSrc=A.getAttribute(J.vars.dataAttr)}catch(E){}var F=null!=D.data&&0===D.data.indexOf(f.domain),G=null!=D.dataSrc&&0===D.dataSrc.indexOf(f.domain);F?d(f,c,D.data,A):G&&d(f,c,D.dataSrc,A)}for(l=0;l<g.length;l++){var H=g[l],I={};try{I.src=H.getAttribute("src"),I.dataSrc=H.getAttribute(J.vars.dataAttr),I.rendered=H.getAttribute("data-holder-rendered")}catch(E){}var K=null!=I.src,L=null!=I.dataSrc&&0===I.dataSrc.indexOf(f.domain),M=null!=I.rendered&&"true"==I.rendered;K?0===I.src.indexOf(f.domain)?d(f,c,I.src,H):L&&(M?d(f,c,I.dataSrc,H):!function(a,b,c,e,f){z.imageExists(a,function(a){a||d(b,c,e,f)})}(I.src,f,c,I.dataSrc,H)):L&&d(f,c,I.dataSrc,H)}return this}},J={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",stylesheets:[],themes:{gray:{background:"#EEEEEE",foreground:"#AAAAAA"},social:{background:"#3a5a97",foreground:"#FFFFFF"},industrial:{background:"#434A52",foreground:"#C2F200"},sky:{background:"#0D8FDB",foreground:"#FFFFFF"},vine:{background:"#39DBAC",foreground:"#1E292C"},lava:{background:"#F8591A",foreground:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16},flags:{dimensions:{regex:/^(\d+)x(\d+)$/,output:function(a){var b=this.regex.exec(a);return{width:+b[1],height:+b[2]}}},fluid:{regex:/^([0-9]+%?)x([0-9]+%?)$/,output:function(a){var b=this.regex.exec(a);return{width:b[1],height:b[2]}}},colors:{regex:/(?:#|\^)([0-9a-f]{3,})\:(?:#|\^)([0-9a-f]{3,})/i,output:function(a){var b=this.regex.exec(a);return{foreground:"#"+b[2],background:"#"+b[1]}}},text:{regex:/text\:(.*)/,output:function(a){return this.regex.exec(a)[1].replace("\\/","/")}},font:{regex:/font\:(.*)/,output:function(a){return this.regex.exec(a)[1]}},auto:{regex:/^auto$/},textmode:{regex:/textmode\:(.*)/,output:function(a){return this.regex.exec(a)[1]}},random:{regex:/^random$/},size:{regex:/size\:(\d+)/,output:function(a){return this.regex.exec(a)[1]}}}},K=function(){var a=null,b=null,c=null;return function(d){var e=d.root;if(J.setup.supportsSVG){var f=!1,g=function(a){return document.createTextNode(a)};(null==a||a.parentNode!==document.body)&&(f=!0),a=s(a,e.properties.width,e.properties.height),a.style.display="block",f&&(b=q("text",E),c=g(null),r(b,{x:0}),b.appendChild(c),a.appendChild(b),document.body.appendChild(a),a.style.visibility="hidden",a.style.position="absolute",a.style.top="-100%",a.style.left="-100%");var h=e.children.holderTextGroup,i=h.properties;r(b,{y:i.font.size,style:z.cssProps({"font-weight":i.font.weight,"font-size":i.font.size+i.font.units,"font-family":i.font.family})}),c.nodeValue=i.text;var j=b.getBBox(),k=Math.ceil(j.width/(e.properties.width*J.setup.lineWrapRatio)),l=i.text.split(" "),m=i.text.match(/\\n/g);k+=null==m?0:m.length,c.nodeValue=i.text.replace(/[ ]+/g,"");var n=b.getComputedTextLength(),o=j.width-n,p=Math.round(o/Math.max(1,l.length-1)),t=[];if(k>1){c.nodeValue="";for(var u=0;u<l.length;u++)if(0!==l[u].length){c.nodeValue=z.decodeHtmlEntity(l[u]);var v=b.getBBox();t.push({text:l[u],width:v.width})}}return a.style.display="none",{spaceWidth:p,lineCount:k,boundingBox:j,words:t}}return!1}}(),L=function(){var a=q("canvas"),b=null;return function(c){null==b&&(b=a.getContext("2d"));var d=c.root;a.width=J.dpr(d.properties.width),a.height=J.dpr(d.properties.height),b.textBaseline="middle",b.fillStyle=d.children.holderBg.properties.fill,b.fillRect(0,0,J.dpr(d.children.holderBg.width),J.dpr(d.children.holderBg.height));{var e=d.children.holderTextGroup;e.properties}b.font=e.properties.font.weight+" "+J.dpr(e.properties.font.size)+e.properties.font.units+" "+e.properties.font.family+", monospace",b.fillStyle=e.properties.fill;for(var f in e.children){var g=e.children[f];for(var h in g.children){var i=g.children[h],j=J.dpr(e.x+g.x+i.x),k=J.dpr(e.y+g.y+i.y+e.properties.leading/2);b.fillText(i.properties.text,j,k)}}return a.toDataURL("image/png")}}(),M=function(){if(b.XMLSerializer){var a=u(),c=s(null,0,0),d=q("rect",E);return c.appendChild(d),function(b,e){var f=b.root;s(c,f.properties.width,f.properties.height);for(var g=c.querySelectorAll("g"),h=0;h<g.length;h++)g[h].parentNode.removeChild(g[h]);var i=e.holderSettings.flags.holderURL,j="holder_"+(Number(new Date)+32768+(0|32768*Math.random())).toString(16),k=q("g",E),l=f.children.holderTextGroup,m=l.properties,n=q("g",E),o=l.textPositionData,p="#"+j+" text { "+z.cssProps({fill:m.fill,"font-weight":m.font.weight,"font-family":m.font.family+", monospace","font-size":m.font.size+m.font.units})+" } ",u=a.createComment("\nSource URL: "+i+H),v=a.createCDATASection(p),w=c.querySelector("style");r(k,{id:j}),c.insertBefore(u,c.firstChild),w.appendChild(v),k.appendChild(d),k.appendChild(n),c.appendChild(k),r(d,{width:f.children.holderBg.width,height:f.children.holderBg.height,fill:f.children.holderBg.properties.fill}),l.y+=.8*o.boundingBox.height;for(var x in l.children){var y=l.children[x];for(var A in y.children){var B=y.children[A],C=l.x+y.x+B.x,D=l.y+y.y+B.y,F=q("text",E),G=document.createTextNode(null);r(F,{x:C,y:D}),G.nodeValue=B.properties.text,F.appendChild(G),n.appendChild(F)}}var I=N(t(c,e.engineSettings),"background"===e.mode);return I}}}(),N=function(){var a="data:image/svg+xml;charset=UTF-8,",b="data:image/svg+xml;charset=UTF-8;base64,";return function(c,d){return d?b+btoa(unescape(encodeURIComponent(c))):a+encodeURIComponent(c)}}();for(var O in J.flags)J.flags.hasOwnProperty(O)&&(J.flags[O].match=function(a){return a.match(this.regex)});J.setup={renderer:"html",debounce:100,ratio:1,supportsCanvas:!1,supportsSVG:!1,lineWrapRatio:.9,renderers:["html","canvas","svg"]},J.dpr=function(a){return a*J.setup.ratio},J.vars={preempted:!1,resizableImages:[],invisibleImages:{},invisibleId:0,visibilityCheckStarted:!1,debounceTimer:null,cache:{},dataAttr:"data-src"},function(){var a=1,c=1,d=q("canvas"),e=null;d.getContext&&-1!=d.toDataURL("image/png").indexOf("data:image/png")&&(J.setup.renderer="canvas",e=d.getContext("2d"),J.setup.supportsCanvas=!0),J.setup.supportsCanvas&&(a=b.devicePixelRatio||1,c=e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1),J.setup.ratio=a/c,document.createElementNS&&document.createElementNS(E,"svg").createSVGRect&&(J.setup.renderer="svg",J.setup.supportsSVG=!0)}(),o(),x&&x(function(){J.vars.preempted||I.run(),b.addEventListener?(b.addEventListener("resize",w,!1),b.addEventListener("orientationchange",w,!1)):b.attachEvent("onresize",w),"object"==typeof b.Turbolinks&&b.document.addEventListener("page:change",function(){I.run()})}),a.exports=I}).call(b,function(){return this}())},function(a){function b(a){function b(a){if(!v){if(!g.body)return e(b);for(v=!0;a=w.shift();)e(a)}}function c(a){(t||a.type===i||g[m]===l)&&(d(),b())}function d(){t?(g[s](q,c,j),a[s](i,c,j)):(g[o](r,c),a[o](k,c))}function e(a,b){setTimeout(a,+b>=0?b:1)}function f(a){v?e(a):w.push(a)}null==document.readyState&&document.addEventListener&&(document.addEventListener("DOMContentLoaded",function y(){document.removeEventListener("DOMContentLoaded",y,!1),document.readyState="complete"},!1),document.readyState="loading");var g=a.document,h=g.documentElement,i="load",j=!1,k="on"+i,l="complete",m="readyState",n="attachEvent",o="detachEvent",p="addEventListener",q="DOMContentLoaded",r="onreadystatechange",s="removeEventListener",t=p in g,u=j,v=j,w=[];if(g[m]===l)e(b);else if(t)g[p](q,c,j),a[p](i,c,j);else{g[n](r,c),a[n](k,c);try{u=null==a.frameElement&&h}catch(x){}u&&u.doScroll&&!function z(){if(!v){try{u.doScroll("left")}catch(a){return e(z,50)}d(),b()}}()}return f.version="1.4.0",f.isReady=function(){return v},f}a.exports="undefined"!=typeof window&&b(window)},function(a,b,c){var d=c(5),e=function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}var c=1,e=d.defclass({constructor:function(a){c++,this.parent=null,this.children={},this.id=c,this.name="n"+c,null!=a&&(this.name=a),this.x=0,this.y=0,this.z=0,this.width=0,this.height=0},resize:function(a,b){null!=a&&(this.width=a),null!=b&&(this.height=b)},moveTo:function(a,b,c){this.x=null!=a?a:this.x,this.y=null!=b?b:this.y,this.z=null!=c?c:this.z},add:function(a){var b=a.name;if(null!=this.children[b])throw"SceneGraph: child with that name already exists: "+b;this.children[b]=a,a.parent=this}}),f=d(e,function(b){this.constructor=function(){b.constructor.call(this,"root"),this.properties=a}}),g=d(e,function(a){function c(c,d){if(a.constructor.call(this,c),this.properties={fill:"#000"},null!=d)b(this.properties,d);else if(null!=c&&"string"!=typeof c)throw"SceneGraph: invalid node name"}this.Group=d.extend(this,{constructor:c,type:"group"}),this.Rect=d.extend(this,{constructor:c,type:"rect"}),this.Text=d.extend(this,{constructor:function(a){c.call(this),this.properties.text=a},type:"text"})}),h=new f;return this.Shape=g,this.root=h,this};a.exports=e},function(a,b){(function(a){b.extend=function(a,b){var c={};for(var d in a)a.hasOwnProperty(d)&&(c[d]=a[d]);if(null!=b)for(var e in b)b.hasOwnProperty(e)&&(c[e]=b[e]);return c},b.cssProps=function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c+":"+a[c]);return b.join(";")},b.encodeHtmlEntity=function(a){for(var b=[],c=0,d=a.length-1;d>=0;d--)c=a.charCodeAt(d),b.unshift(c>128?["&#",c,";"].join(""):a[d]);return b.join("")},b.getNodeArray=function(b){var c=null;return"string"==typeof b?c=document.querySelectorAll(b):a.NodeList&&b instanceof a.NodeList?c=b:a.Node&&b instanceof a.Node?c=[b]:a.HTMLCollection&&b instanceof a.HTMLCollection?c=b:b instanceof Array?c=b:null===b&&(c=[]),c},b.imageExists=function(a,b){var c=new Image;c.onerror=function(){b.call(this,!1)},c.onload=function(){b.call(this,!0)},c.src=a},b.decodeHtmlEntity=function(a){return a.replace(/&#(\d+);/g,function(a,b){return String.fromCharCode(b)})},b.dimensionCheck=function(a){var b={height:a.clientHeight,width:a.clientWidth};return b.height&&b.width?b:!1},b.truthy=function(a){return"string"==typeof a?"true"===a||"yes"===a||"1"===a||"on"===a||"✓"===a:!!a}}).call(b,function(){return this}())},function(a,b,c){var d=encodeURIComponent,e=decodeURIComponent,f=c(6),g=c(7),h=/(\w+)\[(\d+)\]/,i=/\w+\.\w+/;b.parse=function(a){if("string"!=typeof a)return{};if(a=f(a),""===a)return{};"?"===a.charAt(0)&&(a=a.slice(1));for(var b={},c=a.split("&"),d=0;d<c.length;d++){var g,j,k,l=c[d].split("="),m=e(l[0]);if(g=h.exec(m))b[g[1]]=b[g[1]]||[],b[g[1]][g[2]]=e(l[1]);else if(g=i.test(m)){for(g=m.split("."),j=b;g.length;)if(k=g.shift(),k.length){if(j[k]){if(j[k]&&"object"!=typeof j[k])break}else j[k]={};g.length||(j[k]=e(l[1])),j=j[k]}}else b[l[0]]=null==l[1]?"":e(l[1])}return b},b.stringify=function(a){if(!a)return"";var b=[];for(var c in a){var e=a[c];if("array"!=g(e))b.push(d(c)+"="+d(a[c]));else for(var f=0;f<e.length;++f)b.push(d(c+"["+f+"]")+"="+d(e[f]))}return b.join("&")}},function(a){var b=function(){},c=Array.prototype.slice,d=function(a,d){var e=b.prototype="function"==typeof a?a.prototype:a,f=new b,g=d.apply(f,c.call(arguments,2).concat(e));if("object"==typeof g)for(var h in g)f[h]=g[h];if(!f.hasOwnProperty("constructor"))return f;var i=f.constructor;return i.prototype=f,i};d.defclass=function(a){var b=a.constructor;return b.prototype=a,b},d.extend=function(a,b){return d(a,function(a){return this.uber=a,b})},a.exports=d},function(a,b){function c(a){return a.replace(/^\s*|\s*$/g,"")}b=a.exports=c,b.left=function(a){return a.replace(/^\s*/,"")},b.right=function(a){return a.replace(/\s*$/,"")}},function(a){var b=Object.prototype.toString;a.exports=function(a){switch(b.call(a)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}return null===a?"null":void 0===a?"undefined":a!==a?"nan":a&&1===a.nodeType?"element":(a=a.valueOf?a.valueOf():Object.prototype.valueOf.apply(a),typeof a)}}])}),function(a,b){b&&(Holder=a.Holder)}(this,"undefined"!=typeof Meteor&&"undefined"!=typeof Package);
  19424. /* nvd3 version 1.7.1 (https://github.com/novus/nvd3) 2015-02-08 */
  19425. !function(){var a=window.nv||{};window.nv=a,a.dev=!1,a.tooltip=a.tooltip||{},a.utils=a.utils||{},a.models=a.models||{},a.charts={},a.graphs=[],a.logs={},a.dispatch=d3.dispatch("render_start","render_end"),Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d&&a?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),a.dev&&(a.dispatch.on("render_start",function(){a.logs.startTime=+new Date}),a.dispatch.on("render_end",function(){a.logs.endTime=+new Date,a.logs.totalTime=a.logs.endTime-a.logs.startTime,a.log("total",a.logs.totalTime)})),a.log=function(){if(a.dev&&window.console&&console.log&&console.log.apply)console.log.apply(console,arguments);else if(a.dev&&window.console&&"function"==typeof console.log&&Function.prototype.bind){var b=Function.prototype.bind.call(console.log,console);b.apply(console,arguments)}return arguments[arguments.length-1]},a.deprecated=function(b){a.dev&&console&&console.warn&&console.warn("`"+b+"` has been deprecated.")},a.render=function(b){b=b||1,a.render.active=!0,a.dispatch.render_start(),setTimeout(function(){for(var c,d,e=0;b>e&&(d=a.render.queue[e]);e++)c=d.generate(),typeof d.callback==typeof Function&&d.callback(c),a.graphs.push(c);a.render.queue.splice(0,e),a.render.queue.length?setTimeout(arguments.callee,0):(a.dispatch.render_end(),a.render.active=!1)},0)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&d3.event.relatedTarget.className.match(c.nvPointerEventsClass))return;return h.elementMouseout({mouseX:d,mouseY:e}),void b.renderGuideLine(null)}var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.renderGuideLine=function(b){if(i){var c=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=b?[a.utils.NaNtoZero(b)]:[],String);c.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),c.exit().remove()}})})}var c=a.models.tooltip(),d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=(d3.scale.linear(),d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick")),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;"function"!=typeof c&&(c=function(a){return a.x});var d=d3.bisector(c).left,e=d3.max([0,d(a,b)-1]),f=c(a[e],e);if("undefined"==typeof f&&(f=e),f===b)return e;var g=d3.min([e+1,a.length-1]),h=c(a[g],g);return"undefined"==typeof h&&(h=g),Math.abs(h-b)>=Math.abs(f-b)?e:g},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";window.nv.tooltip={},window.nv.models.tooltip=function(){function b(){if(l){var a=d3.select(l);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"))/b[2];n.left=n.left*c,n.top=n.top*c}}}function c(a){var b;b=d3.select(l?l:"body");var c=b.select(".nvtooltip");return null===c.node()&&(c=b.append("div").attr("class","nvtooltip "+(k?k:"xy-tooltip")).attr("id",p)),c.node().innerHTML=a,c.style("top",0).style("left",0).style("opacity",0),c.selectAll("div, table, td, tr").classed(q,!0),c.classed(q,!0),c.node()}function d(){if(o&&u(f)){b();var e=n.left,k=null!=j?j:n.top,p=c(t(f));if(m=p,l){var q=l.getElementsByTagName("svg")[0],r=(q?q.getBoundingClientRect():l.getBoundingClientRect(),{left:0,top:0});if(q){var s=q.getBoundingClientRect(),v=l.getBoundingClientRect(),w=s.top;if(0>w){var x=l.getBoundingClientRect();w=Math.abs(w)>x.height?0:w}r.top=Math.abs(w-v.top),r.left=Math.abs(s.left-v.left)}e+=l.offsetLeft+r.left-2*l.scrollLeft,k+=l.offsetTop+r.top-2*l.scrollTop}return i&&i>0&&(k=Math.floor(k/i)*i),a.tooltip.calcTooltipPosition([e,k],g,h,p),d}}var e=null,f=null,g="w",h=50,i=25,j=null,k=null,l=null,m=null,n={left:null,top:null},o=!0,p="nvtooltip-"+Math.floor(1e5*Math.random()),q="nv-pointer-events-none",r=function(a){return a},s=function(a){return a},t=function(a){if(null!=e)return e;if(null==a)return"";var b=d3.select(document.createElement("table")),c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(s(a.value));var d=b.selectAll("tbody").data([a]).enter().append("tbody"),f=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});f.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),f.append("td").classed("key",!0).html(function(a){return a.key}),f.append("td").classed("value",!0).html(function(a,b){return r(a.value,b)}),f.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var g=b.node().outerHTML;return void 0!==a.footer&&(g+="<div class='footer'>"+a.footer+"</div>"),g},u=function(a){return a&&a.series&&a.series.length>0?!0:!1};return d.nvPointerEventsClass=q,d.content=function(a){return arguments.length?(e=a,d):e},d.tooltipElem=function(){return m},d.contentGenerator=function(a){return arguments.length?("function"==typeof a&&(t=a),d):t},d.data=function(a){return arguments.length?(f=a,d):f},d.gravity=function(a){return arguments.length?(g=a,d):g},d.distance=function(a){return arguments.length?(h=a,d):h},d.snapDistance=function(a){return arguments.length?(i=a,d):i},d.classes=function(a){return arguments.length?(k=a,d):k},d.chartContainer=function(a){return arguments.length?(l=a,d):l},d.position=function(a){return arguments.length?(n.left="undefined"!=typeof a.left?a.left:n.left,n.top="undefined"!=typeof a.top?a.top:n.top,d):n},d.fixedTop=function(a){return arguments.length?(j=a,d):j},d.enabled=function(a){return arguments.length?(o=a,d):o},d.valueFormatter=function(a){return arguments.length?("function"==typeof a&&(r=a),d):r},d.headerFormatter=function(a){return arguments.length?("function"==typeof a&&(s=a),d):s},d.id=function(){return p},d},a.tooltip.show=function(b,c,d,e,f,g){var h=document.createElement("div");h.className="nvtooltip "+(g?g:"xy-tooltip");var i=f;(!f||f.tagName.match(/g|svg/i))&&(i=document.getElementsByTagName("body")[0]),h.style.left=0,h.style.top=0,h.style.opacity=0,"string"!=typeof c?h.appendChild(c):h.innerHTML=c,i.appendChild(h),f&&(b[0]=b[0]-f.scrollLeft,b[1]=b[1]-f.scrollTop),a.tooltip.calcTooltipPosition(b,d,e,h)},a.tooltip.findFirstNonSVGParent=function(a){for(;null!==a.tagName.match(/^g|svg$/i);)a=a.parentNode;return a},a.tooltip.findTotalOffsetTop=function(a,b){var c=b;do isNaN(a.offsetTop)||(c+=a.offsetTop);while(a=a.offsetParent);return c},a.tooltip.findTotalOffsetLeft=function(a,b){var c=b;do isNaN(a.offsetLeft)||(c+=a.offsetLeft);while(a=a.offsetParent);return c},a.tooltip.calcTooltipPosition=function(b,c,d,e){var f,g,h=parseInt(e.offsetHeight),i=parseInt(e.offsetWidth),j=a.utils.windowSize().width,k=a.utils.windowSize().height,l=window.pageYOffset,m=window.pageXOffset;k=window.innerWidth>=document.body.scrollWidth?k:k-16,j=window.innerHeight>=document.body.scrollHeight?j:j-16,c=c||"s",d=d||20;var n=function(b){return a.tooltip.findTotalOffsetTop(b,g)},o=function(b){return a.tooltip.findTotalOffsetLeft(b,f)};switch(c){case"e":f=b[0]-i-d,g=b[1]-h/2;var p=o(e),q=n(e);m>p&&(f=b[0]+d>m?b[0]+d:m-p+f),l>q&&(g=l-q+g),q+h>l+k&&(g=l+k-q+g-h);break;case"w":f=b[0]+d,g=b[1]-h/2;var p=o(e),q=n(e);p+i>j&&(f=b[0]-i-d),l>q&&(g=l+5),q+h>l+k&&(g=l+k-q+g-h);break;case"n":f=b[0]-i/2-5,g=b[1]+d;var p=o(e),q=n(e);m>p&&(f=m+5),p+i>j&&(f=f-i/2+5),q+h>l+k&&(g=l+k-q+g-h);break;case"s":f=b[0]-i/2,g=b[1]-h-d;var p=o(e),q=n(e);m>p&&(f=m+5),p+i>j&&(f=f-i/2+5),l>q&&(g=l);break;case"none":f=b[0],g=b[1]-d;var p=o(e),q=n(e)}return e.style.left=f+"px",e.style.top=g+"px",e.style.opacity=1,e.style.position="absolute",e},a.tooltip.cleanup=function(){for(var a=document.getElementsByClassName("nvtooltip"),b=[];a.length;)b.push(a[0]),a[0].style.transitionDelay="0 !important",a[0].style.opacity=0,a[0].className="nvtooltip-pending-removal";setTimeout(function(){for(;b.length;){var a=b.pop();a.parentNode.removeChild(a)}},500)}}(),a.utils.windowSize=function(){var a={width:640,height:480};return document.body&&document.body.offsetWidth&&(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight),"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth&&(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight),window.innerWidth&&window.innerHeight&&(a.width=window.innerWidth,a.height=window.innerHeight),a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){return arguments.length?b instanceof Array?function(a,c){return a.color||b[c%b.length]}:b:a.utils.defaultColor()},a.utils.defaultColor=function(){var a=d3.scale.category20().range();return function(b,c){return b.color||a[c%a.length]}},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px","")),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(key in c){var d=b[key]instanceof Array,e="object"==typeof b[key],f="object"==typeof c[key];e&&!d&&f?a.utils.deepExtend(b[key],c[key]):b[key]=c[key]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(b){return a.deprecated("nv.utils.optionsFunc"),b&&d3.map(b).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;e<c.length;e+=1){var f=c[e]&&c[e].values?c[e].values.length:0;d=f>d?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a[b]=a._calls&&a._calls[b]?a._calls[b]:function(c){return arguments.length?(a._options[b]=c,a):a._options[b]}},a.utils.initOptions=function(b){var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.models.axis=function(){"use strict";function b(g){return t.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var q=g.selectAll("g.nv-wrap.nv-axis").data([b]),r=q.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),u=(r.append("g"),q.select("g"));null!==o?c.ticks(o):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),u.watchTransition(t,"axis").call(c),s=s||c.scale();var v=c.tickFormat();null==v&&(v=s.tickFormat());var w=u.selectAll("text.nv-axislabel").data([h||null]);switch(w.exit().remove(),c.orient()){case"top":w.enter().append("text").attr("class","nv-axislabel");var x;if(x=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),w.attr("text-anchor","middle").attr("y",0).attr("x",x/2),i){var y=q.selectAll("g.nv-axisMaxMin").data(d.domain());y.enter().append("g").attr("class","nv-axisMaxMin").append("text"),y.exit().remove(),y.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=v(a);return(""+b).match("NaN")?"":b}),y.watchTransition(t,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"})}break;case"bottom":var z=p+36,A=30,B=u.selectAll("g").select("text");if(k%360){B.each(function(){var a=this.getBoundingClientRect().width;a>A&&(A=a)});var C=Math.abs(Math.sin(k*Math.PI/180)),z=(C?C*A:A)+30;B.attr("transform",function(){return"rotate("+k+" 0,0)"}).style("text-anchor",k%360>0?"start":"end")}w.enter().append("text").attr("class","nv-axislabel");var x;if(x=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),w.attr("text-anchor","middle").attr("y",z).attr("x",x/2),i){var y=q.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]);y.enter().append("g").attr("class","nv-axisMaxMin").append("text"),y.exit().remove(),y.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(n?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",function(){return"rotate("+k+" 0,0)"}).style("text-anchor",k?k%360>0?"start":"end":"middle").text(function(a){var b=v(a);return(""+b).match("NaN")?"":b}),y.watchTransition(t,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(n?d.rangeBand()/2:0))+",0)"})}m&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":if(w.enter().append("text").attr("class","nv-axislabel"),w.style("text-anchor",l?"middle":"begin").attr("transform",l?"rotate(90)":"").attr("y",l?-Math.max(e.right,f)+12:-10).attr("x",l?d.range()[0]/2:c.tickPadding()),i){var y=q.selectAll("g.nv-axisMaxMin").data(d.domain());y.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0),y.exit().remove(),y.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=v(a);return(""+b).match("NaN")?"":b}),y.watchTransition(t,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1)}break;case"left":if(w.enter().append("text").attr("class","nv-axislabel"),w.style("text-anchor",l?"middle":"end").attr("transform",l?"rotate(-90)":"").attr("y",l?-Math.max(e.left,f)+25-(p||0):-10).attr("x",l?-d.range()[0]/2:-c.tickPadding()),i){var y=q.selectAll("g.nv-axisMaxMin").data(d.domain());y.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0),y.exit().remove(),y.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(s(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=v(a);return(""+b).match("NaN")?"":b}),y.watchTransition(t,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1)}}if(w.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(u.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)<d.range()[1]+10||d(a)>d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&q.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var D=[];q.selectAll("g.nv-axisMaxMin").each(function(a,b){try{D.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){D.push(b?d(a)-4:d(a)+4)}}),u.selectAll("g").each(function(a){(d(a)<D[0]||d(a)>D[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}j&&u.selectAll(".tick").filter(function(){return!parseFloat(Math.round(1e5*this.__data__)/1e6)&&void 0!==this.__data__}).classed("zero",!0),s=d.copy()}),t.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=!0,k=0,l=!0,m=!1,n=!1,o=null,p=0,q=250,r=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var s,t=a.utils.renderWatch(r,q);return b.axis=c,b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return p},set:function(a){p=a}},staggerLabels:{get:function(){return m},set:function(a){m=a}},rotateLabels:{get:function(){return k},set:function(a){k=a}},rotateYLabel:{get:function(){return l},set:function(a){l=a}},highlightZero:{get:function(){return j},set:function(a){j=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return o},set:function(a){o=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return q},set:function(a){q=a,t.reset(q)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),n="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var o=m-c.left-c.right,r=n-c.top-c.bottom,s=d3.select(this);a.utils.initSVG(s);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[o,0]:[0,o]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=s.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),F.append("path").attr("class","nv-markerTriangle"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",r).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",r).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",r).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",p).attr("height",r/3).attr("y",r/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){q.elementMouseover({value:v[0],label:y[0]||"Current",pos:[z(v[0]),r/2]})}).on("mouseout",function(){q.elementMouseout({value:v[0],label:y[0]||"Current"})});var J=r/6;u[0]?G.selectAll("path.nv-markerTriangle").attr("transform",function(){return"translate("+z(u[0])+","+r/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(){q.elementMouseover({value:u[0],label:x[0]||"Previous",pos:[z(u[0]),r/2]})}).on("mouseout",function(){q.elementMouseout({value:u[0],label:x[0]||"Previous"})}):G.selectAll("path.nv-markerTriangle").remove(),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");q.elementMouseover({value:a,label:c,pos:[z(a),r/2]})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");q.elementMouseout({value:a,label:c})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=a.utils.getColor(["#1f77b4"]),q=d3.dispatch("elementMouseover","elementMouseout");return b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(n,r){var s=d3.select(this);a.utils.initSVG(s);var t=(j||parseInt(s.style("width"))||960)-f.left-f.right,u=k-f.top-f.bottom,v=this;if(b.update=function(){b(d)},b.container=this,!n||!g.call(this,n,r)){var w=s.selectAll(".nv-noData").data([o]);return w.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),w.attr("x",f.left+t/2).attr("y",18+f.top+u/2).text(function(a){return a}),b}s.selectAll(".nv-noData").remove();var x=g.call(this,n,r).slice().sort(d3.descending),y=h.call(this,n,r).slice().sort(d3.descending),z=i.call(this,n,r).slice().sort(d3.descending),A=s.selectAll("g.nv-wrap.nv-bulletChart").data([n]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),C=B.append("g"),D=A.select("g");C.append("g").attr("class","nv-bulletWrap"),C.append("g").attr("class","nv-titles"),A.attr("transform","translate("+f.left+","+f.top+")");var E=d3.scale.linear().domain([0,Math.max(x[0],y[0],z[0])]).range(e?[t,0]:[0,t]),F=this.__chart__||d3.scale.linear().domain([0,1/0]).range(E.range());this.__chart__=E;var G=C.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(k-f.top-f.bottom)/2+")");G.append("text").attr("class","nv-title").text(function(a){return a.title}),G.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(t).height(u);var H=D.select(".nv-bulletWrap");d3.transition(H).call(c);var I=l||E.tickFormat(t/100),J=D.selectAll("g.nv-tick").data(E.ticks(t/50),function(a){return this.textContent||I(a)}),K=J.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+F(a)+",0)"}).style("opacity",1e-6);K.append("line").attr("y1",u).attr("y2",7*u/6),K.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*u/6).text(I);var L=d3.transition(J).attr("transform",function(a){return"translate("+E(a)+",0)"}).style("opacity",1);L.select("line").attr("y1",u).attr("y2",7*u/6),L.select("text").attr("y",7*u/6),d3.transition(J.exit()).attr("transform",function(a){return"translate("+E(a)+",0)"}).style("opacity",1e-6).remove(),p.on("tooltipShow",function(a){a.key=n.title,m&&q(a,v.parentNode)})}),d3.timer.flush(),b}var c=a.models.bullet(),d="left",e=!1,f={top:5,right:40,bottom:20,left:120},g=function(a){return a.ranges},h=function(a){return a.markers?a.markers:[0]},i=function(a){return a.measures},j=null,k=55,l=null,m=!0,n=function(a,b,c){return"<h3>"+b+"</h3><p>"+c+"</p>"},o="No Data Available.",p=d3.dispatch("tooltipShow","tooltipHide"),q=function(c,d){var e=c.pos[0]+(d.offsetLeft||0)+f.left,g=c.pos[1]+(d.offsetTop||0)+f.top,h=n(c.key,c.label,c.value,c,b);a.tooltip.show([e,g],h,c.value<0?"e":"w",null,d)};return c.dispatch.on("elementMouseover.tooltip",function(a){p.tooltipShow(a)}),c.dispatch.on("elementMouseout.tooltip",function(a){p.tooltipHide(a)}),p.on("tooltipHide",function(){m&&a.tooltip.cleanup()}),b.bullet=c,b.dispatch=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return g},set:function(a){g=a}},markers:{get:function(){return h},set:function(a){h=a}},measures:{get:function(){return i},set:function(a){i=a}},width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},tickFormat:{get:function(){return l},set:function(a){l=a}},tooltips:{get:function(){return m},set:function(a){m=a}},tooltipContent:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(x){return I.reset(),I.models(f),q&&I.models(g),r&&I.models(h),x.each(function(x){function F(){d3.select(b.container).style("cursor","ew-resize")}function I(){H.x=d3.event.x,H.i=Math.round(G.invert(H.x)),N()}function M(){d3.select(b.container).style("cursor","auto"),z.index=H.i,D.stateChange(z)}function N(){fb.data([H]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var O=d3.select(this);a.utils.initSVG(O),O.classed("nv-chart-"+y,!0);var P=this,Q=(n||parseInt(O.style("width"))||960)-l.left-l.right,R=(o||parseInt(O.style("height"))||400)-l.top-l.bottom;if(b.update=function(){0===E?O.call(b):O.transition().duration(E).call(b)},b.container=this,z.setter(L(x),b.update).getter(K(x)).update(),z.disabled=x.map(function(a){return!!a.disabled}),!A){var S;A={};for(S in z)A[S]=z[S]instanceof Array?z[S].slice(0):z[S]}var T=d3.behavior.drag().on("dragstart",F).on("drag",I).on("dragend",M);if(!(x&&x.length&&x.filter(function(a){return a.values.length}).length)){var U=O.selectAll(".nv-noData").data([B]);return U.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),U.attr("x",l.left+Q/2).attr("y",l.top+R/2).text(function(a){return a}),b}if(O.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var V=x.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),W=[d3.min(V,function(a){return a[0]
  19426. }),d3.max(V,function(a){return a[1]})];f.yDomain(W)}G.domain([0,x[0].values.length-1]).range([0,Q]).clamp(!0);var x=c(H.i,x),X=v?"none":"all",Y=O.selectAll("g.nv-wrap.nv-cumulativeLine").data([x]),Z=Y.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),$=Y.select("g");if(Z.append("g").attr("class","nv-interactive"),Z.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),Z.append("g").attr("class","nv-y nv-axis"),Z.append("g").attr("class","nv-background"),Z.append("g").attr("class","nv-linesWrap").style("pointer-events",X),Z.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),Z.append("g").attr("class","nv-legendWrap"),Z.append("g").attr("class","nv-controlsWrap"),p&&(i.width(Q),$.select(".nv-legendWrap").datum(x).call(i),l.top!=i.height()&&(l.top=i.height(),R=(o||parseInt(O.style("height"))||400)-l.top-l.bottom),$.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),u){var _=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),$.select(".nv-controlsWrap").datum(_).attr("transform","translate(0,"+-l.top+")").call(j)}Y.attr("transform","translate("+l.left+","+l.top+")"),s&&$.select(".nv-y.nv-axis").attr("transform","translate("+Q+",0)");var ab=x.filter(function(a){return a.tempDisabled});Y.select(".tempDisabled").remove(),ab.length&&Y.append("text").attr("class","tempDisabled").attr("x",Q/2).attr("y","-.71em").style("text-anchor","end").text(ab.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(Q).height(R).margin({left:l.left,top:l.top}).svgContainer(O).xScale(d),Y.select(".nv-interactive").call(k)),Z.select(".nv-background").append("rect"),$.select(".nv-background rect").attr("width",Q).attr("height",R),f.y(function(a){return a.display.y}).width(Q).height(R).color(x.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!x[b].disabled&&!x[b].tempDisabled}));var bb=$.select(".nv-linesWrap").datum(x.filter(function(a){return!a.disabled&&!a.tempDisabled}));bb.call(f),x.forEach(function(a,b){a.seriesIndex=b});var cb=x.filter(function(a){return!a.disabled&&!!C(a)}),db=$.select(".nv-avgLinesWrap").selectAll("line").data(cb,function(a){return a.key}),eb=function(a){var b=e(C(a));return 0>b?0:b>R?R:b};db.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",Q).attr("y1",eb).attr("y2",eb),db.style("stroke-opacity",function(a){var b=e(C(a));return 0>b||b>R?0:1}).attr("x1",0).attr("x2",Q).attr("y1",eb).attr("y2",eb),db.exit().remove();var fb=bb.selectAll(".nv-indexLine").data([H]);fb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(T),fb.attr("transform",function(a){return"translate("+G(a.i)+",0)"}).attr("height",R),q&&(g.scale(d).ticks(a.utils.calcTicksX(Q/70,x)).tickSize(-R,0),$.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),$.select(".nv-x.nv-axis").call(g)),r&&(h.scale(e).ticks(a.utils.calcTicksY(R/36,x)).tickSize(-Q,0),$.select(".nv-y.nv-axis").call(h)),$.select(".nv-background rect").on("click",function(){H.x=d3.mouse(this)[0],H.i=Math.round(G.invert(H.x)),z.index=H.i,D.stateChange(z),N()}),f.dispatch.on("elementClick",function(a){H.i=a.pointIndex,H.x=G(H.i),z.index=H.i,D.stateChange(z),N()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,z.rescaleY=w,D.stateChange(z),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)z[c]=a[c];D.stateChange(z),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(x.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:m(g,g.seriesIndex)}))}),j.length>2){var n=b.yScale().invert(c.mouseY),o=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),p=.03*o,q=a.nearestValueIndex(j.map(function(a){return a.value}),n,p);null!==q&&(j[q].highlight=!0)}var r=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+l.left,top:c.mouseY+l.top}).chartContainer(P.parentNode).enabled(t).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:r,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){D.tooltipHide(),f.clearHighlights()}),D.on("tooltipShow",function(a){t&&J(a,P.parentNode)}),D.on("changeState",function(a){"undefined"!=typeof a.disabled&&(x.forEach(function(b,c){b.disabled=a.disabled[c]}),z.disabled=a.disabled),"undefined"!=typeof a.index&&(H.i=a.index,H.x=G(H.i),z.index=a.index,fb.data([H])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),I.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return M||(M=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=M(c,a);return-.95>d&&!F?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(M(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l={top:30,right:30,bottom:50,left:60},m=a.utils.defaultColor(),n=null,o=null,p=!0,q=!0,r=!0,s=!1,t=!0,u=!0,v=!1,w=!0,x=function(a,b,c){return"<h3>"+a+"</h3><p>"+c+" at "+b+"</p>"},y=f.id(),z=a.utils.state(),A=null,B="No Data Available.",C=function(a){return a.average},D=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),E=250,F=!1;z.index=0,z.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),j.updateState(!1);var G=d3.scale.linear(),H={i:0,x:0},I=a.utils.renderWatch(D,E),J=function(c,d){var e=c.pos[0]+(d.offsetLeft||0),i=c.pos[1]+(d.offsetTop||0),j=g.tickFormat()(f.x()(c.point,c.pointIndex)),k=h.tickFormat()(f.y()(c.point,c.pointIndex)),l=x(c.series.key,j,k,c,b);a.tooltip.show([e,i],l,null,null,d)},K=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:H.i,rescaleY:w}}},L=function(a){return function(b){void 0!==b.index&&(H.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+l.left,a.pos[1]+l.top],D.tooltipShow(a)}),f.dispatch.on("elementMouseout.tooltip",function(a){D.tooltipHide(a)}),D.on("tooltipHide",function(){t&&a.tooltip.cleanup()});var M=null;return b.dispatch=D,b.lines=f,b.legend=i,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return p},set:function(a){p=a}},average:{get:function(){return C},set:function(a){C=a}},tooltips:{get:function(){return t},set:function(a){t=a}},tooltipContent:{get:function(){return x},set:function(a){x=a}},defaultState:{get:function(){return A},set:function(a){A=a}},noData:{get:function(){return B},set:function(a){B=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},noErrorCheck:{get:function(){return F},set:function(a){F=a}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},duration:{get:function(){return E},set:function(a){E=a,f.duration(E),g.duration(E),h.duration(E),I.reset(E)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(l){return x.reset(),l.each(function(b){var l=j-i.left-i.right,w=k-i.top-i.bottom,y=d3.select(this);a.utils.initSVG(y),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=c&&d?[]:b.map(function(a){return a.values.map(function(a,b){return{x:o(a,b),y:p(a,b),y0:a.y0}})});m.domain(c||d3.merge(z).map(function(a){return a.x})).rangeBands(e||[0,l],.1),n.domain(d||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(q))),n.range(s?f||[w-(n.domain()[0]<0?12:0),n.domain()[1]>0?12:0]:f||[w,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var A=y.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+i.left+","+i.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(x,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(x,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", "+n(0)+")"}).on("mouseover",function(a,c){d3.select(this).classed("hover",!0),u.elementMouseover({value:p(a,c),point:a,series:b[a.series],pos:[m(o(a,c))+m.rangeBand()*(a.series+.5)/b.length,n(p(a,c))],pointIndex:c,seriesIndex:a.series,e:d3.event})}).on("mouseout",function(a,c){d3.select(this).classed("hover",!1),u.elementMouseout({value:p(a,c),point:a,series:b[a.series],pointIndex:c,seriesIndex:a.series,e:d3.event})}).on("click",function(a,c){u.elementClick({value:p(a,c),point:a,series:b[a.series],pos:[m(o(a,c))+m.rangeBand()*(a.series+.5)/b.length,n(p(a,c))],pointIndex:c,seriesIndex:a.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(a,c){u.elementDblClick({value:p(a,c),point:a,series:b[a.series],pos:[m(o(a,c))+m.rangeBand()*(a.series+.5)/b.length,n(p(a,c))],pointIndex:c,seriesIndex:a.series,e:d3.event}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*m.rangeBand()/b.length),s?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return t(p(a,b))}).watchTransition(x,"discreteBar: bars text").attr("x",.9*m.rangeBand()/2).attr("y",function(a,b){return p(a,b)<0?n(p(a,b))-n(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return p(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||r(a,b)}).style("stroke",function(a,b){return a.color||r(a,b)}).select("rect").attr("class",v).watchTransition(x,"discreteBar: bars rect").attr("width",.9*m.rangeBand()/b.length),E.watchTransition(x,"discreteBar: bars").attr("transform",function(a,b){var c=m(o(a,b))+.05*m.rangeBand(),d=p(a,b)<0?n(0):n(0)-n(p(a,b))<1?n(0)-1:n(p(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(n(p(a,b))-n(d&&d[0]||0))||1)}),g=m.copy(),h=n.copy()}),x.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=[0],r=a.utils.defaultColor(),s=!1,t=d3.format(",.2f"),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),v="discreteBar",w=250,x=a.utils.renderWatch(u,w);return b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},forceY:{get:function(){return q},set:function(a){q=a}},showValues:{get:function(){return s},set:function(a){s=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},valueFormat:{get:function(){return t},set:function(a){t=a}},id:{get:function(){return l},set:function(a){l=a}},rectClass:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return r},set:function(b){r=a.utils.getColor(b)}},duration:{get:function(){return w},set:function(a){w=a,x.reset(w)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(k){return v.reset(),v.models(e),l&&v.models(f),m&&v.models(g),k.each(function(k){var q=d3.select(this),v=this;a.utils.initSVG(q);var w=(i||parseInt(q.style("width"))||960)-h.left-h.right,x=(j||parseInt(q.style("height"))||400)-h.top-h.bottom;if(b.update=function(){s.beforeUpdate(),q.transition().duration(t).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.length}).length)){var y=q.selectAll(".nv-noData").data([r]);return y.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),y.attr("x",h.left+w/2).attr("y",h.top+x/2).text(function(a){return a}),b}q.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var z=q.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([k]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),B=A.append("defs"),C=z.select("g");A.append("g").attr("class","nv-x nv-axis"),A.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),A.append("g").attr("class","nv-barsWrap"),C.attr("transform","translate("+h.left+","+h.top+")"),n&&C.select(".nv-y.nv-axis").attr("transform","translate("+w+",0)"),e.width(w).height(x);var D=C.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(D.transition().call(e),B.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),C.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(w/100,k)).tickSize(-x,0),C.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),C.select(".nv-x.nv-axis").call(f);var E=C.select(".nv-x.nv-axis").selectAll("g");o&&E.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(a.utils.calcTicksY(x/36,k)).tickSize(-w,0),C.select(".nv-y.nv-axis").call(g)),C.select(".nv-zeroLine line").attr("x1",0).attr("x2",w).attr("y1",d(0)).attr("y2",d(0)),s.on("tooltipShow",function(a){p&&u(a,v.parentNode)})}),v.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=!0,q=function(a,b,c){return"<h3>"+b+"</h3><p>"+c+"</p>"},r="No Data Available.",s=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),t=250;f.orient("bottom").highlightZero(!1).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f"));var u=function(c,d){var h=c.pos[0]+(d.offsetLeft||0),i=c.pos[1]+(d.offsetTop||0),j=f.tickFormat()(e.x()(c.point,c.pointIndex)),k=g.tickFormat()(e.y()(c.point,c.pointIndex)),l=q(c.series.key,j,k,c,b);a.tooltip.show([h,i],l,c.value<0?"n":"s",null,d)},v=a.utils.renderWatch(s,t);return e.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+h.left,a.pos[1]+h.top],s.tooltipShow(a)}),e.dispatch.on("elementMouseout.tooltip",function(a){s.tooltipHide(a)}),s.on("tooltipHide",function(){p&&a.tooltip.cleanup()}),b.dispatch=s,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return p},set:function(a){p=a}},tooltipContent:{get:function(){return q},set:function(a){q=a}},noData:{get:function(){return r},set:function(a){r=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t),e.duration(t),f.duration(t),g.duration(t)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.historicalBar=function(){"use strict";function b(w){return w.each(function(b){v.reset();var w=d3.select(this),x=(h||parseInt(w.style("width"))||960)-g.left-g.right,y=(i||parseInt(w.style("height"))||400)-g.top-g.bottom;a.utils.initSVG(w),k.domain(c||d3.extent(b[0].values.map(m).concat(o))),k.range(q?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),l.domain(d||d3.extent(b[0].values.map(n).concat(p))).range(f||[y,0]),k.domain()[0]===k.domain()[1]&&k.domain(k.domain()[0]?[k.domain()[0]-.01*k.domain()[0],k.domain()[1]+.01*k.domain()[1]]:[-1,1]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]+.01*l.domain()[0],l.domain()[1]-.01*l.domain()[1]]:[-1,1]);var z=w.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),w.on("click",function(a,b){t.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",r?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return m(a,b)});E.exit().remove();E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(l(Math.max(0,n(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(l(n(b,c))-l(0)))}).attr("transform",function(a,c){return"translate("+(k(m(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,c){u&&(d3.select(this).classed("hover",!0),t.elementMouseover({point:a,series:b[0],pos:[k(m(a,c)),l(n(a,c))],pointIndex:c,seriesIndex:0,e:d3.event}))}).on("mouseout",function(a,c){u&&(d3.select(this).classed("hover",!1),t.elementMouseout({point:a,series:b[0],pointIndex:c,seriesIndex:0,e:d3.event}))}).on("click",function(a,b){u&&(t.elementClick({value:n(a,b),data:a,index:b,pos:[k(m(a,b)),l(n(a,b))],e:d3.event,id:j}),d3.event.stopPropagation())}).on("dblclick",function(a,b){u&&(t.elementDblClick({value:n(a,b),data:a,index:b,pos:[k(m(a,b)),l(n(a,b))],e:d3.event,id:j}),d3.event.stopPropagation())});E.attr("fill",function(a,b){return s(a,b)}).attr("class",function(a,b,c){return(n(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(v,"bars").attr("transform",function(a,c){return"translate("+(k(m(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(v,"bars").attr("y",function(b,c){var d=n(b,c)<0?l(0):l(0)-l(n(b,c))<1?l(0)-1:l(n(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(l(n(b,c))-l(0)),1))})}),v.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=d3.scale.linear(),l=d3.scale.linear(),m=function(a){return a.x},n=function(a){return a.y},o=[],p=[0],q=!1,r=!0,s=a.utils.defaultColor(),t=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),u=!0,v=a.utils.renderWatch(t,0);return b.highlightPoint=function(a,b){d3.select(".nv-historicalBar-"+j).select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){d3.select(".nv-historicalBar-"+j).select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=t,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return o},set:function(a){o=a}},forceY:{get:function(){return p},set:function(a){p=a}},padData:{get:function(){return q},set:function(a){q=a}},x:{get:function(){return m},set:function(a){m=a}},y:{get:function(){return n},set:function(a){n=a}},xScale:{get:function(){return k},set:function(a){k=a}},yScale:{get:function(){return l},set:function(a){l=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return r},set:function(a){r=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return u},set:function(a){u=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(u){B.reset(),B.models(f),p&&B.models(g),q&&B.models(h);var C=d3.select(this),D=this;a.utils.initSVG(C);var E=(m||parseInt(C.style("width"))||960)-k.left-k.right,F=(n||parseInt(C.style("height"))||400)-k.top-k.bottom;if(c.update=function(){C.transition().duration(z).call(c)},c.container=this,v.disabled=u.map(function(a){return!!a.disabled}),!w){var G;w={};for(G in v)w[G]=v[G]instanceof Array?v[G].slice(0):v[G]}if(!(u&&u.length&&u.filter(function(a){return a.values.length}).length)){var H=C.selectAll(".nv-noData").data([x]);return H.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),H.attr("x",k.left+E/2).attr("y",k.top+F/2).text(function(a){return a}),c}C.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var I=C.selectAll("g.nv-wrap.nv-historicalBarChart").data([u]),J=I.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),K=I.select("g");J.append("g").attr("class","nv-x nv-axis"),J.append("g").attr("class","nv-y nv-axis"),J.append("g").attr("class","nv-barsWrap"),J.append("g").attr("class","nv-legendWrap"),J.append("g").attr("class","nv-interactive"),o&&(i.width(E),K.select(".nv-legendWrap").datum(u).call(i),k.top!=i.height()&&(k.top=i.height(),F=(n||parseInt(C.style("height"))||400)-k.top-k.bottom),I.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),I.attr("transform","translate("+k.left+","+k.top+")"),r&&K.select(".nv-y.nv-axis").attr("transform","translate("+E+",0)"),s&&(j.width(E).height(F).margin({left:k.left,top:k.top}).svgContainer(C).xScale(d),I.select(".nv-interactive").call(j)),f.width(E).height(F).color(u.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!u[b].disabled}));var L=K.select(".nv-barsWrap").datum(u.filter(function(a){return!a.disabled}));L.transition().call(f),p&&(g.scale(d).tickSize(-F,0),K.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),K.select(".nv-x.nv-axis").transition().call(g)),q&&(h.scale(e).ticks(a.utils.calcTicksY(F/36,u)).tickSize(-E,0),K.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,m=[];u.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];"undefined"!=typeof h&&("undefined"==typeof d&&(d=h),"undefined"==typeof i&&(i=c.xScale()(c.x()(h,e))),m.push({key:g.key,value:c.y()(h,e),color:l(g,g.seriesIndex),data:g.values[e]}))});var n=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+k.left,top:b.mouseY+k.top}).chartContainer(D.parentNode).enabled(t).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:n,series:m})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){y.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,u.filter(function(a){return!a.disabled}).length||u.map(function(a){return a.disabled=!1,I.selectAll(".nv-series").classed("disabled",!1),a}),v.disabled=u.map(function(a){return!!a.disabled}),y.stateChange(v),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){u.forEach(function(a){a.disabled=!0}),a.disabled=!1,v.disabled=u.map(function(a){return!!a.disabled}),y.stateChange(v),c.update()}),y.on("tooltipShow",function(a){t&&A(a,D.parentNode)}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(u.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),c.update()})}),B.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k={top:30,right:90,bottom:50,left:90},l=a.utils.defaultColor(),m=null,n=null,o=!1,p=!0,q=!0,r=!1,s=!1,t=!0,u=function(a,b,c){return"<h3>"+a+"</h3><p>"+c+" at "+b+"</p>"},v={},w=null,x="No Data Available.",y=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),z=250;g.orient("bottom").tickPadding(7),h.orient(r?"right":"left");var A=function(b,d){if(d){var e=d3.select(d).select("svg"),i=e.node()?e.attr("viewBox"):null;if(i){i=i.split(" ");var j=parseInt(e.style("width"))/i[2];b.pos[0]=b.pos[0]*j,b.pos[1]=b.pos[1]*j}}var k=b.pos[0]+(d.offsetLeft||0),l=b.pos[1]+(d.offsetTop||0),m=g.tickFormat()(f.x()(b.point,b.pointIndex)),n=h.tickFormat()(f.y()(b.point,b.pointIndex)),o=u(b.series.key,m,n,b,c);a.tooltip.show([k,l],o,null,null,d)},B=a.utils.renderWatch(y,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+k.left,a.pos[1]+k.top],y.tooltipShow(a)}),f.dispatch.on("elementMouseout.tooltip",function(a){y.tooltipHide(a)}),y.on("tooltipHide",function(){t&&a.tooltip.cleanup()}),c.dispatch=y,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return t},set:function(a){t=a}},tooltipContent:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),i.color(l),f.color(l)}},duration:{get:function(){return z},set:function(a){z=a,B.reset(z),h.duration(z),g.duration(z)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.legend=function(){"use strict";function b(m){return m.each(function(b){var m=d-c.left-c.right,n=d3.select(this);a.utils.initSVG(n);var o=n.selectAll("g.nv-legend").data([b]),p=(o.enter().append("g").attr("class","nvd3 nv-legend").append("g"),o.select("g"));o.attr("transform","translate("+c.left+","+c.top+")");var q=p.selectAll(".nv-series").data(function(a){return a}),r=q.enter().append("g").attr("class","nv-series").on("mouseover",function(a,b){l.legendMouseover(a,b)}).on("mouseout",function(a,b){l.legendMouseout(a,b)}).on("click",function(a,c){l.legendClick(a,c),j&&(k?(b.forEach(function(a){a.disabled=!0
  19427. }),a.disabled=!1):(a.disabled=!a.disabled,b.every(function(a){return a.disabled})&&b.forEach(function(a){a.disabled=!1})),l.stateChange({disabled:b.map(function(a){return!!a.disabled})}))}).on("dblclick",function(a,c){l.legendDblclick(a,c),j&&(b.forEach(function(a){a.disabled=!0}),a.disabled=!1,l.stateChange({disabled:b.map(function(a){return!!a.disabled})}))});if(r.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),r.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8"),q.classed("nv-disabled",function(a){return a.disabled}),q.exit().remove(),q.select("circle").style("fill",function(a,b){return a.color||g(a,b)}).style("stroke",function(a,b){return a.color||g(a,b)}),q.select("text").text(f),h){var s=[];q.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}s.push(b+28)});for(var t=0,u=0,v=[];m>u&&t<s.length;)v[t]=s[t],u+=s[t++];for(0===t&&(t=1);u>m&&t>1;){v=[],t--;for(var w=0;w<s.length;w++)s[w]>(v[w%t]||0)&&(v[w%t]=s[w]);u=v.reduce(function(a,b){return a+b})}for(var x=[],y=0,z=0;t>y;y++)x[y]=z,z+=v[y];q.attr("transform",function(a,b){return"translate("+x[b%t]+","+(5+20*Math.floor(b/t))+")"}),i?p.attr("transform","translate("+(d-c.right-u)+","+c.top+")"):p.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+20*Math.ceil(s.length/t)}else{var A,B=5,C=5,D=0;q.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+28;return A=C,d<c.left+c.right+A+a&&(C=A=5,B+=20),C+=a,C>D&&(D=C),"translate("+A+","+B+")"}),p.attr("transform","translate("+(d-c.right-D)+","+c.top+")"),e=c.top+c.bottom+B+15}}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.defaultColor(),h=!0,i=!0,j=!0,k=!1,l=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange");return b.dispatch=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return j},set:function(a){j=a}},radioButtonMode:{get:function(){return k},set:function(a){k=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(p){return t.reset(),t.models(e),p.each(function(b){var p=g-f.left-f.right,q=h-f.top-f.bottom,u=d3.select(this);a.utils.initSVG(u),c=e.xScale(),d=e.yScale(),r=r||c,s=s||d;var v=u.selectAll("g.nv-wrap.nv-line").data([b]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),x=w.append("defs"),y=w.append("g"),z=v.select("g");y.append("g").attr("class","nv-groups"),y.append("g").attr("class","nv-scatterWrap"),v.attr("transform","translate("+f.left+","+f.top+")"),e.width(p).height(q);var A=v.select(".nv-scatterWrap");A.call(e),x.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),v.select("#nv-edge-clip-"+e.id()+" rect").attr("width",p).attr("height",q>0?q:0),z.attr("clip-path",n?"url(#nv-edge-clip-"+e.id()+")":""),A.attr("clip-path",n?"url(#nv-edge-clip-"+e.id()+")":"");var B=v.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});B.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),B.exit().remove(),B.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return i(a,b)}).style("stroke",function(a,b){return i(a,b)}),B.watchTransition(t,"line: groups").style("stroke-opacity",1).style("fill-opacity",.5);var C=B.selectAll("path.nv-area").data(function(a){return m(a)?[a]:[]});C.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(o).defined(l).x(function(b,c){return a.utils.NaNtoZero(r(j(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(s(k(b,c)))}).y1(function(){return s(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),B.exit().selectAll("path.nv-area").remove(),C.watchTransition(t,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(o).defined(l).x(function(b,d){return a.utils.NaNtoZero(c(j(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(k(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var D=B.selectAll("path.nv-line").data(function(a){return[a.values]});D.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(o).defined(l).x(function(b,c){return a.utils.NaNtoZero(r(j(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(s(k(b,c)))})),D.watchTransition(t,"line: linePaths").attr("d",d3.svg.line().interpolate(o).defined(l).x(function(b,d){return a.utils.NaNtoZero(c(j(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(k(b,c)))})),r=c.copy(),s=d.copy()}),t.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=a.utils.defaultColor(),j=function(a){return a.x},k=function(a){return a.y},l=function(a,b){return!isNaN(k(a,b))&&null!==k(a,b)},m=function(a){return a.area},n=!1,o="linear",p=250,q=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var r,s,t=a.utils.renderWatch(q,p);return b.dispatch=q,b.scatter=e,e.dispatch.on("elementClick",function(){q.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){q.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){q.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return l},set:function(a){l=a}},interpolate:{get:function(){return o},set:function(a){o=a}},clipEdge:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return p},set:function(a){p=a,t.reset(p),e.duration(p)}},isArea:{get:function(){return m},set:function(a){m=d3.functor(a)}},x:{get:function(){return j},set:function(a){j=a,e.x(a)}},y:{get:function(){return k},set:function(a){k=a,e.y(a)}},color:{get:function(){return i},set:function(b){i=a.utils.getColor(b),e.color(i)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(t){return A.reset(),A.models(e),o&&A.models(f),p&&A.models(g),t.each(function(t){var A=d3.select(this),D=this;a.utils.initSVG(A);var E=(l||parseInt(A.style("width"))||960)-j.left-j.right,F=(m||parseInt(A.style("height"))||400)-j.top-j.bottom;if(b.update=function(){0===y?A.call(b):A.transition().duration(y).call(b)},b.container=this,u.setter(C(t),b.update).getter(B(t)).update(),u.disabled=t.map(function(a){return!!a.disabled}),!v){var G;v={};for(G in u)v[G]=u[G]instanceof Array?u[G].slice(0):u[G]}if(!(t&&t.length&&t.filter(function(a){return a.values.length}).length)){var H=A.selectAll(".nv-noData").data([w]);return H.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),H.attr("x",j.left+E/2).attr("y",j.top+F/2).text(function(a){return a}),b}A.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var I=A.selectAll("g.nv-wrap.nv-lineChart").data([t]),J=I.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),K=I.select("g");J.append("rect").style("opacity",0),J.append("g").attr("class","nv-x nv-axis"),J.append("g").attr("class","nv-y nv-axis"),J.append("g").attr("class","nv-linesWrap"),J.append("g").attr("class","nv-legendWrap"),J.append("g").attr("class","nv-interactive"),K.select("rect").attr("width",E).attr("height",F>0?F:0),n&&(h.width(E),K.select(".nv-legendWrap").datum(t).call(h),j.top!=h.height()&&(j.top=h.height(),F=(m||parseInt(A.style("height"))||400)-j.top-j.bottom),I.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")),I.attr("transform","translate("+j.left+","+j.top+")"),q&&K.select(".nv-y.nv-axis").attr("transform","translate("+E+",0)"),r&&(i.width(E).height(F).margin({left:j.left,top:j.top}).svgContainer(A).xScale(c),I.select(".nv-interactive").call(i)),e.width(E).height(F).color(t.map(function(a,b){return a.color||k(a,b)}).filter(function(a,b){return!t[b].disabled}));var L=K.select(".nv-linesWrap").datum(t.filter(function(a){return!a.disabled}));L.call(e),o&&(f.scale(c).ticks(a.utils.calcTicksX(E/100,t)).tickSize(-F,0),K.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),K.select(".nv-x.nv-axis").call(f)),p&&(g.scale(d).ticks(a.utils.calcTicksY(F/36,t)).tickSize(-E,0),K.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,l,m=[];if(t.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x()),e.highlightPoint(g,h,!0);var i=f.values[h];"undefined"!=typeof i&&("undefined"==typeof d&&(d=i),"undefined"==typeof l&&(l=b.xScale()(b.x()(i,h))),m.push({key:f.key,value:b.y()(i,h),color:k(f,f.seriesIndex)}))}),m.length>2){var n=b.yScale().invert(c.mouseY),o=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),p=.03*o,q=a.nearestValueIndex(m.map(function(a){return a.value}),n,p);null!==q&&(m[q].highlight=!0)}var r=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:l+j.left,top:c.mouseY+j.top}).chartContainer(D.parentNode).enabled(s).valueFormatter(function(a){return g.tickFormat()(a)}).data({value:r,series:m})(),i.renderGuideLine(l)}),i.dispatch.on("elementClick",function(c){var d,f=[];t.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){x.tooltipHide(),e.clearHighlights()}),x.on("tooltipShow",function(a){s&&z(a,D.parentNode)}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&t.length===a.disabled.length&&(t.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),b.update()})}),A.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j={top:30,right:20,bottom:50,left:60},k=a.utils.defaultColor(),l=null,m=null,n=!0,o=!0,p=!0,q=!1,r=!1,s=!0,t=function(a,b,c){return"<h3>"+a+"</h3><p>"+c+" at "+b+"</p>"},u=a.utils.state(),v=null,w="No Data Available.",x=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),y=250;f.orient("bottom").tickPadding(7),g.orient(q?"right":"left");var z=function(c,d){var h=c.pos[0]+(d.offsetLeft||0),i=c.pos[1]+(d.offsetTop||0),j=f.tickFormat()(e.x()(c.point,c.pointIndex)),k=g.tickFormat()(e.y()(c.point,c.pointIndex)),l=t(c.series.key,j,k,c,b);a.tooltip.show([h,i],l,null,null,d)},A=a.utils.renderWatch(x,y),B=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},C=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+j.left,a.pos[1]+j.top],x.tooltipShow(a)}),e.dispatch.on("elementMouseout.tooltip",function(a){x.tooltipHide(a)}),x.on("tooltipHide",function(){s&&a.tooltip.cleanup()}),b.dispatch=x,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.dispatch=x,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return n},set:function(a){n=a}},showXAxis:{get:function(){return o},set:function(a){o=a}},showYAxis:{get:function(){return p},set:function(a){p=a}},tooltips:{get:function(){return s},set:function(a){s=a}},tooltipContent:{get:function(){return t},set:function(a){t=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return y},set:function(a){y=a,A.reset(y),e.duration(y),f.duration(y),g.duration(y)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),h.color(k),e.color(k)}},rightAlignYAxis:{get:function(){return q},set:function(a){q=a,g.orient(q?"right":"left")}},useInteractiveGuideline:{get:function(){return r},set:function(a){r=a,r&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(J){return J.each(function(J){function U(a){var b=+("e"==a),c=b?1:-1,d=_/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function V(){u.empty()||u.extent(H),nb.data([u.empty()?e.domain():H]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function W(){H=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),L.brush({extent:c,brush:u}),V(),l.width(Z).height($).color(J.map(function(a,b){return a.color||B(a,b)}).filter(function(a,b){return!J[b].disabled&&J[b].bar})),j.width(Z).height($).color(J.map(function(a,b){return a.color||B(a,b)}).filter(function(a,b){return!J[b].disabled&&!J[b].bar}));var b=ib.select(".nv-focus .nv-barsWrap").datum(cb.length?cb.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=ib.select(".nv-focus .nv-linesWrap").datum(db[0].disabled?[{values:[]}]:db.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=cb.length?l.xScale():j.xScale(),n.scale(d).ticks(a.utils.calcTicksX(Z/100,J)).tickSize(-$,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),ib.select(".nv-x.nv-axis").transition().duration(M).call(n),b.transition().duration(M).call(l),h.transition().duration(M).call(j),ib.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f).ticks(a.utils.calcTicksY($/36,J)).tickSize(-Z,0),q.scale(g).ticks(a.utils.calcTicksY($/36,J)).tickSize(cb.length?0:-Z,0),ib.select(".nv-focus .nv-y1.nv-axis").style("opacity",cb.length?1:0),ib.select(".nv-focus .nv-y2.nv-axis").style("opacity",db.length&&!db[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),ib.select(".nv-focus .nv-y1.nv-axis").transition().duration(M).call(p),ib.select(".nv-focus .nv-y2.nv-axis").transition().duration(M).call(q)}var X=d3.select(this),Y=this;a.utils.initSVG(X);var Z=(x||parseInt(X.style("width"))||960)-v.left-v.right,$=(y||parseInt(X.style("height"))||400)-v.top-v.bottom-(D?G:0),_=G-w.top-w.bottom;if(b.update=function(){X.transition().duration(M).call(b)},b.container=this,N.setter(T(J),b.update).getter(S(J)).update(),N.disabled=J.map(function(a){return!!a.disabled}),!O){var ab;O={};for(ab in N)O[ab]=N[ab]instanceof Array?N[ab].slice(0):N[ab]}if(!(J&&J.length&&J.filter(function(a){return a.values.length}).length)){var bb=X.selectAll(".nv-noData").data([K]);return bb.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),bb.attr("x",v.left+Z/2).attr("y",v.top+$/2).text(function(a){return a}),b}X.selectAll(".nv-noData").remove();var cb=J.filter(function(a){return!a.disabled&&a.bar}),db=J.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var eb=J.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:z(a,b),y:A(a,b)}})}),fb=J.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:z(a,b),y:A(a,b)}})});d.range([0,Z]),e.domain(d3.extent(d3.merge(eb.concat(fb)),function(a){return a.x})).range([0,Z]);var gb=X.selectAll("g.nv-wrap.nv-linePlusBar").data([J]),hb=gb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),ib=gb.select("g");hb.append("g").attr("class","nv-legendWrap");var jb=hb.append("g").attr("class","nv-focus");jb.append("g").attr("class","nv-x nv-axis"),jb.append("g").attr("class","nv-y1 nv-axis"),jb.append("g").attr("class","nv-y2 nv-axis"),jb.append("g").attr("class","nv-barsWrap"),jb.append("g").attr("class","nv-linesWrap");var kb=hb.append("g").attr("class","nv-context");kb.append("g").attr("class","nv-x nv-axis"),kb.append("g").attr("class","nv-y1 nv-axis"),kb.append("g").attr("class","nv-y2 nv-axis"),kb.append("g").attr("class","nv-barsWrap"),kb.append("g").attr("class","nv-linesWrap"),kb.append("g").attr("class","nv-brushBackground"),kb.append("g").attr("class","nv-x nv-brush"),C&&(t.width(Z/2),ib.select(".nv-legendWrap").datum(J.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?P:Q),a})).call(t),v.top!=t.height()&&(v.top=t.height(),$=(y||parseInt(X.style("height"))||400)-v.top-v.bottom-G),ib.select(".nv-legendWrap").attr("transform","translate("+Z/2+","+-v.top+")")),gb.attr("transform","translate("+v.left+","+v.top+")"),ib.select(".nv-context").style("display",D?"initial":"none"),m.width(Z).height(_).color(J.map(function(a,b){return a.color||B(a,b)}).filter(function(a,b){return!J[b].disabled&&J[b].bar})),k.width(Z).height(_).color(J.map(function(a,b){return a.color||B(a,b)}).filter(function(a,b){return!J[b].disabled&&!J[b].bar}));var lb=ib.select(".nv-context .nv-barsWrap").datum(cb.length?cb:[{values:[]}]),mb=ib.select(".nv-context .nv-linesWrap").datum(db[0].disabled?[{values:[]}]:db);ib.select(".nv-context").attr("transform","translate(0,"+($+v.bottom+w.top)+")"),lb.transition().call(m),mb.transition().call(k),F&&(o.ticks(a.utils.calcTicksX(Z/100,J)).tickSize(-_,0),ib.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),ib.select(".nv-context .nv-x.nv-axis").transition().call(o)),E&&(r.scale(h).ticks(_/36).tickSize(-Z,0),s.scale(i).ticks(_/36).tickSize(cb.length?0:-Z,0),ib.select(".nv-context .nv-y3.nv-axis").style("opacity",cb.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),ib.select(".nv-context .nv-y2.nv-axis").style("opacity",db.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),ib.select(".nv-context .nv-y1.nv-axis").transition().call(r),ib.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",W),H&&u.extent(H);var nb=ib.select(".nv-brushBackground").selectAll("g").data([H||u.extent()]),ob=nb.enter().append("g");ob.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",_),ob.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",_);var pb=ib.select(".nv-x.nv-brush").call(u);pb.selectAll("rect").attr("height",_),pb.selectAll(".resize").append("path").attr("d",U),t.dispatch.on("stateChange",function(a){for(var c in a)N[c]=a[c];L.stateChange(N),b.update()}),L.on("tooltipShow",function(a){I&&R(a,Y.parentNode)}),L.on("changeState",function(a){"undefined"!=typeof a.disabled&&(J.forEach(function(b,c){b.disabled=a.disabled[c]}),N.disabled=a.disabled),b.update()}),W()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v={top:30,right:30,bottom:30,left:60},w={top:0,right:30,bottom:20,left:60},x=null,y=null,z=function(a){return a.x},A=function(a){return a.y},B=a.utils.defaultColor(),C=!0,D=!0,E=!1,F=!0,G=50,H=null,I=!0,J=function(a,b,c){return"<h3>"+a+"</h3><p>"+c+" at "+b+"</p>"},K="No Data Available.",L=d3.dispatch("tooltipShow","tooltipHide","brush","stateChange","changeState"),M=0,N=a.utils.state(),O=null,P=" (left axis)",Q=" (right axis)";j.clipEdge(!0),k.interactive(!1),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right");var R=function(d,e){c&&(d.pointIndex+=Math.ceil(c[0]));var f=d.pos[0]+(e.offsetLeft||0),g=d.pos[1]+(e.offsetTop||0),h=n.tickFormat()(j.x()(d.point,d.pointIndex)),i=(d.series.bar?p:q).tickFormat()(j.y()(d.point,d.pointIndex)),k=J(d.series.key,h,i,d,b);a.tooltip.show([f,g],k,d.value<0?"n":"s",null,e)},S=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},T=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+v.left,a.pos[1]+v.top],L.tooltipShow(a)}),j.dispatch.on("elementMouseout.tooltip",function(a){L.tooltipHide(a)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+v.left,a.pos[1]+v.top],L.tooltipShow(a)}),l.dispatch.on("elementMouseout.tooltip",function(a){L.tooltipHide(a)}),L.on("tooltipHide",function(){I&&a.tooltip.cleanup()}),b.dispatch=L,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return x},set:function(a){x=a}},height:{get:function(){return y},set:function(a){y=a}},showLegend:{get:function(){return C},set:function(a){C=a}},tooltips:{get:function(){return I},set:function(a){I=a}},tooltipContent:{get:function(){return J},set:function(a){J=a}},brushExtent:{get:function(){return H},set:function(a){H=a}},noData:{get:function(){return K},set:function(a){K=a}},focusEnable:{get:function(){return D},set:function(a){D=a}},focusHeight:{get:function(){return G},set:function(a){G=a}},focusShowAxisX:{get:function(){return F},set:function(a){F=a}},focusShowAxisY:{get:function(){return E},set:function(a){E=a}},legendLeftAxisHint:{get:function(){return P},set:function(a){P=a}},legendRightAxisHint:{get:function(){return Q},set:function(a){Q=a}},margin:{get:function(){return v},set:function(a){v.top=void 0!==a.top?a.top:v.top,v.right=void 0!==a.right?a.right:v.right,v.bottom=void 0!==a.bottom?a.bottom:v.bottom,v.left=void 0!==a.left?a.left:v.left}},duration:{get:function(){return M},set:function(a){M=a}},color:{get:function(){return B},set:function(b){B=a.utils.getColor(b),t.color(B)}},x:{get:function(){return z},set:function(a){z=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return A},set:function(a){A=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(x){return x.each(function(x){function G(a){var b=+("e"==a),c=b?1:-1,d=N/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function H(){n.empty()||n.extent(v),W.data([n.empty()?e.domain():v]).each(function(a){var b=e(a[0])-c.range()[0],d=c.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function I(){v=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){z.brush({extent:a,brush:n}),H();var b=S.select(".nv-focus .nv-linesWrap").datum(x.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(A).call(g),S.select(".nv-focus .nv-x.nv-axis").transition().duration(A).call(i),S.select(".nv-focus .nv-y.nv-axis").transition().duration(A).call(j)}}var J=d3.select(this),K=this;a.utils.initSVG(J);var L=(r||parseInt(J.style("width"))||960)-o.left-o.right,M=(s||parseInt(J.style("height"))||400)-o.top-o.bottom-t,N=t-p.top-p.bottom;if(b.update=function(){J.transition().duration(A).call(b)},b.container=this,B.setter(F(x),b.update).getter(E(x)).update(),B.disabled=x.map(function(a){return!!a.disabled}),!C){var O;C={};for(O in B)C[O]=B[O]instanceof Array?B[O].slice(0):B[O]}if(!(x&&x.length&&x.filter(function(a){return a.values.length}).length)){var P=J.selectAll(".nv-noData").data([y]);return P.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),P.attr("x",o.left+L/2).attr("y",o.top+M/2).text(function(a){return a}),b}J.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var Q=J.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([x]),R=Q.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),S=Q.select("g");R.append("g").attr("class","nv-legendWrap");var T=R.append("g").attr("class","nv-focus");T.append("g").attr("class","nv-x nv-axis"),T.append("g").attr("class","nv-y nv-axis"),T.append("g").attr("class","nv-linesWrap");var U=R.append("g").attr("class","nv-context");U.append("g").attr("class","nv-x nv-axis"),U.append("g").attr("class","nv-y nv-axis"),U.append("g").attr("class","nv-linesWrap"),U.append("g").attr("class","nv-brushBackground"),U.append("g").attr("class","nv-x nv-brush"),u&&(m.width(L),S.select(".nv-legendWrap").datum(x).call(m),o.top!=m.height()&&(o.top=m.height(),M=(s||parseInt(J.style("height"))||400)-o.top-o.bottom-t),S.select(".nv-legendWrap").attr("transform","translate(0,"+-o.top+")")),Q.attr("transform","translate("+o.left+","+o.top+")"),g.width(L).height(M).color(x.map(function(a,b){return a.color||q(a,b)}).filter(function(a,b){return!x[b].disabled})),h.defined(g.defined()).width(L).height(N).color(x.map(function(a,b){return a.color||q(a,b)}).filter(function(a,b){return!x[b].disabled})),S.select(".nv-context").attr("transform","translate(0,"+(M+o.bottom+p.top)+")");var V=S.select(".nv-context .nv-linesWrap").datum(x.filter(function(a){return!a.disabled}));d3.transition(V).call(h),i.scale(c).ticks(a.utils.calcTicksX(L/100,x)).tickSize(-M,0),j.scale(d).ticks(a.utils.calcTicksY(M/36,x)).tickSize(-L,0),S.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+M+")"),n.x(e).on("brush",function(){var a=b.duration();b.duration(0),I(),b.duration(a)}),v&&n.extent(v);var W=S.select(".nv-brushBackground").selectAll("g").data([v||n.extent()]),X=W.enter().append("g");X.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",N),X.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",N);var Y=S.select(".nv-x.nv-brush").call(n);Y.selectAll("rect").attr("height",N),Y.selectAll(".resize").append("path").attr("d",G),I(),k.scale(e).ticks(a.utils.calcTicksX(L/100,x)).tickSize(-N,0),S.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(S.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f).ticks(a.utils.calcTicksY(N/36,x)).tickSize(-L,0),d3.transition(S.select(".nv-context .nv-y.nv-axis")).call(l),S.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)B[c]=a[c];z.stateChange(B),b.update()}),z.on("tooltipShow",function(a){w&&D(a,K.parentNode)}),z.on("changeState",function(a){"undefined"!=typeof a.disabled&&x.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o={top:30,right:30,bottom:30,left:60},p={top:0,right:30,bottom:20,left:60},q=a.utils.defaultColor(),r=null,s=null,t=100,u=!0,v=null,w=!0,x=function(a,b,c){return"<h3>"+a+"</h3><p>"+c+" at "+b+"</p>"},y="No Data Available.",z=d3.dispatch("tooltipShow","tooltipHide","brush","stateChange","changeState"),A=250,B=a.utils.state(),C=null;g.clipEdge(!0),h.interactive(!1),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left");var D=function(c,d){var e=c.pos[0]+(d.offsetLeft||0),f=c.pos[1]+(d.offsetTop||0),h=i.tickFormat()(g.x()(c.point,c.pointIndex)),k=j.tickFormat()(g.y()(c.point,c.pointIndex)),l=x(c.series.key,h,k,c,b);a.tooltip.show([e,f],l,null,null,d)},E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+o.left,a.pos[1]+o.top],z.tooltipShow(a)}),g.dispatch.on("elementMouseout.tooltip",function(a){z.tooltipHide(a)}),z.on("tooltipHide",function(){w&&a.tooltip.cleanup()}),b.dispatch=z,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return r},set:function(a){r=a}},height:{get:function(){return s},set:function(a){s=a}},focusHeight:{get:function(){return t},set:function(a){t=a}},showLegend:{get:function(){return u},set:function(a){u=a}},brushExtent:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return w},set:function(a){w=a}},tooltipContent:{get:function(){return x},set:function(a){x=a}},defaultState:{get:function(){return C},set:function(a){C=a}},noData:{get:function(){return y},set:function(a){y=a}},margin:{get:function(){return o},set:function(a){o.top=void 0!==a.top?a.top:o.top,o.right=void 0!==a.right?a.right:o.right,o.bottom=void 0!==a.bottom?a.bottom:o.bottom,o.left=void 0!==a.left?a.left:o.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b),m.color(q)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.xTickFormat()},set:function(a){i.xTickFormat(a),k.xTickFormat(a)}},yTickFormat:{get:function(){return j.yTickFormat()},set:function(a){j.yTickFormat(a),l.yTickFormat(a)}},duration:{get:function(){return A},set:function(a){A=a,j.duration(A),i.duration(A)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(D){return B.reset(),D.each(function(b){var D=k-j.left-j.right,E=l-j.top-j.bottom,F=d3.select(this);a.utils.initSVG(F);w&&b.length&&(w=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),t&&(b=d3.layout.stack().offset(u).values(function(a){return a.values}).y(q)(!b.length&&w?w:b)),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})}),t&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e,e-=b.size):(b.y1=b.size+d,d+=b.size)})});var G=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0,y1:a.y1}})});m.domain(d||d3.merge(G).map(function(a){return a.x})).rangeBands(f||[0,D],z),n.domain(e||d3.extent(d3.merge(G).map(function(a){return t?a.y>0?a.y1:a.y1+a.y:a.y
  19428. }).concat(r))).range(g||[E,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var H=F.selectAll("g.nv-wrap.nv-multibar").data([b]),I=H.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),J=I.append("defs"),K=I.append("g"),L=H.select("g");K.append("g").attr("class","nv-groups"),H.attr("transform","translate("+j.left+","+j.top+")"),J.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),H.select("#nv-edge-clip-"+o+" rect").attr("width",D).attr("height",E),L.attr("clip-path",s?"url(#nv-edge-clip-"+o+")":"");var M=H.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});M.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var N=B.transition(M.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,y)).attr("y",function(a){return i(t?a.y0:0)||0}).attr("height",0).remove();N.delay&&N.delay(function(a,b){var c=b*(y/(C+1))-b;return c}),M.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return v(a,b)}).style("stroke",function(a,b){return v(a,b)}),M.style("stroke-opacity",1).style("fill-opacity",.75);var O=M.selectAll("rect.nv-bar").data(function(a){return w&&!b.length?w.values:a.values});O.exit().remove();O.enter().append("rect").attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return t?0:d*m.rangeBand()/b.length}).attr("y",function(a){return i(t?a.y0:0)||0}).attr("height",0).attr("width",m.rangeBand()/(t?1:b.length)).attr("transform",function(a,b){return"translate("+m(p(a,b))+",0)"});O.style("fill",function(a,b,c){return v(a,c,b)}).style("stroke",function(a,b,c){return v(a,c,b)}).on("mouseover",function(a,c){d3.select(this).classed("hover",!0),A.elementMouseover({value:q(a,c),point:a,series:b[a.series],pos:[m(p(a,c))+m.rangeBand()*(t?b.length/2:a.series+.5)/b.length,n(q(a,c)+(t?a.y0:0))],pointIndex:c,seriesIndex:a.series,e:d3.event})}).on("mouseout",function(a,c){d3.select(this).classed("hover",!1),A.elementMouseout({value:q(a,c),point:a,series:b[a.series],pointIndex:c,seriesIndex:a.series,e:d3.event})}).on("click",function(a,c){A.elementClick({value:q(a,c),point:a,series:b[a.series],pos:[m(p(a,c))+m.rangeBand()*(t?b.length/2:a.series+.5)/b.length,n(q(a,c)+(t?a.y0:0))],pointIndex:c,seriesIndex:a.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(a,c){A.elementDblClick({value:q(a,c),point:a,series:b[a.series],pos:[m(p(a,c))+m.rangeBand()*(t?b.length/2:a.series+.5)/b.length,n(q(a,c)+(t?a.y0:0))],pointIndex:c,seriesIndex:a.series,e:d3.event}),d3.event.stopPropagation()}),O.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(p(a,b))+",0)"}),x&&(c||(c=b.map(function(){return!0})),O.style("fill",function(a,b,d){return d3.rgb(x(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(x(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var P=O.watchTransition(B,"multibar",Math.min(250,y)).delay(function(a,c){return c*y/b[0].values.length});t?P.attr("y",function(a){return n(t?a.y1:0)}).attr("height",function(a){return Math.max(Math.abs(n(a.y+(t?a.y0:0))-n(t?a.y0:0)),1)}).attr("x",function(a){return t?0:a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/(t?1:b.length)):P.attr("x",function(a){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return q(a,b)<0?n(0):n(0)-n(q(a,b))<1?n(0)-1:n(q(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(q(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(C=b[0].values.length)}),B.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=!0,t=!1,u="zero",v=a.utils.defaultColor(),w=!1,x=null,y=500,z=.1,A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),B=a.utils.renderWatch(A,y),C=0;return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return r},set:function(a){r=a}},stacked:{get:function(){return t},set:function(a){t=a}},stackOffset:{get:function(){return u},set:function(a){u=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return w},set:function(a){w=a}},groupSpacing:{get:function(){return z},set:function(a){z=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return y},set:function(a){y=a,B.reset(y)}},color:{get:function(){return v},set:function(b){v=a.utils.getColor(b)}},barColor:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(x){return E.reset(),E.models(e),q&&E.models(f),r&&E.models(g),x.each(function(x){var E=d3.select(this),J=this;a.utils.initSVG(E);var K=(k||parseInt(E.style("width"))||960)-j.left-j.right,L=(l||parseInt(E.style("height"))||400)-j.top-j.bottom;if(b.update=function(){0===D?E.call(b):E.transition().duration(D).call(b)},b.container=this,y.setter(I(x),b.update).getter(H(x)).update(),y.disabled=x.map(function(a){return!!a.disabled}),!z){var M;z={};for(M in y)z[M]=y[M]instanceof Array?y[M].slice(0):y[M]}if(!(x&&x.length&&x.filter(function(a){return a.values.length}).length)){var N=E.selectAll(".nv-noData").data([A]);return N.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),N.attr("x",j.left+K/2).attr("y",j.top+L/2).text(function(a){return a}),b}E.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var O=E.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([x]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),Q=O.select("g");if(P.append("g").attr("class","nv-x nv-axis"),P.append("g").attr("class","nv-y nv-axis"),P.append("g").attr("class","nv-barsWrap"),P.append("g").attr("class","nv-legendWrap"),P.append("g").attr("class","nv-controlsWrap"),p&&(h.width(K-C()),e.barColor()&&x.forEach(function(a,b){a.color=d3.rgb("#ccc").darker(1.5*b).toString()}),Q.select(".nv-legendWrap").datum(x).call(h),j.top!=h.height()&&(j.top=h.height(),L=(l||parseInt(E.style("height"))||400)-j.top-j.bottom),Q.select(".nv-legendWrap").attr("transform","translate("+C()+","+-j.top+")")),n){var R=[{key:o.grouped||"Grouped",disabled:e.stacked()},{key:o.stacked||"Stacked",disabled:!e.stacked()}];i.width(C()).color(["#444","#444","#444"]),Q.select(".nv-controlsWrap").datum(R).attr("transform","translate(0,"+-j.top+")").call(i)}O.attr("transform","translate("+j.left+","+j.top+")"),s&&Q.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),e.disabled(x.map(function(a){return a.disabled})).width(K).height(L).color(x.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!x[b].disabled}));var S=Q.select(".nv-barsWrap").datum(x.filter(function(a){return!a.disabled}));if(S.call(e),q){f.scale(c).ticks(a.utils.calcTicksX(K/100,x)).tickSize(-L,0),Q.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),Q.select(".nv-x.nv-axis").call(f);var T=Q.select(".nv-x.nv-axis > g").selectAll("g");if(T.selectAll("line, text").style("opacity",1),u){var U=function(a,b){return"translate("+a+","+b+")"},V=5,W=17;T.selectAll("text").attr("transform",function(a,b,c){return U(0,c%2==0?V:W)});var X=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;Q.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return U(0,0===b||X%2!==0?W:V)})}t&&T.filter(function(a,b){return b%Math.ceil(x[0].values.length/(K/100))!==0}).selectAll("text, line").style("opacity",0),v&&T.selectAll(".tick text").attr("transform","rotate("+v+" 0,0)").style("text-anchor",v>0?"start":"end"),Q.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}r&&(g.scale(d).ticks(a.utils.calcTicksY(L/36,x)).tickSize(-K,0),Q.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];B.stateChange(y),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}y.stacked=e.stacked(),B.stateChange(y),b.update()}}),B.on("tooltipShow",function(a){w&&G(a,J.parentNode)}),B.on("changeState",function(a){"undefined"!=typeof a.disabled&&(x.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),y.stacked=a.stacked,F=a.stacked),b.update()})}),E.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j={top:30,right:20,bottom:50,left:60},k=null,l=null,m=a.utils.defaultColor(),n=!0,o={},p=!0,q=!0,r=!0,s=!1,t=!0,u=!1,v=0,w=!0,x=function(a,b,c){return"<h3>"+a+"</h3><p>"+c+" on "+b+"</p>"},y=a.utils.state(),z=null,A="No Data Available.",B=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),C=function(){return n?180:0},D=250;y.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).highlightZero(!0).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(s?"right":"left").tickFormat(d3.format(",.1f")),i.updateState(!1);var E=a.utils.renderWatch(B),F=!1,G=function(c,d){var h=c.pos[0]+(d.offsetLeft||0),i=c.pos[1]+(d.offsetTop||0),j=f.tickFormat()(e.x()(c.point,c.pointIndex)),k=g.tickFormat()(e.y()(c.point,c.pointIndex)),l=x(c.series.key,j,k,c,b);a.tooltip.show([h,i],l,c.value<0?"n":"s",null,d)},H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:F}}},I=function(a){return function(b){void 0!==b.stacked&&(F=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+j.left,a.pos[1]+j.top],B.tooltipShow(a)}),e.dispatch.on("elementMouseout.tooltip",function(a){B.tooltipHide(a)}),B.on("tooltipHide",function(){w&&a.tooltip.cleanup()}),b.dispatch=B,b.multibar=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.state=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showControls:{get:function(){return n},set:function(a){n=a}},controlLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},tooltips:{get:function(){return w},set:function(a){w=a}},tooltipContent:{get:function(){return x},set:function(a){x=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},reduceXTicks:{get:function(){return t},set:function(a){t=a}},rotateLabels:{get:function(){return v},set:function(a){v=a}},staggerLabels:{get:function(){return u},set:function(a){u=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return D},set:function(a){D=a,e.duration(D),f.duration(D),g.duration(D),E.reset(D)}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),h.color(m)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,g.orient(s?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return C.reset(),m.each(function(b){var m=k-j.left-j.right,A=l-j.top-j.bottom,D=d3.select(this);a.utils.initSVG(D),v&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(q)(b)),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})}),v&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var E=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0,y1:a.y1}})});n.domain(d||d3.merge(E).map(function(a){return a.x})).rangeBands(f||[0,A],.1),o.domain(e||d3.extent(d3.merge(E).map(function(a){return v?a.y>0?a.y1+a.y:a.y1:a.y}).concat(s))),o.range(w&&!v?g||[o.domain()[0]<0?y:0,m-(o.domain()[1]>0?y:0)]:g||[0,m]),h=h||n,i=i||d3.scale.linear().domain(o.domain()).range([o(0),o(0)]);{var F=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),H=(G.append("defs"),G.append("g"));F.select("g")}H.append("g").attr("class","nv-groups"),F.attr("transform","translate("+j.left+","+j.top+")");var I=F.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});I.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),I.exit().watchTransition(C,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),I.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return t(a,b)}).style("stroke",function(a,b){return t(a,b)}),I.watchTransition(C,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var J=I.selectAll("g.nv-bar").data(function(a){return a.values});J.exit().remove();var K=J.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(v?a.y0:0)+","+(v?0:d*n.rangeBand()/b.length+n(p(a,c)))+")"});K.append("rect").attr("width",0).attr("height",n.rangeBand()/(v?1:b.length)),J.on("mouseover",function(a,c){d3.select(this).classed("hover",!0),B.elementMouseover({value:q(a,c),point:a,series:b[a.series],pos:[o(q(a,c)+(v?a.y0:0)),n(p(a,c))+n.rangeBand()*(v?b.length/2:a.series+.5)/b.length],pointIndex:c,seriesIndex:a.series,e:d3.event})}).on("mouseout",function(a,c){d3.select(this).classed("hover",!1),B.elementMouseout({value:q(a,c),point:a,series:b[a.series],pointIndex:c,seriesIndex:a.series,e:d3.event})}).on("click",function(a,c){B.elementClick({value:q(a,c),point:a,series:b[a.series],pos:[n(p(a,c))+n.rangeBand()*(v?b.length/2:a.series+.5)/b.length,o(q(a,c)+(v?a.y0:0))],pointIndex:c,seriesIndex:a.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(a,c){B.elementDblClick({value:q(a,c),point:a,series:b[a.series],pos:[n(p(a,c))+n.rangeBand()*(v?b.length/2:a.series+.5)/b.length,o(q(a,c)+(v?a.y0:0))],pointIndex:c,seriesIndex:a.series,e:d3.event}),d3.event.stopPropagation()}),r(b[0],0)&&(K.append("polyline"),J.select("polyline").attr("fill","none").attr("points",function(a,c){var d=r(a,c),e=.8*n.rangeBand()/(2*(v?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return o(a)-o(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=n.rangeBand()/(2*(v?1:b.length));return"translate("+(q(a,c)<0?0:o(q(a,c))-o(0))+", "+d+")"})),K.append("text"),w&&!v?(J.select("text").attr("text-anchor",function(a,b){return q(a,b)<0?"end":"start"}).attr("y",n.rangeBand()/(2*b.length)).attr("dy",".32em").html(function(a,b){var c=z(q(a,b)),d=r(a,b);return void 0===d?c:d.length?c+"+"+z(Math.abs(d[1]))+"-"+z(Math.abs(d[0])):c+"&plusmn;"+z(Math.abs(d))}),J.watchTransition(C,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return q(a,b)<0?-4:o(q(a,b))-o(0)+4})):J.selectAll("text").text(""),x&&!v?(K.append("text").classed("nv-bar-label",!0),J.select("text.nv-bar-label").attr("text-anchor",function(a,b){return q(a,b)<0?"start":"end"}).attr("y",n.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return p(a,b)}),J.watchTransition(C,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return q(a,b)<0?o(0)-o(q(a,b))+4:-4})):J.selectAll("text.nv-bar-label").text(""),J.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}),u&&(c||(c=b.map(function(){return!0})),J.style("fill",function(a,b,d){return d3.rgb(u(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(u(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),v?J.watchTransition(C,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+o(a.y1)+","+n(p(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(o(q(a,b)+a.y0)-o(a.y0))}).attr("height",n.rangeBand()):J.watchTransition(C,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+o(q(a,c)<0?q(a,c):0)+","+(a.series*n.rangeBand()/b.length+n(p(a,c)))+")"}).select("rect").attr("height",n.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(0)),1)}),h=n.copy(),i=o.copy()}),C.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.yErr},s=[0],t=a.utils.defaultColor(),u=null,v=!1,w=!1,x=!1,y=60,z=d3.format(",.2f"),A=250,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),C=a.utils.renderWatch(B,A);return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},yErr:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return v},set:function(a){v=a}},showValues:{get:function(){return w},set:function(a){w=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return z},set:function(a){z=a}},valuePadding:{get:function(){return y},set:function(a){y=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return A},set:function(a){A=a,C.reset(A)}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}},barColor:{get:function(){return t},set:function(b){u=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(u){return E.reset(),E.models(e),q&&E.models(f),r&&E.models(g),u.each(function(u){var E=d3.select(this),F=this;a.utils.initSVG(E);var G=(k||parseInt(E.style("width"))||960)-j.left-j.right,H=(l||parseInt(E.style("height"))||400)-j.top-j.bottom;if(b.update=function(){E.transition().duration(A).call(b)},b.container=this,s=e.stacked(),v.setter(D(u),b.update).getter(C(u)).update(),v.disabled=u.map(function(a){return!!a.disabled}),!w){var I;w={};for(I in v)w[I]=v[I]instanceof Array?v[I].slice(0):v[I]}if(!(u&&u.length&&u.filter(function(a){return a.values.length}).length)){var J=E.selectAll(".nv-noData").data([x]);return J.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),J.attr("x",j.left+G/2).attr("y",j.top+H/2).text(function(a){return a}),b}E.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var K=E.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([u]),L=K.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),M=K.select("g");if(L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),L.append("g").attr("class","nv-barsWrap"),L.append("g").attr("class","nv-legendWrap"),L.append("g").attr("class","nv-controlsWrap"),p&&(h.width(G-z()),e.barColor()&&u.forEach(function(a,b){a.color=d3.rgb("#ccc").darker(1.5*b).toString()}),M.select(".nv-legendWrap").datum(u).call(h),j.top!=h.height()&&(j.top=h.height(),H=(l||parseInt(E.style("height"))||400)-j.top-j.bottom),M.select(".nv-legendWrap").attr("transform","translate("+z()+","+-j.top+")")),n){var N=[{key:o.grouped||"Grouped",disabled:e.stacked()},{key:o.stacked||"Stacked",disabled:!e.stacked()}];i.width(z()).color(["#444","#444","#444"]),M.select(".nv-controlsWrap").datum(N).attr("transform","translate(0,"+-j.top+")").call(i)}K.attr("transform","translate("+j.left+","+j.top+")"),e.disabled(u.map(function(a){return a.disabled})).width(G).height(H).color(u.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!u[b].disabled}));var O=M.select(".nv-barsWrap").datum(u.filter(function(a){return!a.disabled}));if(O.transition().call(e),q){f.scale(c).ticks(a.utils.calcTicksY(H/24,u)).tickSize(-G,0),M.select(".nv-x.nv-axis").call(f);var P=M.select(".nv-x.nv-axis").selectAll("g");P.selectAll("line, text")}r&&(g.scale(d).ticks(a.utils.calcTicksX(G/100,u)).tickSize(-H,0),M.select(".nv-y.nv-axis").attr("transform","translate(0,"+H+")"),M.select(".nv-y.nv-axis").call(g)),M.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-H),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(N=N.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}v.stacked=e.stacked(),y.stateChange(v),s=e.stacked(),b.update()}}),y.on("tooltipShow",function(a){t&&B(a,F.parentNode)}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(u.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),v.stacked=a.stacked,s=a.stacked),b.update()})}),E.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j={top:30,right:20,bottom:50,left:60},k=null,l=null,m=a.utils.defaultColor(),n=!0,o={},p=!0,q=!0,r=!0,s=!1,t=!0,u=function(a,b,c){return"<h3>"+a+" - "+b+"</h3><p>"+c+"</p>"},v=a.utils.state(),w=null,x="No Data Available.",y=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),z=function(){return n?180:0},A=250;v.stacked=!1,e.stacked(s),f.orient("left").tickPadding(5).highlightZero(!1).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),i.updateState(!1);var B=function(c,d){var h=c.pos[0]+(d.offsetLeft||0),i=c.pos[1]+(d.offsetTop||0),j=f.tickFormat()(e.x()(c.point,c.pointIndex)),k=g.tickFormat()(e.y()(c.point,c.pointIndex)),l=u(c.series.key,j,k,c,b);a.tooltip.show([h,i],l,c.value<0?"e":"w",null,d)},C=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:s}}},D=function(a){return function(b){void 0!==b.stacked&&(s=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},E=a.utils.renderWatch(y,A);return e.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+j.left,a.pos[1]+j.top],y.tooltipShow(a)}),e.dispatch.on("elementMouseout.tooltip",function(a){y.tooltipHide(a)}),y.on("tooltipHide",function(){t&&a.tooltip.cleanup()}),b.dispatch=y,b.multibar=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.state=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showControls:{get:function(){return n},set:function(a){n=a}},controlLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},tooltips:{get:function(){return t},set:function(a){t=a}},tooltipContent:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return A},set:function(a){A=a,E.reset(A),e.duration(A),f.duration(A),g.duration(A)}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),h.color(m)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(l){return l.each(function(l){var n=d3.select(this),o=this;a.utils.initSVG(n),b.update=function(){n.transition().call(b)},b.container=this;var E=(h||parseInt(n.style("width"))||960)-f.left-f.right,F=(i||parseInt(n.style("height"))||400)-f.top-f.bottom,G=l.filter(function(a){return"line"==a.type&&1==a.yAxis}),H=l.filter(function(a){return"line"==a.type&&2==a.yAxis}),I=l.filter(function(a){return"bar"==a.type&&1==a.yAxis}),J=l.filter(function(a){return"bar"==a.type&&2==a.yAxis}),K=l.filter(function(a){return"area"==a.type&&1==a.yAxis}),L=l.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length)){var M=n.selectAll(".nv-noData").data([m]);return M.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),M.attr("x",f.left+E/2).attr("y",f.top+F/2).text(function(a){return a}),b}n.selectAll(".nv-noData").remove();var N=l.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),O=l.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});c.domain(d3.extent(d3.merge(N.concat(O)),function(a){return a.x})).range([0,E]);var P=n.selectAll("g.wrap.multiChart").data([l]),Q=P.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");Q.append("g").attr("class","x axis"),Q.append("g").attr("class","y1 axis"),Q.append("g").attr("class","y2 axis"),Q.append("g").attr("class","lines1Wrap"),Q.append("g").attr("class","lines2Wrap"),Q.append("g").attr("class","bars1Wrap"),Q.append("g").attr("class","bars2Wrap"),Q.append("g").attr("class","stack1Wrap"),Q.append("g").attr("class","stack2Wrap"),Q.append("g").attr("class","legendWrap");var R=P.select("g"),S=l.map(function(a,b){return l[b].color||g(a,b)});j&&(B.color(S),B.width(E/2),R.select(".legendWrap").datum(l.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(B),f.top!=B.height()&&(f.top=B.height(),F=(i||parseInt(n.style("height"))||400)-f.top-f.bottom),R.select(".legendWrap").attr("transform","translate("+E/2+","+-f.top+")")),s.width(E).height(F).interpolate(p).color(S.filter(function(a,b){return!l[b].disabled&&1==l[b].yAxis&&"line"==l[b].type})),t.width(E).height(F).interpolate(p).color(S.filter(function(a,b){return!l[b].disabled&&2==l[b].yAxis&&"line"==l[b].type})),u.width(E).height(F).color(S.filter(function(a,b){return!l[b].disabled&&1==l[b].yAxis&&"bar"==l[b].type})),v.width(E).height(F).color(S.filter(function(a,b){return!l[b].disabled&&2==l[b].yAxis&&"bar"==l[b].type})),w.width(E).height(F).color(S.filter(function(a,b){return!l[b].disabled&&1==l[b].yAxis&&"area"==l[b].type})),x.width(E).height(F).color(S.filter(function(a,b){return!l[b].disabled&&2==l[b].yAxis&&"area"==l[b].type})),R.attr("transform","translate("+f.left+","+f.top+")");var T=R.select(".lines1Wrap").datum(G.filter(function(a){return!a.disabled})),U=R.select(".bars1Wrap").datum(I.filter(function(a){return!a.disabled})),V=R.select(".stack1Wrap").datum(K.filter(function(a){return!a.disabled})),W=R.select(".lines2Wrap").datum(H.filter(function(a){return!a.disabled})),X=R.select(".bars2Wrap").datum(J.filter(function(a){return!a.disabled})),Y=R.select(".stack2Wrap").datum(L.filter(function(a){return!a.disabled})),Z=K.length?K.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],$=L.length?L.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];q.domain(d||d3.extent(d3.merge(N).concat(Z),function(a){return a.y})).range([0,F]),r.domain(e||d3.extent(d3.merge(O).concat($),function(a){return a.y})).range([0,F]),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),t.yDomain(r.domain()),v.yDomain(r.domain()),x.yDomain(r.domain()),K.length&&d3.transition(V).call(w),L.length&&d3.transition(Y).call(x),I.length&&d3.transition(U).call(u),J.length&&d3.transition(X).call(v),G.length&&d3.transition(T).call(s),H.length&&d3.transition(W).call(t),y.ticks(a.utils.calcTicksX(E/100,l)).tickSize(-F,0),R.select(".x.axis").attr("transform","translate(0,"+F+")"),d3.transition(R.select(".x.axis")).call(y),z.ticks(a.utils.calcTicksY(F/36,l)).tickSize(-E,0),d3.transition(R.select(".y1.axis")).call(z),A.ticks(a.utils.calcTicksY(F/36,l)).tickSize(-E,0),d3.transition(R.select(".y2.axis")).call(A),R.select(".y1.axis").classed("nv-disabled",N.length?!1:!0).attr("transform","translate("+c.range()[0]+",0)"),R.select(".y2.axis").classed("nv-disabled",O.length?!1:!0).attr("transform","translate("+c.range()[1]+",0)"),B.dispatch.on("stateChange",function(){b.update()}),C.on("tooltipShow",function(a){k&&D(a,o.parentNode)})}),b}var c,d,e,f={top:30,right:20,bottom:50,left:60},g=a.utils.defaultColor(),h=null,i=null,j=!0,k=!0,l=function(a,b,c){return"<h3>"+a+"</h3><p>"+c+" at "+b+"</p>"},m="No Data Available.",n=function(a){return a.x},o=function(a){return a.y},p="monotone",c=d3.scale.linear(),q=d3.scale.linear(),r=d3.scale.linear(),s=a.models.line().yScale(q),t=a.models.line().yScale(r),u=a.models.multiBar().stacked(!1).yScale(q),v=a.models.multiBar().stacked(!1).yScale(r),w=a.models.stackedArea().yScale(q),x=a.models.stackedArea().yScale(r),y=a.models.axis().scale(c).orient("bottom").tickPadding(5),z=a.models.axis().scale(q).orient("left"),A=a.models.axis().scale(r).orient("right"),B=a.models.legend().height(30),C=d3.dispatch("tooltipShow","tooltipHide"),D=function(c,d){var e=c.pos[0]+(d.offsetLeft||0),f=c.pos[1]+(d.offsetTop||0),g=y.tickFormat()(s.x()(c.point,c.pointIndex)),h=(2==c.series.yAxis?A:z).tickFormat()(s.y()(c.point,c.pointIndex)),i=l(c.series.key,g,h,c,b);
  19429. a.tooltip.show([e,f],i,void 0,void 0,d.offsetParent)};return s.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+f.left,a.pos[1]+f.top],C.tooltipShow(a)}),s.dispatch.on("elementMouseout.tooltip",function(a){C.tooltipHide(a)}),t.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+f.left,a.pos[1]+f.top],C.tooltipShow(a)}),t.dispatch.on("elementMouseout.tooltip",function(a){C.tooltipHide(a)}),u.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+f.left,a.pos[1]+f.top],C.tooltipShow(a)}),u.dispatch.on("elementMouseout.tooltip",function(a){C.tooltipHide(a)}),v.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+f.left,a.pos[1]+f.top],C.tooltipShow(a)}),v.dispatch.on("elementMouseout.tooltip",function(a){C.tooltipHide(a)}),w.dispatch.on("tooltipShow",function(a){return Math.round(100*w.y()(a.point))?(a.pos=[a.pos[0]+f.left,a.pos[1]+f.top],void C.tooltipShow(a)):(setTimeout(function(){d3.selectAll(".point.hover").classed("hover",!1)},0),!1)}),w.dispatch.on("tooltipHide",function(a){C.tooltipHide(a)}),x.dispatch.on("tooltipShow",function(a){return Math.round(100*x.y()(a.point))?(a.pos=[a.pos[0]+f.left,a.pos[1]+f.top],void C.tooltipShow(a)):(setTimeout(function(){d3.selectAll(".point.hover").classed("hover",!1)},0),!1)}),x.dispatch.on("tooltipHide",function(a){C.tooltipHide(a)}),s.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+f.left,a.pos[1]+f.top],C.tooltipShow(a)}),s.dispatch.on("elementMouseout.tooltip",function(a){C.tooltipHide(a)}),t.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+f.left,a.pos[1]+f.top],C.tooltipShow(a)}),t.dispatch.on("elementMouseout.tooltip",function(a){C.tooltipHide(a)}),C.on("tooltipHide",function(){k&&a.tooltip.cleanup()}),b.dispatch=C,b.lines1=s,b.lines2=t,b.bars1=u,b.bars2=v,b.stack1=w,b.stack2=x,b.xAxis=y,b.yAxis1=z,b.yAxis2=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},showLegend:{get:function(){return j},set:function(a){j=a}},yDomain1:{get:function(){return d},set:function(a){d=a}},yDomain2:{get:function(){return e},set:function(a){e=a}},tooltips:{get:function(){return k},set:function(a){k=a}},tooltipContent:{get:function(){return l},set:function(a){l=a}},noData:{get:function(){return m},set:function(a){m=a}},interpolate:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}},x:{get:function(){return n},set:function(a){n=a,s.x(a),u.x(a)}},y:{get:function(){return o},set:function(a){o=a,s.y(a),u.y(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(x){return x.each(function(b){var x=d3.select(this),z=(h||parseInt(x.style("width"))||960)-g.left-g.right,A=(i||parseInt(x.style("height"))||400)-g.top-g.bottom;a.utils.initSVG(x),k.domain(c||d3.extent(b[0].values.map(m).concat(s))),k.range(u?e||[.5*z/b[0].values.length,z*(b[0].values.length-.5)/b[0].values.length]:e||[0,z]),l.domain(d||[d3.min(b[0].values.map(r).concat(t)),d3.max(b[0].values.map(q).concat(t))]).range(f||[A,0]),k.domain()[0]===k.domain()[1]&&k.domain(k.domain()[0]?[k.domain()[0]-.01*k.domain()[0],k.domain()[1]+.01*k.domain()[1]]:[-1,1]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]+.01*l.domain()[0],l.domain()[1]-.01*l.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+g.left+","+g.top+")"),x.on("click",function(a,b){y.chartClick({data:a,index:b,pos:d3.event,id:j})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),B.select("#nv-chart-clip-path-"+j+" rect").attr("width",z).attr("height",A),F.attr("clip-path",v?"url(#nv-chart-clip-path-"+j+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();G.enter().append("path").attr("class",function(a,b,c){return(o(a,b)>p(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,c){var d=z/b[0].values.length*.9;return"m0,0l0,"+(l(o(a,c))-l(q(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(l(r(a,c))-l(o(a,c)))+"l0,"+(l(p(a,c))-l(r(a,c)))+"l"+d/2+",0l"+-d/2+",0z"}).attr("transform",function(a,b){return"translate("+k(m(a,b))+","+l(q(a,b))+")"}).attr("fill",function(){return w[0]}).attr("stroke",function(){return w[0]}).attr("x",0).attr("y",function(a,b){return l(Math.max(0,n(a,b)))}).attr("height",function(a,b){return Math.abs(l(n(a,b))-l(0))});G.attr("class",function(a,b,c){return(o(a,b)>p(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(G).attr("transform",function(a,b){return"translate("+k(m(a,b))+","+l(q(a,b))+")"}).attr("d",function(a,c){var d=z/b[0].values.length*.9;return"m0,0l0,"+(l(o(a,c))-l(q(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(l(r(a,c))-l(o(a,c)))+"l0,"+(l(p(a,c))-l(r(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=d3.scale.linear(),l=d3.scale.linear(),m=function(a){return a.x},n=function(a){return a.y},o=function(a){return a.open},p=function(a){return a.close},q=function(a){return a.high},r=function(a){return a.low},s=[],t=[],u=!1,v=!0,w=a.utils.defaultColor(),x=!1,y=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout");return b.highlightPoint=function(a,c){b.clearHighlights(),d3.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){d3.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return k},set:function(a){k=a}},yScale:{get:function(){return l},set:function(a){l=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return s},set:function(a){s=a}},forceY:{get:function(){return t},set:function(a){t=a}},padData:{get:function(){return u},set:function(a){u=a}},clipEdge:{get:function(){return v},set:function(a){v=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return x},set:function(a){x=a}},x:{get:function(){return m},set:function(a){m=a}},y:{get:function(){return n},set:function(a){n=a}},open:{get:function(){return o()},set:function(a){o=a}},close:{get:function(){return p()},set:function(a){p=a}},high:{get:function(){return q},set:function(a){q=a}},low:{get:function(){return r},set:function(a){r=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(m){return m.each(function(m){function n(a){return y(h.map(function(b){return[f(b),g[b](a[b])]}))}function o(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});j=[],a.forEach(function(a,c){j[c]={dimension:a,extent:b[c]}}),k=[],x.style("display",function(c){var d=a.every(function(a,d){return b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&k.push(c),d?null:"none"}),l.brush({filters:j,active:k})}var p=d3.select(this),q=(d||parseInt(p.style("width"))||960)-c.left-c.right,r=(e||parseInt(p.style("height"))||400)-c.top-c.bottom;a.utils.initSVG(p),k=m,b.update=function(){},f.rangePoints([0,q],1).domain(h),h.forEach(function(a){return g[a]=d3.scale.linear().domain(d3.extent(m,function(b){return+b[a]})).range([r,0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",o),"name"!=a});var s=p.selectAll("g.nv-wrap.nv-parallelCoordinates").data([m]),t=s.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),u=t.append("g"),v=s.select("g");u.append("g").attr("class","nv-parallelCoordinatesWrap"),s.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=d3.svg.line(),z=d3.svg.axis().orient("left");w=u.append("g").attr("class","background").selectAll("path").data(m).enter().append("path").attr("d",n),x=u.append("g").attr("class","foreground").selectAll("path").data(m).enter().append("path").attr("d",n).attr("stroke",i);var A=v.selectAll(".dimension").data(h).enter().append("g").attr("class","dimension").attr("transform",function(a){return"translate("+f(a)+",0)"});A.append("g").attr("class","axis").each(function(a){d3.select(this).call(z.scale(g[a]))}).append("text").attr("text-anchor","middle").attr("y",-9).text(String),A.append("g").attr("class","brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:10,bottom:10,left:10},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=a.utils.defaultColor(),j=[],k=[],l=d3.dispatch("brush");return b.dispatch=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensions:{get:function(){return h},set:function(a){h=a}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},color:{get:function(){return i},set:function(b){i=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(k){return C.reset(),k.each(function(b){function k(a){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,r||(a.innerRadius=0);var b=d3.interpolate(this._current,a);return this._current=b(0),function(a){return N(b(a))}}var D=e-c.left-c.right,E=f-c.top-c.bottom,F=Math.min(D,E)/2,G=F-F/5,H=d3.select(this);a.utils.initSVG(H);var I=H.selectAll(".nv-wrap.nv-pie").data(b),J=I.enter().append("g").attr("class","nvd3 nv-wrap nv-pie nv-chart-"+i),K=J.append("g"),L=I.select("g"),M=K.append("g").attr("class","nv-pie");K.append("g").attr("class","nv-pieLabels"),I.attr("transform","translate("+c.left+","+c.top+")"),L.select(".nv-pie").attr("transform","translate("+D/2+","+E/2+")"),L.select(".nv-pieLabels").attr("transform","translate("+D/2+","+E/2+")"),H.on("click",function(a,b){B.chartClick({data:a,index:b,pos:d3.event,id:i})});var N=d3.svg.arc().outerRadius(G),O=d3.svg.arc().outerRadius(G+5);w&&(N.startAngle(w),O.startAngle(w)),y&&(N.endAngle(y),O.endAngle(y)),r&&(N.innerRadius(F*A),O.innerRadius(F*A));var P=d3.layout.pie().sort(null).value(function(a){return a.disabled?0:h(a)});if(P.padAngle&&x&&P.padAngle(x),N.cornerRadius&&z&&(N.cornerRadius(z),O.cornerRadius(z)),r&&s){var Q=M.append("g").attr("class","nv-pie");Q.append("text").style("text-anchor","middle").attr("class","nv-pie-title").text(function(){return s}).attr("dy","0.35em").attr("transform",function(){return"translate(0, "+u+")"})}var R=I.select(".nv-pie").selectAll(".nv-slice").data(P),S=I.select(".nv-pieLabels").selectAll(".nv-label").data(P);R.exit().remove(),S.exit().remove();var T=R.enter().append("g");T.attr("class","nv-slice"),T.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),t&&d3.select(this).select("path").transition().duration(70).attr("d",O),B.elementMouseover({label:g(a.data),value:h(a.data),point:a.data,pointIndex:b,pos:[d3.event.pageX,d3.event.pageY],id:i,color:d3.select(this).style("fill")})}),T.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),t&&d3.select(this).select("path").transition().duration(50).attr("d",N),B.elementMouseout({label:g(a.data),value:h(a.data),point:a.data,index:b,id:i})}),R.attr("fill",function(a,b){return j(a,b)}),R.attr("stroke",function(a,b){return j(a,b)});var U=T.append("path").each(function(a){this._current=a});if(U.on("click",function(a,b){B.elementClick({label:g(a.data),value:h(a.data),point:a.data,index:b,pos:d3.event,id:i}),d3.event.stopPropagation()}),U.on("dblclick",function(a,b){B.elementDblClick({label:g(a.data),value:h(a.data),point:a.data,index:b,pos:d3.event,id:i}),d3.event.stopPropagation()}),R.select("path").transition().attr("d",N).attrTween("d",k),m){var V=d3.svg.arc().innerRadius(0);if(n)var V=N;o&&(V=d3.svg.arc().outerRadius(N.outerRadius())),S.enter().append("g").classed("nv-label",!0).each(function(a){var b=d3.select(this);b.attr("transform",function(a){if(v){a.outerRadius=G+10,a.innerRadius=G+15;var b=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?b-=90:b+=90,"translate("+V.centroid(a)+") rotate("+b+")"}return a.outerRadius=F+10,a.innerRadius=F+15,"translate("+V.centroid(a)+")"}),b.append("rect").style("stroke","#fff").style("fill","#fff").attr("rx",3).attr("ry",3),b.append("text").style("text-anchor",v?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle").style("fill","#000")});var W={},X=14,Y=140,Z=function(a){return Math.floor(a[0]/Y)*Y+","+Math.floor(a[1]/X)*X};S.watchTransition(C,"pie labels").attr("transform",function(a){if(v){a.outerRadius=G+10,a.innerRadius=G+15;var b=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?b-=90:b+=90,"translate("+V.centroid(a)+") rotate("+b+")"}a.outerRadius=F+10,a.innerRadius=F+15;var c=V.centroid(a);if(a.value){var d=Z(c);W[d]&&(c[1]-=X),W[Z(c)]=!0}return"translate("+c+")"}),S.select(".nv-label text").style("text-anchor",v?(d.startAngle+d.endAngle)/2<Math.PI?"start":"end":"middle").text(function(a){var b=(a.endAngle-a.startAngle)/(2*Math.PI),c={key:g(a.data),value:h(a.data),percent:l(b)};return a.value&&b>q?c[p]:""})}}),C.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},e=500,f=500,g=function(a){return a.x},h=function(a){return a.y},i=Math.floor(1e4*Math.random()),j=a.utils.defaultColor(),k=d3.format(",.2f"),l=d3.format("%"),m=!0,n=!0,o=!1,p="key",q=.02,r=!1,s=!1,t=!0,u=0,v=!1,w=!1,x=!1,y=!1,z=0,A=.5,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),C=a.utils.renderWatch(B);return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return e},set:function(a){e=a}},height:{get:function(){return f},set:function(a){f=a}},showLabels:{get:function(){return m},set:function(a){m=a}},title:{get:function(){return s},set:function(a){s=a}},titleOffset:{get:function(){return u},set:function(a){u=a}},labelThreshold:{get:function(){return q},set:function(a){q=a}},labelFormat:{get:function(){return l},set:function(a){l=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return g},set:function(a){g=a}},id:{get:function(){return i},set:function(a){i=a}},endAngle:{get:function(){return y},set:function(a){y=a}},startAngle:{get:function(){return w},set:function(a){w=a}},padAngle:{get:function(){return x},set:function(a){x=a}},cornerRadius:{get:function(){return z},set:function(a){z=a}},donutRatio:{get:function(){return A},set:function(a){A=a}},pieLabelsOutside:{get:function(){return n},set:function(a){n=a}},donutLabelsOutside:{get:function(){return o},set:function(a){o=a}},labelSunbeamLayout:{get:function(){return v},set:function(a){v=a}},donut:{get:function(){return r},set:function(a){r=a}},growOnHover:{get:function(){return t},set:function(a){t=a}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return h},set:function(a){h=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return p},set:function(a){p=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(i){return r.reset(),r.models(c),i.each(function(i){var j=d3.select(this);a.utils.initSVG(j);var k=(f||parseInt(j.style("width"),10)||960)-e.left-e.right,o=(g||parseInt(j.style("height"),10)||400)-e.top-e.bottom;if(b.update=function(){j.transition().call(b)},b.container=this,l.setter(t(i),b.update).getter(s(i)).update(),l.disabled=i.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!i||!i.length){var r=j.selectAll(".nv-noData").data([n]);return r.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),r.attr("x",e.left+k/2).attr("y",e.top+o/2).text(function(a){return a}),b}j.selectAll(".nv-noData").remove();var u=j.selectAll("g.nv-wrap.nv-pieChart").data([i]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),w=u.select("g");v.append("g").attr("class","nv-pieWrap"),v.append("g").attr("class","nv-legendWrap"),h&&(d.width(k).key(c.x()),u.select(".nv-legendWrap").datum(i).call(d),e.top!=d.height()&&(e.top=d.height(),o=(g||parseInt(j.style("height"))||400)-e.top-e.bottom),u.select(".nv-legendWrap").attr("transform","translate(0,"+-e.top+")")),u.attr("transform","translate("+e.left+","+e.top+")"),c.width(k).height(o);var x=w.select(".nv-pieWrap").datum([i]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){p.tooltipHide(a)}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(i.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),r.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=!0,i=a.utils.defaultColor(),j=!0,k=function(a,b,c){return'<h3 style="background-color: '+c.color+'">'+a+"</h3><p>"+b+"</p>"},l=a.utils.state(),m=null,n="No Data Available.",o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),q=function(d,e){var f=c.x()(d.point),g=d.pos[0]+(e&&e.offsetLeft||0),h=d.pos[1]+(e&&e.offsetTop||0),i=c.valueFormat()(c.y()(d.point)),j=k(f,i,d,b);a.tooltip.show([g,h],j,d.value<0?"n":"s",null,e)},r=a.utils.renderWatch(p),s=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},t=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+e.left,a.pos[1]+e.top],p.tooltipShow(a)}),p.on("tooltipShow",function(a){j&&q(a)}),p.on("tooltipHide",function(){j&&a.tooltip.cleanup()}),b.legend=d,b.dispatch=p,b.pie=c,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},tooltipContent:{get:function(){return k},set:function(a){k=a}},tooltips:{get:function(){return j},set:function(a){j=a}},showLegend:{get:function(){return h},set:function(a){h=a}},defaultState:{get:function(){return m},set:function(a){m=a}},color:{get:function(){return i},set:function(a){i=a,d.color(i),c.color(i)}},duration:{get:function(){return o},set:function(a){o=a,r.reset(o)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(L){return N.reset(),L.each(function(b){function L(){if(!v)return!1;var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=o(a,c),e=p(a,c);return[l(d)+1e-7*Math.random(),m(e)+1e-7*Math.random(),b,c,a]}).filter(function(a,b){return w(a[4],b)})}));if(K===!0){a.length<3&&(a.push([l.range()[0]-20,m.range()[0]-20,null,null]),a.push([l.range()[1]+20,m.range()[1]+20,null,null]),a.push([l.range()[0]-20,m.range()[0]+20,null,null]),a.push([l.range()[1]+20,m.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});S.select(".nv-point-paths").selectAll("path").remove();var e=S.select(".nv-point-paths").selectAll("path").data(d);if(e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+b+")"}),A){var f=S.append("svg:g").attr("id","nv-point-clips");f.selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",B)}var j=function(a,c){if(M)return 0;var d=b[a.series];if("undefined"!=typeof d){var e=d.values[a.point];c({point:e,series:d,pos:[l(o(e,a.point))+g.left,m(p(e,a.point))+g.top],seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){j(a,J.elementClick)}).on("dblclick",function(a){j(a,J.elementDblClick)}).on("mouseover",function(a){j(a,J.elementMouseover)}).on("mouseout",function(a){j(a,J.elementMouseout)})}else S.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(M||!b[a.series])return 0;var d=b[a.series],e=d.values[c];J.elementClick({point:e,series:d,pos:[l(o(e,c))+g.left,m(p(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(M||!b[a.series])return 0;var d=b[a.series],e=d.values[c];J.elementMouseover({point:e,series:d,pos:[l(o(e,c))+g.left,m(p(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseout",function(a,c){if(M||!b[a.series])return 0;var d=b[a.series],e=d.values[c];J.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c})});M=!1}var O=d3.select(this),P=(h||parseInt(O.style("width"))||960)-g.left-g.right,Q=(i||parseInt(O.style("height"))||400)-g.top-g.bottom;a.utils.initSVG(O),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var R=C&&D&&G?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:o(a,b),y:p(a,b),size:q(a,b)}})}));l.domain(C||d3.extent(R.map(function(a){return a.x}).concat(s))),l.range(x&&b[0]?E||[(P*y+P)/(2*b[0].values.length),P-P*(1+y)/(2*b[0].values.length)]:E||[0,P]),m.domain(D||d3.extent(R.map(function(a){return a.y}).concat(t))).range(F||[Q,0]),n.domain(G||d3.extent(R.map(function(a){return a.size}).concat(u))).range(H||[16,256]),(l.domain()[0]===l.domain()[1]||m.domain()[0]===m.domain()[1])&&(I=!0),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),isNaN(l.domain()[0])&&l.domain([-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),c=c||l,d=d||m,e=e||n;var S=O.selectAll("g.nv-wrap.nv-scatter").data([b]),T=S.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k+(I?" nv-single-point":"")),U=T.append("defs"),V=T.append("g"),W=S.select("g");V.append("g").attr("class","nv-groups"),V.append("g").attr("class","nv-point-paths"),S.attr("transform","translate("+g.left+","+g.top+")"),U.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),S.select("#nv-edge-clip-"+k+" rect").attr("width",P).attr("height",Q>0?Q:0),W.attr("clip-path",z?"url(#nv-edge-clip-"+k+")":""),M=!0;var X=S.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});X.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),X.exit().remove(),X.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),X.watchTransition(N,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var Y=X.selectAll("path.nv-point").data(function(a){return a.values});Y.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a,b){return"translate("+c(o(a,b))+","+d(p(a,b))+")"}).attr("d",a.utils.symbol().type(r).size(function(a,b){return n(q(a,b))})),Y.exit().remove(),X.exit().selectAll("path.nv-point").watchTransition(N,"scatter exit").attr("transform",function(a,b){return"translate("+l(o(a,b))+","+m(p(a,b))+")"}).remove(),Y.each(function(a,b){d3.select(this).classed("nv-point",!0).classed("nv-point-"+b,!0).classed("hover",!1)}),Y.watchTransition(N,"scatter points").attr("transform",function(a,b){return"translate("+l(o(a,b))+","+m(p(a,b))+")"}).attr("d",a.utils.symbol().type(r).size(function(a,b){return n(q(a,b))})),clearTimeout(f),f=setTimeout(L,300),c=l.copy(),d=m.copy(),e=n.copy()}),N.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=function(a){return a.size||1},r=function(a){return a.shape||"circle"},s=[],t=[],u=[],v=!0,w=function(a){return!a.notActive},x=!1,y=.1,z=!1,A=!0,B=function(){return 25},C=null,D=null,E=null,F=null,G=null,H=null,I=!1,J=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),K=!0,L=250,M=!1,N=a.utils.renderWatch(J,L);return b.dispatch=J,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return d3.selectAll(".nv-chart-"+k+" .nv-point.hover").classed("hover",!1),null},this.highlightPoint=function(a,b,c){d3.select(".nv-chart-"+k+" .nv-series-"+a+" .nv-point-"+b).classed("hover",c)}},J.on("elementMouseover.point",function(a){v&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),J.on("elementMouseout.point",function(a){v&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},pointScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return C},set:function(a){C=a}},yDomain:{get:function(){return D},set:function(a){D=a}},pointDomain:{get:function(){return G},set:function(a){G=a}},xRange:{get:function(){return E},set:function(a){E=a}},yRange:{get:function(){return F},set:function(a){F=a}},pointRange:{get:function(){return H},set:function(a){H=a}},forceX:{get:function(){return s},set:function(a){s=a}},forceY:{get:function(){return t},set:function(a){t=a}},forcePoint:{get:function(){return u},set:function(a){u=a}},interactive:{get:function(){return v},set:function(a){v=a}},pointActive:{get:function(){return w},set:function(a){w=a}},padDataOuter:{get:function(){return y},set:function(a){y=a}},padData:{get:function(){return x},set:function(a){x=a}},clipEdge:{get:function(){return z},set:function(a){z=a}},clipVoronoi:{get:function(){return A},set:function(a){A=a}},clipRadius:{get:function(){return B},set:function(a){B=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return o},set:function(a){o=d3.functor(a)}},y:{get:function(){return p},set:function(a){p=d3.functor(a)}},pointSize:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointShape:{get:function(){return r},set:function(a){r=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return L},set:function(a){L=a,N.reset(L)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return K},set:function(a){K=a,K===!1&&(A=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(v){return F.reset(),F.models(c),r&&F.models(d),s&&F.models(e),o&&F.models(g),p&&F.models(h),v.each(function(v){var w=d3.select(this),x=this;a.utils.initSVG(w);var J=(j||parseInt(w.style("width"))||960)-i.left-i.right,K=(k||parseInt(w.style("height"))||400)-i.top-i.bottom;if(b.update=function(){0===C?w.call(b):w.transition().duration(C).call(b)},b.container=this,y.setter(I(v),b.update).getter(H(v)).update(),y.disabled=v.map(function(a){return!!a.disabled}),!z){var L;z={};for(L in y)z[L]=y[L]instanceof Array?y[L].slice(0):y[L]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length)){var M=w.selectAll(".nv-noData").data([B]);return M.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),M.attr("x",i.left+J/2).attr("y",i.top+K/2).text(function(a){return a}),F.renderEnd("scatter immediate"),b}w.selectAll(".nv-noData").remove(),m=c.xScale(),n=c.yScale();var N=w.selectAll("g.nv-wrap.nv-scatterChart").data([v]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),P=O.append("g"),Q=N.select("g");P.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),P.append("g").attr("class","nv-x nv-axis"),P.append("g").attr("class","nv-y nv-axis"),P.append("g").attr("class","nv-scatterWrap"),P.append("g").attr("class","nv-regressionLinesWrap"),P.append("g").attr("class","nv-distWrap"),P.append("g").attr("class","nv-legendWrap"),N.attr("transform","translate("+i.left+","+i.top+")"),t&&Q.select(".nv-y.nv-axis").attr("transform","translate("+J+",0)"),q&&(f.width(J/2),N.select(".nv-legendWrap").datum(v).call(f),i.top!=f.height()&&(i.top=f.height(),K=(k||parseInt(w.style("height"))||400)-i.top-i.bottom),N.select(".nv-legendWrap").attr("transform","translate("+J/2+","+-i.top+")")),c.width(J).height(K).color(v.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!v[b].disabled})),N.select(".nv-scatterWrap").datum(v.filter(function(a){return!a.disabled})).call(c),N.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var R=N.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});R.enter().append("g").attr("class","nv-regLines");var S=R.selectAll(".nv-regLine").data(function(a){return[a]});S.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),S.filter(function(a){return a.intercept&&a.slope}).watchTransition(F,"scatterPlusLineChart: regline").attr("x1",m.range()[0]).attr("x2",m.range()[1]).attr("y1",function(a){return n(m.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return n(m.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return l(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),r&&(d.scale(m).ticks(d.ticks()?d.ticks():a.utils.calcTicksX(J/100,v)).tickSize(-K,0),Q.select(".nv-x.nv-axis").attr("transform","translate(0,"+n.range()[0]+")").call(d)),s&&(e.scale(n).ticks(e.ticks()?e.ticks():a.utils.calcTicksY(K/36,v)).tickSize(-J,0),Q.select(".nv-y.nv-axis").call(e)),o&&(g.getData(c.x()).scale(m).width(J).color(v.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!v[b].disabled})),P.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),Q.select(".nv-distributionX").attr("transform","translate(0,"+n.range()[0]+")").datum(v.filter(function(a){return!a.disabled})).call(g)),p&&(h.getData(c.y()).scale(n).width(K).color(v.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!v[b].disabled})),P.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),Q.select(".nv-distributionY").attr("transform","translate("+(t?J:-h.size())+",0)").datum(v.filter(function(a){return!a.disabled
  19430. })).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];A.stateChange(y),b.update()}),c.dispatch.on("elementMouseover.tooltip",function(a){d3.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos[1]-K),d3.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos[0]+g.size()),a.pos=[a.pos[0]+i.left,a.pos[1]+i.top],A.tooltipShow(a)}),A.on("tooltipShow",function(a){u&&G(a,x.parentNode)}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),b.update()}),D=m.copy(),E=n.copy()}),F.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i={top:30,right:20,bottom:50,left:75},j=null,k=null,l=a.utils.defaultColor(),m=c.xScale(),n=c.yScale(),o=!1,p=!1,q=!0,r=!0,s=!0,t=!1,u=!0,v=function(a,b){return"<strong>"+b+"</strong>"},w=function(a,b,c){return"<strong>"+c+"</strong>"},x=function(a,b,c,d){return"<h3>"+a+"</h3><p>"+d+"</p>"},y=a.utils.state(),z=null,A=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),B="No Data Available.",C=250;c.xScale(m).yScale(n),d.orient("bottom").tickPadding(10),e.orient(t?"right":"left").tickPadding(10),g.axis("x"),h.axis("y");var D,E,F=a.utils.renderWatch(A,C),G=function(f,g){var h=f.pos[0]+(g.offsetLeft||0),j=f.pos[1]+(g.offsetTop||0),k=f.pos[0]+(g.offsetLeft||0),l=n.range()[0]+i.top+(g.offsetTop||0),o=m.range()[0]+i.left+(g.offsetLeft||0),p=f.pos[1]+(g.offsetTop||0),q=d.tickFormat()(c.x()(f.point,f.pointIndex)),r=e.tickFormat()(c.y()(f.point,f.pointIndex));null!=v&&a.tooltip.show([k,l],v(f.series.key,q,r,f,b),"n",1,g,"x-nvtooltip"),null!=w&&a.tooltip.show([o,p],w(f.series.key,q,r,f,b),"e",1,g,"y-nvtooltip"),null!=x&&a.tooltip.show([h,j],x(f.series.key,q,r,f.point.tooltip,f,b),f.value<0?"n":"s",null,g)},H=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},I=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseout.tooltip",function(a){A.tooltipHide(a),d3.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),d3.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),A.on("tooltipHide",function(){u&&a.tooltip.cleanup()}),b.dispatch=A,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},showDistX:{get:function(){return o},set:function(a){o=a}},showDistY:{get:function(){return p},set:function(a){p=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},tooltips:{get:function(){return u},set:function(a){u=a}},tooltipContent:{get:function(){return x},set:function(a){x=a}},tooltipXContent:{get:function(){return v},set:function(a){v=a}},tooltipYContent:{get:function(){return w},set:function(a){w=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return B},set:function(a){B=a}},duration:{get:function(){return C},set:function(a){C=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,e.orient(a?"right":"left")}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),f.color(l),g.color(l),h.color(l)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(j){return j.each(function(b){var j=h-g.left-g.right,p=i-g.top-g.bottom,q=d3.select(this);a.utils.initSVG(q),k.domain(c||d3.extent(b,m)).range(e||[0,j]),l.domain(d||d3.extent(b,n)).range(f||[p,0]);{var r=q.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||o(a,b)}).attr("d",d3.svg.line().x(function(a,b){return k(m(a,b))}).y(function(a,b){return l(n(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return n(a,b)}),d=b(c.lastIndexOf(l.domain()[1])),e=b(c.indexOf(l.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return k(m(a,a.pointIndex))}).attr("cy",function(a){return l(n(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return m(a,a.pointIndex)==k.domain()[1]?"nv-point nv-currentValue":n(a,a.pointIndex)==l.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=!0,k=d3.scale.linear(),l=d3.scale.linear(),m=function(a){return a.x},n=function(a){return a.y},o=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return k},set:function(a){k=a}},yScale:{get:function(){return l},set:function(a){l=a}},animate:{get:function(){return j},set:function(a){j=a}},x:{get:function(){return m},set:function(a){m=d3.functor(a)}},y:{get:function(){return n},set:function(a){n=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(m){return m.each(function(q){function r(){if(!j){var a=B.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(q[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",v),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),B.select(".nv-hoverValue .nv-xValue").text(k(e.x()(q[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),B.select(".nv-hoverValue .nv-yValue").text(l(e.y()(q[i[0]],i[0]))))}}function s(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;f<a.length;f++)Math.abs(e.x()(a[f],f)-b)<c&&(c=Math.abs(e.x()(a[f],f)-b),d=f);return d}if(!j){var b=d3.mouse(this)[0]-f.left;i=[a(q,Math.round(c.invert(b)))],r()}}var t=d3.select(this);a.utils.initSVG(t);var u=(g||parseInt(t.style("width"))||960)-f.left-f.right,v=(h||parseInt(t.style("height"))||400)-f.top-f.bottom;if(b.update=function(){b(m)},b.container=this,!q||!q.length){var w=t.selectAll(".nv-noData").data([p]);return w.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),w.attr("x",f.left+u/2).attr("y",f.top+v/2).text(function(a){return a}),b}t.selectAll(".nv-noData").remove();var x=e.y()(q[q.length-1],q.length-1);c=e.xScale(),d=e.yScale();var y=t.selectAll("g.nv-wrap.nv-sparklineplus").data([q]),z=y.enter().append("g").attr("class","nvd3 nv-wrap nv-sparklineplus"),A=z.append("g"),B=y.select("g");A.append("g").attr("class","nv-sparklineWrap"),A.append("g").attr("class","nv-valueWrap"),A.append("g").attr("class","nv-hoverArea"),y.attr("transform","translate("+f.left+","+f.top+")");var C=B.select(".nv-sparklineWrap");e.width(u).height(v),C.call(e);var D=B.select(".nv-valueWrap"),E=D.selectAll(".nv-currentValue").data([x]);E.enter().append("text").attr("class","nv-currentValue").attr("dx",o?-8:8).attr("dy",".9em").style("text-anchor",o?"end":"start"),E.attr("x",u+(o?f.right:0)).attr("y",n?function(a){return d(a)}:0).style("fill",e.color()(q[q.length-1],q.length-1)).text(l(x)),A.select(".nv-hoverArea").append("rect").on("mousemove",s).on("click",function(){j=!j}).on("mouseout",function(){i=[],r()}),B.select(".nv-hoverArea rect").attr("transform",function(){return"translate("+-f.left+","+-f.top+")"}).attr("width",u+f.left+f.right).attr("height",v+f.top)}),b}var c,d,e=a.models.sparkline(),f={top:15,right:100,bottom:10,left:50},g=null,h=null,i=[],j=!1,k=d3.format(",r"),l=d3.format(",.2f"),m=!0,n=!0,o=!1,p="No Data Available.";return b.sparkline=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},xTickFormat:{get:function(){return k},set:function(a){k=a}},yTickFormat:{get:function(){return l},set:function(a){l=a}},showValue:{get:function(){return m},set:function(a){m=a}},alignValue:{get:function(){return n},set:function(a){n=a}},rightAlignValue:{get:function(){return o},set:function(a){o=a}},noData:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.stackedArea=function(){"use strict";function b(l){return t.reset(),t.models(q),l.each(function(l){var r=f-e.left-e.right,u=g-e.top-e.bottom,v=d3.select(this);a.utils.initSVG(v),c=q.xScale(),d=q.yScale();var w=l;l.forEach(function(a,b){a.seriesIndex=b,a.values=a.values.map(function(a,c){return a.index=c,a.seriesIndex=b,a})});var x=l.filter(function(a){return!a.disabled});l=d3.layout.stack().order(n).offset(m).values(function(a){return a.values}).x(j).y(k).out(function(a,b,c){var d=0===k(a)?0:c;a.display={y:d,y0:b}})(x);var y=v.selectAll("g.nv-wrap.nv-stackedarea").data([l]),z=y.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedarea"),A=z.append("defs"),B=z.append("g"),C=y.select("g");B.append("g").attr("class","nv-areaWrap"),B.append("g").attr("class","nv-scatterWrap"),y.attr("transform","translate("+e.left+","+e.top+")"),q.width(r).height(u).x(j).y(function(a){return a.display.y+a.display.y0}).forceY([0]).color(l.map(function(a){return a.color||h(a,a.seriesIndex)}));var D=C.select(".nv-scatterWrap").datum(l);D.call(q),A.append("clipPath").attr("id","nv-edge-clip-"+i).append("rect"),y.select("#nv-edge-clip-"+i+" rect").attr("width",r).attr("height",u),C.attr("clip-path",p?"url(#nv-edge-clip-"+i+")":"");var E=d3.svg.area().x(function(a,b){return c(j(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y+a.display.y0)}).interpolate(o),F=d3.svg.area().x(function(a,b){return c(j(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y0)}),G=C.select(".nv-areaWrap").selectAll("path.nv-area").data(function(a){return a});G.enter().append("path").attr("class",function(a,b){return"nv-area nv-area-"+b}).attr("d",function(a){return F(a.values,a.seriesIndex)}).on("mouseover",function(a){d3.select(this).classed("hover",!0),s.areaMouseover({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("mouseout",function(a){d3.select(this).classed("hover",!1),s.areaMouseout({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("click",function(a){d3.select(this).classed("hover",!1),s.areaClick({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}),G.exit().remove(),G.style("fill",function(a){return a.color||h(a,a.seriesIndex)}).style("stroke",function(a){return a.color||h(a,a.seriesIndex)}),G.watchTransition(t,"stackedArea path").attr("d",function(a,b){return E(a.values,b)}),q.dispatch.on("elementMouseover.area",function(a){C.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!0)}),q.dispatch.on("elementMouseout.area",function(a){C.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!1)}),b.d3_stackedOffset_stackPercent=function(a){var b,c,d,e=a.length,f=a[0].length,g=1/e,h=[];for(c=0;f>c;++c){for(b=0,d=0;b<w.length;b++)d+=k(w[b].values[c]);if(d)for(b=0;e>b;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=g}for(c=0;f>c;++c)h[c]=0;return h}}),t.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=function(a){return a.x},k=function(a){return a.y},l="stack",m="zero",n="default",o="linear",p=!1,q=a.models.scatter(),r=250,s=d3.dispatch("tooltipShow","tooltipHide","areaClick","areaMouseover","areaMouseout","renderEnd");q.interactive(!1),q.pointSize(2.2).pointDomain([2.2,2.2]);var t=a.utils.renderWatch(s,r);return q.dispatch.on("elementClick.area",function(a){s.areaClick(a)}),q.dispatch.on("elementMouseover.tooltip",function(a){a.pos=[a.pos[0]+e.left,a.pos[1]+e.top],s.tooltipShow(a)}),q.dispatch.on("elementMouseout.tooltip",function(a){s.tooltipHide(a)}),b.dispatch=s,b.scatter=q,b.interpolate=function(a){return arguments.length?(o=a,b):o},b.duration=function(a){return arguments.length?(r=a,t.reset(r),q.duration(r),b):r},b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},offset:{get:function(){return m},set:function(a){m=a}},order:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return o},set:function(a){o=a}},x:{get:function(){return j},set:function(a){j=d3.functor(a)}},y:{get:function(){return k},set:function(a){k=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return l},set:function(a){switch(l=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return r},set:function(a){r=a,t.reset(r),q.duration(r)}}}),a.utils.inheritOptions(b,q),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(v){return F.reset(),F.models(e),q&&F.models(f),r&&F.models(g),v.each(function(v){var F=d3.select(this),K=this;a.utils.initSVG(F);var L=(l||parseInt(F.style("width"))||960)-k.left-k.right,M=(m||parseInt(F.style("height"))||400)-k.top-k.bottom;if(b.update=function(){F.transition().duration(E).call(b)},b.container=this,x.setter(J(v),b.update).getter(I(v)).update(),x.disabled=v.map(function(a){return!!a.disabled}),!y){var N;y={};for(N in x)y[N]=x[N]instanceof Array?x[N].slice(0):x[N]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length)){var O=F.selectAll(".nv-noData").data([z]);return O.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),O.attr("x",k.left+L/2).attr("y",k.top+M/2).text(function(a){return a}),b}F.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var P=F.selectAll("g.nv-wrap.nv-stackedAreaChart").data([v]),Q=P.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),R=P.select("g");if(Q.append("rect").style("opacity",0),Q.append("g").attr("class","nv-x nv-axis"),Q.append("g").attr("class","nv-y nv-axis"),Q.append("g").attr("class","nv-stackedWrap"),Q.append("g").attr("class","nv-legendWrap"),Q.append("g").attr("class","nv-controlsWrap"),Q.append("g").attr("class","nv-interactive"),R.select("rect").attr("width",L).attr("height",M),p){var S=o?L-B:L;h.width(S),R.select(".nv-legendWrap").datum(v).call(h),k.top!=h.height()&&(k.top=h.height(),M=(m||parseInt(F.style("height"))||400)-k.top-k.bottom),R.select(".nv-legendWrap").attr("transform","translate("+(L-S)+","+-k.top+")")}if(o){var T=[{key:D.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:D.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:D.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:D.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];B=C.length/3*260,T=T.filter(function(a){return-1!==C.indexOf(a.metaKey)}),i.width(B).color(["#444","#444","#444"]),R.select(".nv-controlsWrap").datum(T).call(i),k.top!=Math.max(i.height(),h.height())&&(k.top=Math.max(i.height(),h.height()),M=(m||parseInt(F.style("height"))||400)-k.top-k.bottom),R.select(".nv-controlsWrap").attr("transform","translate(0,"+-k.top+")")}P.attr("transform","translate("+k.left+","+k.top+")"),s&&R.select(".nv-y.nv-axis").attr("transform","translate("+L+",0)"),t&&(j.width(L).height(M).margin({left:k.left,top:k.top}).svgContainer(F).xScale(c),P.select(".nv-interactive").call(j)),e.width(L).height(M);var U=R.select(".nv-stackedWrap").datum(v);U.transition().call(e),q&&(f.scale(c).ticks(a.utils.calcTicksX(L/100,v)).tickSize(-M,0),R.select(".nv-x.nv-axis").attr("transform","translate(0,"+M+")"),R.select(".nv-x.nv-axis").transition().duration(0).call(f)),r&&(g.scale(d).ticks("wiggle"==e.offset()?0:a.utils.calcTicksY(M/36,v)).tickSize(-L,0).setTickFormat("expand"==e.style()||"stack_percent"==e.style()?d3.format("%"):w),R.select(".nv-y.nv-axis").transition().duration(0).call(g)),e.dispatch.on("areaClick.toggle",function(a){v.forEach(1===v.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),x.disabled=v.map(function(a){return!!a.disabled}),A.stateChange(x),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(T=T.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),x.style=e.style(),A.stateChange(x),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,i,l=[];if(v.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x()),e.highlightPoint(g,h,!0);var j=f.values[h];if("undefined"!=typeof j){"undefined"==typeof d&&(d=j),"undefined"==typeof i&&(i=b.xScale()(b.x()(j,h)));var k="expand"==e.style()?j.display.y:b.y()(j,h);l.push({key:f.key,value:k,color:n(f,f.seriesIndex),stackedValue:j.display})}}),l.reverse(),l.length>2){var m=b.yScale().invert(c.mouseY),o=null;l.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(o=b):void 0}),null!=o&&(l[o].highlight=!0)}var p=f.tickFormat()(b.x()(d,h)),q="expand"==e.style()?function(a){return d3.format(".1%")(a)}:function(a){return g.tickFormat()(a)};j.tooltip.position({left:i+k.left,top:c.mouseY+k.top}).chartContainer(K.parentNode).enabled(u).valueFormatter(q).data({value:p,series:l})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){A.tooltipHide(),e.clearHighlights()}),A.on("tooltipShow",function(a){u&&H(a,K.parentNode)}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&v.length===a.disabled.length&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k={top:30,right:25,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p=!0,q=!0,r=!0,s=!1,t=!1,u=!0,v=function(a,b,c){return"<h3>"+a+"</h3><p>"+c+" on "+b+"</p>"},w=d3.format(",.2f"),x=a.utils.state(),y=null,z="No Data Available.",A=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),B=250,C=["Stacked","Stream","Expanded"],D={},E=250;x.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(s?"right":"left"),i.updateState(!1);var F=a.utils.renderWatch(A),G=e.style(),H=function(c,d){var h=c.pos[0]+(d.offsetLeft||0),i=c.pos[1]+(d.offsetTop||0),j=f.tickFormat()(e.x()(c.point,c.pointIndex)),k=g.tickFormat()(e.y()(c.point,c.pointIndex)),l=v(c.series.key,j,k,c,b);a.tooltip.show([h,i],l,c.value<0?"n":"s",null,d)},I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},J=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("tooltipShow",function(a){a.pos=[a.pos[0]+k.left,a.pos[1]+k.top],A.tooltipShow(a)}),e.dispatch.on("tooltipHide",function(a){A.tooltipHide(a)}),A.on("tooltipHide",function(){u&&a.tooltip.cleanup()}),b.dispatch=A,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,g.setTickFormat=g.tickFormat,b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},tooltips:{get:function(){return u},set:function(a){u=a}},tooltipContent:{get:function(){return v},set:function(a){v=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return D},set:function(a){D=a}},yAxisTickFormat:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return E},set:function(a){E=a,F.reset(E),e.duration(E),f.duration(E),g.duration(E)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n),e.color(n)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,g.orient(s?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=!!a,a&&(b.interactive(!1),b.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.version="1.7.1"}();/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
  19431. !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;
  19432. return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ca()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ca()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?aa:ba):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=aa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=aa,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=aa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=ba;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=ba),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function da(a){var b=ea.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var ea="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fa=/ jQuery\d+="(?:null|\d+)"/g,ga=new RegExp("<(?:"+ea+")[\\s/>]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/<tbody/i,la=/<|&#?\w+;/,ma=/<(?:script|style|link)/i,na=/checked\s*(?:[^=]|=\s*.checked.)/i,oa=/^$|\/(?:java|ecma)script/i,pa=/^true\/(.*)/,qa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ra={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?"<table>"!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ca[0].contentWindow||Ca[0].contentDocument).document,b.write(),b.close(),c=Ea(a,b),Ca.detach()),Da[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Ga=/^margin/,Ha=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ia,Ja,Ka=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ia=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Ha.test(g)&&Ga.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ia=function(a){return a.currentStyle},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ha.test(g)&&!Ka.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function La(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Ma=/alpha\([^)]*\)/i,Na=/opacity\s*=\s*([^)]*)/,Oa=/^(none|table(?!-c[ea]).+)/,Pa=new RegExp("^("+S+")(.*)$","i"),Qa=new RegExp("^([+-])=("+S+")","i"),Ra={position:"absolute",visibility:"hidden",display:"block"},Sa={letterSpacing:"0",fontWeight:"400"},Ta=["Webkit","O","Moz","ms"];function Ua(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ta.length;while(e--)if(b=Ta[e]+c,b in a)return b;return d}function Va(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fa(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wa(a,b,c){var d=Pa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Ya(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ia(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Ja(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ha.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xa(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ja(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ua(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qa.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ua(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Ja(a,b,d)),"normal"===f&&b in Sa&&(f=Sa[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Oa.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Ra,function(){return Ya(a,b,d)}):Ya(a,b,d):void 0},set:function(a,c,d){var e=d&&Ia(a);return Wa(a,c,d?Xa(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Na.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Ma,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Ma.test(f)?f.replace(Ma,e):f+" "+e)}}),m.cssHooks.marginRight=La(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Ja,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Ga.test(a)||(m.cssHooks[a+b].set=Wa)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ia(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Va(this,!0)},hide:function(){return Va(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Za(a,b,c,d,e){
  19433. return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[c]=eb[c]||[],eb[c].unshift(b)},prefilter:function(a,b){b?db.unshift(a):db.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kb(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),m.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($a=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$a=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_a||(_a=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_a),_a=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lb=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lb,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mb,nb,ob=m.expr.attrHandle,pb=/^(?:checked|selected)$/i,qb=k.getSetAttribute,rb=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nb:mb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rb&&qb||!pb.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qb?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nb={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rb&&qb||!pb.test(c)?a.setAttribute(!qb&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ob[b]||m.find.attr;ob[b]=rb&&qb||!pb.test(b)?function(a,b,d){var e,f;return d||(f=ob[b],ob[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,ob[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rb&&qb||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mb&&mb.set(a,b,c)}}),qb||(mb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},ob.id=ob.name=ob.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mb.set},m.attrHooks.contenteditable={set:function(a,b,c){mb.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sb=/^(?:input|select|textarea|button|object)$/i,tb=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sb.test(a.nodeName)||tb.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var ub=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ub," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vb=m.now(),wb=/\?/,xb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yb,zb,Ab=/#.*$/,Bb=/([?&])_=[^&]*/,Cb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Db=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Eb=/^(?:GET|HEAD)$/,Fb=/^\/\//,Gb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hb={},Ib={},Jb="*/".concat("*");try{zb=location.href}catch(Kb){zb=y.createElement("a"),zb.href="",zb=zb.href}yb=Gb.exec(zb.toLowerCase())||[];function Lb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mb(a,b,c,d){var e={},f=a===Ib;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nb(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Ob(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zb,type:"GET",isLocal:Db.test(yb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nb(Nb(a,m.ajaxSettings),b):Nb(m.ajaxSettings,a)},ajaxPrefilter:Lb(Hb),ajaxTransport:Lb(Ib),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cb.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zb)+"").replace(Ab,"").replace(Fb,yb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gb.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yb[1]&&c[2]===yb[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yb[3]||("http:"===yb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mb(Hb,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Eb.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wb.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bb.test(e)?e.replace(Bb,"$1_="+vb++):e+(wb.test(e)?"&":"?")+"_="+vb++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jb+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mb(Ib,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Ob(k,v,c)),u=Pb(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qb=/%20/g,Rb=/\[\]$/,Sb=/\r?\n/g,Tb=/^(?:submit|button|image|reset|file)$/i,Ub=/^(?:input|select|textarea|keygen)/i;function Vb(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rb.test(a)?d(a,e):Vb(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vb(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vb(c,a[c],b,e);return d.join("&").replace(Qb,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Ub.test(this.nodeName)&&!Tb.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sb,"\r\n")}}):{name:b.name,value:c.replace(Sb,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zb()||$b()}:Zb;var Wb=0,Xb={},Yb=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xb)Xb[a](void 0,!0)}),k.cors=!!Yb&&"withCredentials"in Yb,Yb=k.ajax=!!Yb,Yb&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xb[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xb[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zb(){try{return new a.XMLHttpRequest}catch(b){}}function $b(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _b=[],ac=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_b.pop()||m.expando+"_"+vb++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ac.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ac.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ac,"$1"+e):b.jsonp!==!1&&(b.url+=(wb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_b.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bc=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bc)return bc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cc=a.document.documentElement;function dc(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cc;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cc})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=La(k.pixelPosition,function(a,c){return c?(c=Ja(a,b),Ha.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ec=a.jQuery,fc=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fc),b&&a.jQuery===m&&(a.jQuery=ec),m},typeof b===K&&(a.jQuery=a.$=m),m});
  19434. <tr>
  19435. <td class="{{classes_level}}">{{name}}</td>
  19436. <td class="{{classes_level}} big">{{classes_bar}}</td>
  19437. <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
  19438. <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
  19439. <td class="{{methods_level}} big">{{methods_bar}}</td>
  19440. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  19441. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  19442. <td class="{{methods_level}} small">{{crap}}</td>
  19443. <td class="{{lines_level}} big">{{lines_bar}}</td>
  19444. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  19445. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  19446. </tr>
  19447. <tr>
  19448. <td class="{{methods_level}}" colspan="4">{{name}}</td>
  19449. <td class="{{methods_level}} big">{{methods_bar}}</td>
  19450. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  19451. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  19452. <td class="{{methods_level}} small">{{crap}}</td>
  19453. <td class="{{lines_level}} big">{{lines_bar}}</td>
  19454. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  19455. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  19456. </tr>
  19457. <tr>
  19458. <td class="{{lines_level}}">{{icon}}{{name}}</td>
  19459. <td class="{{lines_level}} big">{{lines_bar}}</td>
  19460. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  19461. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  19462. <td class="{{methods_level}} big">{{methods_bar}}</td>
  19463. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  19464. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  19465. <td class="{{classes_level}} big">{{classes_bar}}</td>
  19466. <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
  19467. <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
  19468. </tr>
  19469. <!DOCTYPE html>
  19470. <html lang="en">
  19471. <head>
  19472. <meta charset="UTF-8">
  19473. <title>Code Coverage for {{full_path}}</title>
  19474. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  19475. <link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
  19476. <link href="{{path_to_root}}css/style.css" rel="stylesheet">
  19477. <!--[if lt IE 9]>
  19478. <script src="{{path_to_root}}js/html5shiv.min.js"></script>
  19479. <script src="{{path_to_root}}js/respond.min.js"></script>
  19480. <![endif]-->
  19481. </head>
  19482. <body>
  19483. <header>
  19484. <div class="container">
  19485. <div class="row">
  19486. <div class="col-md-12">
  19487. <ol class="breadcrumb">
  19488. {{breadcrumbs}}
  19489. </ol>
  19490. </div>
  19491. </div>
  19492. </div>
  19493. </header>
  19494. <div class="container">
  19495. <table class="table table-bordered">
  19496. <thead>
  19497. <tr>
  19498. <td>&nbsp;</td>
  19499. <td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
  19500. </tr>
  19501. <tr>
  19502. <td>&nbsp;</td>
  19503. <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
  19504. <td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
  19505. <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
  19506. </tr>
  19507. </thead>
  19508. <tbody>
  19509. {{items}}
  19510. </tbody>
  19511. </table>
  19512. <table id="code" class="table table-borderless table-condensed">
  19513. <tbody>
  19514. {{lines}}
  19515. </tbody>
  19516. </table>
  19517. <footer>
  19518. <hr/>
  19519. <h4>Legend</h4>
  19520. <p>
  19521. <span class="success"><strong>Executed</strong></span>
  19522. <span class="danger"><strong>Not Executed</strong></span>
  19523. <span class="warning"><strong>Dead Code</strong></span>
  19524. </p>
  19525. <p>
  19526. <small>Generated by <a href="http://github.com/sebastianbergmann/php-code-coverage" target="_top">PHP_CodeCoverage {{version}}</a> using <a href="{{runtime_link}}" target="_top">{{runtime_name}} {{runtime_version}}</a>{{generator}} at {{date}}.</small>
  19527. </p>
  19528. <a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
  19529. </footer>
  19530. </div>
  19531. <script src="{{path_to_root}}js/jquery.min.js" type="text/javascript"></script>
  19532. <script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
  19533. <script src="{{path_to_root}}js/holder.min.js" type="text/javascript"></script>
  19534. <script type="text/javascript">
  19535. $(function() {
  19536. var $window = $(window)
  19537. , $top_link = $('#toplink')
  19538. , $body = $('body, html')
  19539. , offset = $('#code').offset().top;
  19540. $top_link.hide().click(function(event) {
  19541. event.preventDefault();
  19542. $body.animate({scrollTop:0}, 800);
  19543. });
  19544. $window.scroll(function() {
  19545. if($window.scrollTop() > offset) {
  19546. $top_link.fadeIn();
  19547. } else {
  19548. $top_link.fadeOut();
  19549. }
  19550. }).scroll();
  19551. $('.popin').popover({trigger: 'hover'});
  19552. });
  19553. </script>
  19554. </body>
  19555. </html>
  19556. body {
  19557. padding-top: 10px;
  19558. }
  19559. .popover {
  19560. max-width: none;
  19561. }
  19562. .glyphicon {
  19563. margin-right:.25em;
  19564. }
  19565. .table-bordered>thead>tr>td {
  19566. border-bottom-width: 1px;
  19567. }
  19568. .table tbody>tr>td, .table thead>tr>td {
  19569. padding-top: 3px;
  19570. padding-bottom: 3px;
  19571. }
  19572. .table-condensed tbody>tr>td {
  19573. padding-top: 0;
  19574. padding-bottom: 0;
  19575. }
  19576. .table .progress {
  19577. margin-bottom: inherit;
  19578. }
  19579. .table-borderless th, .table-borderless td {
  19580. border: 0 !important;
  19581. }
  19582. .table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
  19583. background-color: #dff0d8;
  19584. }
  19585. .table tbody tr.covered-by-medium-tests, li.covered-by-medium-tests {
  19586. background-color: #c3e3b5;
  19587. }
  19588. .table tbody tr.covered-by-small-tests, li.covered-by-small-tests {
  19589. background-color: #99cb84;
  19590. }
  19591. .table tbody tr.danger, .table tbody td.danger, li.danger, span.danger {
  19592. background-color: #f2dede;
  19593. }
  19594. .table tbody td.warning, li.warning, span.warning {
  19595. background-color: #fcf8e3;
  19596. }
  19597. .table tbody td.info {
  19598. background-color: #d9edf7;
  19599. }
  19600. td.big {
  19601. width: 117px;
  19602. }
  19603. td.small {
  19604. }
  19605. td.codeLine {
  19606. font-family: monospace;
  19607. white-space: pre;
  19608. }
  19609. td span.comment {
  19610. color: #888a85;
  19611. }
  19612. td span.default {
  19613. color: #2e3436;
  19614. }
  19615. td span.html {
  19616. color: #888a85;
  19617. }
  19618. td span.keyword {
  19619. color: #2e3436;
  19620. font-weight: bold;
  19621. }
  19622. pre span.string {
  19623. color: #2e3436;
  19624. }
  19625. span.success, span.warning, span.danger {
  19626. margin-right: 2px;
  19627. padding-left: 10px;
  19628. padding-right: 10px;
  19629. text-align: center;
  19630. }
  19631. #classCoverageDistribution, #classComplexity {
  19632. height: 200px;
  19633. width: 475px;
  19634. }
  19635. #toplink {
  19636. position: fixed;
  19637. left: 5px;
  19638. bottom: 5px;
  19639. outline: 0;
  19640. }
  19641. svg text {
  19642. font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif;
  19643. font-size: 11px;
  19644. color: #666;
  19645. fill: #666;
  19646. }
  19647. .scrollbox {
  19648. height:245px;
  19649. overflow-x:hidden;
  19650. overflow-y:scroll;
  19651. }
  19652. svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:block;width:100%;height:100%}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:1px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{position:absolute;pointer-events:none}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.axis{opacity:1}.axis.nv-disabled{opacity:0}.nvd3 .nv-axis{pointer-events:none}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-bars .negative rect{zfill:brown}.nvd3 .nv-bars rect{zfill:#4682b4;fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups path.nv-line{fill:none;stroke-width:1.5px}.nvd3 .nv-groups path.nv-line.nv-thin-line{stroke-width:1px}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3 .nv-line.hover path{stroke-width:6px}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}.nvd3 .nv-distribution{pointer-events:none}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3.nv-historicalStockChart .nv-axis .nv-axislabel{font-weight:700}.nvd3.nv-historicalStockChart .nv-dragTarget{fill-opacity:0;stroke:none;cursor:move}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .brush .extent{fill-opacity:.3;stroke:#fff;shape-rendering:crispEdges}.nvd3 .axis line,.axis path{fill:none;stroke:#000;shape-rendering:crispEdges}.nvd3 .axis text{text-shadow:0 1px 0 #fff}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc}/*!
  19653. * Bootstrap v3.3.4 (http://getbootstrap.com)
  19654. * Copyright 2011-2015 Twitter, Inc.
  19655. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  19656. *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px)and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px)and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px)and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}�����€��pFFTMm*—Ü���ü���GDEFD������ OS/2g¹k‰��8���`cmapÚ­ã���˜��rcvt �(ø�� ���gaspÿÿ������glyf}]Âo����”¤headM/Ø��œ¼���6hhea
  19657. D��œô���$hmtxÒÇ `�����tlocaoû•Î�� Œ��0maxpj�Ø��¢¼��� name³, ›��¢Ü��¢postº£å5��¦€��
  19658. ÑwebfÃTP��±T����������Ì=¢Ï����Ðv�u����Ðvs—����������������������‹��� Ð���Z Ð��¤�2¸��������������������������UKWN�@� ÿÿÀÿ���{�������������� ����������,���
  19659. �������h�����,��
  19660. ��Ü�°���h�@��(� �+� �¥
  19661. / _ ¬ ½"#%ü&&ú' 'àà àà)à9àIàYà`àiàyà‰à—á áá)á9áFáIáYáiáyá‰á•á™ââ âââ!â'â9âIâYâ`øÿÿÿ��� �*� �¥ � / _ ¬ ½"#%ü&&ú' 'àààà à0à@àPà`àbàpà€à�ááá á0á@áHáPá`ápá€á�á—â�â âââ!â#â0â@âPâ`øÿÿÿÿãÿÚÿfÿbàßäßµßißYÞÜýÚÚÙ!ÙÙ    
  19662. þø÷ñëå|vpjdc]WQKEDÞÜÖÕÎÍÅ¿¹³���������������������������������������������������������������������������������������������������������� ����Œ�������5��� ��� ������*���+������ ��� ������¥���¥����� ���
  19663. ����� /�� /����� _�� _����� ¬�� ¬����� ½�� ½�����"��"�����#��#�����%ü��%ü�����&��&�����&ú��&ú�����' ��' �����'��'�����à��à�����à��à ���!��à��à���&��à ��à)���0��à0��à9���:��à@��àI���D��àP��àY���N��à`��à`���X��àb��ài���Y��àp��ày���a��à€��à‰���k��à���à—���u��á��á ���}��á��á���†��á ��á)������á0��á9���š��á@��áF���¤��áH��áI���«��áP��áY���­��á`��ái���·��áp��áy���Á��á€��á‰���Ë��á���á•���Õ��á—��á™���Û��â���â���Þ��â ��â ���å��â��â���æ��â��â���í��â!��â!���ï��â#��â'���ð��â0��â9���õ��â@��âI���ÿ��âP��âY�� ��â`��â`����øÿ��øÿ���õ�õ���öª�öª���
  19664. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(ø���ÿÿ���(��h ���.±�/<²�í2±Ü<²�í2�±�/<²�í2²ü<²�í23!%3#(@þèðð üà(Ð��d�dLL�[��27>32+&/#"&/.=/&6?#"&'&546?>;'.?654676X&
  19665. žjžà
  19666. 
  19667. àžjž
  19668. )"&
  19669. žjžà
  19670. 
  19671. àžjž
  19672. )L
  19673. àžjž
  19674. )"&
  19675. žjžà
  19676. 
  19677. àžjž
  19678. )"&
  19679. žjžà
  19680. ��������LL�#��32!2#!+"&5!"&=463!46ÂÈ^þ¢Èþ¢^Lþ¢Èþ¢^È^�����p��@L�E��32!2+!2++"&=!"&?>;5!"&?>;&'&6;22?69ú
  19681. þ”
  19682. x
  19683. }
  19684. x
  19685. } ” þí
  19686. x
  19687. }þí
  19688. x
  19689. vþ”
  19690. ú¤¤L
  19691. þ”   d   ®  ®   d   l
  19692. ¤¤���d�Œ®�;��2#4.#"!!!!32>53#"'.'#7367#73>76èòp<µ#4@9+820{dþÔ–dþÔ 09B49@4#®bk§Îv$B ÙdpÚd†>u®½hi-K0! .O2d22dJtB+"0J+«kuž0ªwd/5dW…%����{��L°�>�G��!2+!2++"&=!"&?>;5!"&?>;4632654&#¬^CjB0  0BjC²
  19693. x
  19694. Š
  19695. þõ
  19696. x
  19697. uþõ
  19698. x
  19699. u¶Ë@--@°$?2O*$ $*P2@%d   ¯ 
  19700. ¯   d   Û
  19701. ÈþÔBVT@���È�L¼���!2#!"&=46ú üà¼ÈÈ����È��è°�%�A��+32!546;5467.=#"&=!54&'.467>=è2cQQc2üà2cQQc2ÈA7 7A�A7 7A°–d[•##•[––––[•##•[d–Èd<c 2<2 c<––<c 2<2 c<d���������������1��ÿò,ÂA���2632#!"&5467&546÷nµ,,.xªªxýOqUBØAwa­xy­rPEk ™×������d°¯�����32!546;'&>76!'ö
  19702. ˆÓûPÔ‡
  19703. $
  19704. op zy¶Ã³#»ý%**%ê·$ ”–üp�������d°L� ��#�7��!2"'&6&546 6'&4#!"&7622?62~
  19705. ýÌýÌþø
  19706. Œ
  19707. þø\l
  19708. û‚
  19709. l¤¤L
  19710. ýÉ7
  19711. Úþøþø
  19712. &
  19713. þð
  19714. ýÚ
  19715. €þ”
  19716. l¤¤���ÿðÿðºº� � ����2'7' à&™ cÖ_"ý™Öfþþ³nº ™&\Ö`þtýšÖfüjpO�������°°���32!546;!¼úüàúþ °ŠýÚ22&&�����Lœ���%6.676.67646p…'0SFOˆ$WOHBý¨XAOˆ$WOHBù£"üÁ7Q)mr ›ý¢*`)nq&*���� ÿø»§��)���2"'#'".4>"2>4&�ȶƒNN;)þíwŽd¶ƒNNƒr°”VV”°”VV§Nƒ¶d�yþî%:MNƒ¶È¶ƒ[V”°”VV”°”��d�X¯D���>.54>‰0{xuX6Cy„¨>>§…xC8ZvxyµDH-Sv@9y€²UU²€y9@vS-H���ÿÓ�^{”���62!2'%&7%&63—ƒ�¥þª‚þ©þª‚þ¥ aþŸ ùþo ö÷ �û �ÿÓ�^{”��"��62!2'%&7%&63#7'7#'—ƒ�¥þª‚þ©þª‚þ¥óðÅJÁÃJÀêN aþŸ ùþo ö÷ �û dŽâ‹ŒåŒÓ������°°�&��2##!"&=467%>="&=46X|°>& f 
  19717. û‚
  19718.  f &>°°°|ú.hK
  19719. æ
  19720. ]
  19721. 
  19722. ]
  19723. æ
  19724. Kh.ú|°��� ����°L���#�'�+�/�3�7�G�K�O�S�W��!2#!"&54635)"3!2654&33535!3535!35!"3!2654&35!3535!35~
  19725. 
  19726. û‚
  19727. Ud£ýÚ
  19728. 
  19729. &
  19730. sdüd düd dáýÚ
  19731. 
  19732. &
  19733. üïd düd dL
  19734. ûæ
  19735. 
  19736. 
  19737. ddd
  19738. þ¢
  19739. 
  19740. ^
  19741. ddÈddddÈddddd
  19742. þ¢
  19743. 
  19744. ^
  19745. dddddÈdddd������LL���/�?��!2#!"&546)2#!"&546!2#!"&546)2#!"&5462�þpm�þpý½�þpm�þpLþp�þp�ý¨þp�þp��� ����LL���/�?�O�_�o�����32+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=462ÈÈ¥ÈÈ¥ÈÈüõÈÈ¥ÈÈ¥ÈÈüõÈÈ¥ÈÈ¥ÈÈLÈÈÈÈÈÈþpÈÈÈÈÈÈþpÈÈÈÈÈÈ�����°L���/�?�O�_��32+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=462ÈÈ¥¼ýDþ…ÈÈ¥¼ýDþ…ÈÈ¥¼ýDLÈÈÈÈþpÈÈÈÈþpÈÈÈÈ�����&�,è ��� 62"'&4?622Ñ;±üñþ€±«Ý;±üð€±«��n�nBB�#�� "' "/&47 &4?62 62ˆ²þõ ²þôþô² þõ²  ;³þôþô² þõ²  ²þõ ��ÿëÅ™��%�I���2"'#".4>"2>4&3232++"&=#"&=46;546™Ä³‚MN,mþÔwŽb´�MM�o³˜XX˜³™XXþ¼–
  19746. K
  19747. 
  19748. K
  19749. K
  19750. 
  19751. K™M‚³b�yþÕl+MM�´Ä³‚MX™³˜XX˜³™#
  19752. K
  19753. K
  19754. 
  19755. K
  19756. K
  19757. ���ÿëÅ™��%�5���2"'#".4>"2>4&!2#!"&=46™Ä³‚MN,mþÔwŽb´�MM�o³˜XX˜³™XXþX^
  19758. 
  19759. þ¢
  19760. ™M‚³b�yþÕl+MM�´Ä³‚MX™³˜XX˜³™‡
  19761. 
  19762. ������™°��-��32+"&5465".5472>54&&dd§Ò[›ÖêÖ›[Ò§g|rÅèÅr|°þp�á¦>þÙ¸uÖ›[[›Öu¸'>¦7ÈxtÅrrÅtxÈ��d��°°���/�?��32+"&54632+"&54632+"&54632+"&=46–
  19763. 
  19764. þÞ–
  19765. 
  19766. þÞ–
  19767. 
  19768. þÞ–
  19769. 
  19770. °
  19771. û‚
  19772. 
  19773. ~
  19774. þp
  19775. ý
  19776. 
  19777. þÔ
  19778. þ>
  19779. 
  19780. È
  19781. ú
  19782. 
  19783. ú
  19784. ������––�G�O��27'#"/&/&'7'&/&54?6?'6776?6"264X!)&1-†=+P˜˜P08†,2&+!)&1-†<,P —— P/:…-1&+x²~~²~–˜P09†,1&+"(&1,†=,Q——Q09†-0&* !(&0-†=,P˜þ™~±~~±��d��°���!�%�)�-�1��!2!2!5463!546!5#!"&53333333ô,);
  19785. û´
  19786. ;),,;)ýD);dddddddd;)d
  19787. KK
  19788. d);dddþÔüà);;) dýD¼ýD¼ýD¼ýD¼�� ��Ñ���62++"&5!+"&5#"&l`
  19789. ¯
  19790. ú
  19791. þÔ
  19792. ú
  19793. j`ý 
  19794. ýÁ
  19795. 
  19796. wþ‰
  19797. 
  19798. ?
  19799. ��d��è°����3!#!"&5463#"&=X;),üàRú°þp);ývLþpú���™™���0���2".4>"2>4&3232+"&546ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrþ|2
  19800. 
  19801. ú
  19802. ™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅ 
  19803. þí
  19804. 2
  19805. 
  19806. ^
  19807. ����ÿœ��°� ���)#!3333ýæ)ò)ýæ¯Ñ¢Ðþžà�þp°þÔ,þpþÔ,�����d��°°��/��3232"'&6;4632#!"&546;2!546&È¿ þ¹ & þ¹ ¿T2
  19808. 
  19809. ûæ
  19810. 
  19811. 2
  19812. „°þ>þp�Âüà
  19813. þ¢
  19814. 
  19815. ^
  19816. 
  19817. ¯¯
  19818. ���™™���1���2".4>"2>4&3232"'&6;46ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrþ|–
  19819. ‰
  19820. ß & ß
  19821. ‰™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅ 
  19822. þíþí
  19823. �����™™���1���2".4>"2>4&%++"&5#"&762ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrþçß
  19824. ‰
  19825. ‰
  19826. ß &™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅþíþí
  19827. 
  19828. ��������°°��9��!2#!"&'&547>!";2;26?>;26'.áî
  19829. º û´ ¹—ýÔ
  19830. W
  19831. &
  19832. ú
  19833. &
  19834. W°
  19835. ýtþW  ©Œ
  19836. È þ> 
  19837. ˜
  19838. 
  19839. ˜
  19840.   ���™™���'���2".4>"2>4&&546ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrþ‹ýý™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅ]¾ $ ¾ � ���™°�(��76#!"&?&#"2>53".4>32³‡ 
  19841. þ– …m�tÅrrÅèÅr–[›ÖêÖ›[[›ÖuÀ$‡ þ–
  19842.  …LrÅèÅrrÅtuÖ›[[›ÖêÖ›[������™°��5��76#!"&?&#"#4>323#"'&5463!232>³‡  þ— †n�tÅr–[›ÖuÀë–[›ÖuÀœ†  h
  19843. …n‚tÅr$‡ þ—  †KrÅtuÖ›[ý¿uÖ›[v†
  19844. h  …LrÅ���
  19845. �d��°°���/�?�O�_�o����Ÿ��!2#!"&546!"3!2654&32+"&=463!2#!"&=4632+"&=463!2#!"&=4632+"&=463!2#!"&=4632+"&=463!2#!"&=46}
  19846. 
  19847. ûæ
  19848. Àü®
  19849. 
  19850. R
  19851. ý2
  19852. 
  19853. 2
  19854. ÒÂ
  19855. 
  19856. þ>
  19857. ¾2
  19858. 
  19859. 2
  19860. ÒÂ
  19861. 
  19862. þ>
  19863. ¾2
  19864. 
  19865. 2
  19866. ÒÂ
  19867. 
  19868. þ>
  19869. ¾2
  19870. 
  19871. 2
  19872. ÒÂ
  19873. 
  19874. þ>
  19875. °
  19876. û‚
  19877. 
  19878. ~
  19879. È
  19880. ü®
  19881. 
  19882. R
  19883. d
  19884. 2
  19885. 
  19886. 2
  19887. 
  19888. 2
  19889. 
  19890. 2
  19891. È
  19892. 2
  19893. 
  19894. 2
  19895. 
  19896. 2
  19897. 
  19898. 2
  19899. È
  19900. 2
  19901. 
  19902. 2
  19903. 
  19904. 2
  19905. 
  19906. 2
  19907. È
  19908. 2
  19909. 
  19910. 2
  19911. 
  19912. 2
  19913. 
  19914. 2
  19915. ��������L°��#��54&#!"#"3!2654&#!546;2„uSþÔRvd);;)„);;)ý¨È ÈSuvRÈ;)ý¨);;)X);––��d��LL� �7��32#462#".'.#"#"'&5>763276}2
  19916. dÀ!C@1?*'),GUKx;(.9)-EgPL
  19917. ûÍ3
  19918. 0þ[;P$ 9¶7W W������°—�!�1�A���2+"&54. +"&54>32+"&546!32+"&546äèÞ£c
  19919. 2
  19920. �äþúä�
  19921. 2
  19922. c£*    `    —c£ÞtþÔ
  19923. 
  19924. ,ÑrrÑþÔ
  19925. 
  19926. ,tÞ£ýÀ þ4 Ì þ4 Ì �������ÓGÝ��9��%6'%&+"&546;2762"/"/&4?'&4?62A þþú
  19927. 
  19928. úXx"xx"xx"ww".¬
  19929. ý
  19930. ¬
  19931. ^
  19932. „x"xx"ww"xx"�������ÓrÝ��/��%6'%&+"&546;2%3"/.7654'&6?6A þþú
  19933. 
  19934. úÒ
  19935. `Z  HN.¬
  19936. ý
  19937. ¬
  19938. ^
  19939. d �¡š g~„j�������Äbì��1�K��3#"/.7654&'&6?6%6'%&+"&546;2%3"/.7654'&6?6Ç ‡D@
  19940.  *o;7 *ý‚ þþú
  19941. 
  19942. úÒ
  19943. `Z  HNì ³ÙiËT "–²Z¬G !¾¬
  19944. ý
  19945. ¬
  19946. ^
  19947. d �¡š g~„j���� ����°°� ����!�%�-�;�?�C�G�K�O��3#!#!#3!##5!!!!#53#533!3533##5#535#5!!#53#53#53!5!ôddþpdô¼ÈÈþÔÈdXû´,�,üàdd¼ddýDÈþ ÈdôÈdÈddÈ,ýD,ddd„ddþ ddôþÔ,„dddXþ dÈ,,ÈdþÔ,þÔ,Èdddþ þ ôdþÔddddÈdÈþÔ,ÈdddþÔddd���� ����°°��� ������#��7#3#3#3#3#3!5!#53#53#53dddÈdd�ÈÈÈdd,ÈÈüàþÔ,ÈddÈdd,ÈÈÈèüèüèüèüèûPdd[[[[[�����
  19948. ¦°� ��� "'463&"26ôªþ0ýV
  19949. C;S;;S;°ýVþ0ªÛ
  19950. Í;;T;;�������
  19951. Ò°� ��!�� "'463!"/ &"26ôªþ0ýV
  19952. ªþ08¨ýDþÓ;S;;S;°ýVþ0ªÛ
  19953. ýVþ08ª¼Í;;T;;�����d��°°�&��!2&54&#!"3!2#!"&54?6,9K@
  19954. 
  19955. ýD@
  19956. 
  19957. ü®
  19958. ‹°Kü|@
  19959. @
  19960. 
  19961. üJ
  19962. 
  19963. Ï‹����ÈÿÿL°�
  19964. ��!2 46ú þ>þ>°û‚¼þC��������°°��E�U��!"3!26?6'.#"#!"&/.+";26=463!2;2654&!"3!26/.6þD N9
  19965. >SV–
  19966. N
  19967. ýÚ
  19968. N
  19969. 
  19970. 
  19971. 
  19972. þ±þ
  19973. &
  19974. X
  19975. &°
  19976. þÓl l-
  19977. þp œ œ 
  19978. ýv
  19979. 
  19980. 
  19981. 
  19982. ý¨
  19983. ˜
  19984. 
  19985. ˜
  19986. �������d°L��!�)�1��3232#!"&546;>35"264$2"&4ôÈ8]4$–);;)ü);;)– '3]ÈdþϾ‡‡¾‡þïV<<V<L);;;)ý¨);;)X);E5+þÔddF‡¾‡‡¾<V<<V�����5��°¯� �#�� !526/!3!567>?!©�(%
  19987. þ_5,Rþy:" *2þ“8 �¬T¢¯ü2*BBW-Þ‘Y". BB % îýZÉ�����d��ð°�'�2�;��#!5>54.'52%32654.+32654&+ñ50;*7Xml0þ ); !×9uc>--þ�‹Ni*S>vØPR}^Ÿ�3:R.CuN7Y3(;  G)IsC3[:+ 1aJ);4ü®ePZ����È��o°���!56764.'&'5mSB„ ,Jþ º­  °95(ü¹1(aaR@ 9����ÿµ��°�%�/��#4.+!52>5#"#!#3'3#72 &È2þp"È& 2èû›KK}}KK}„ ü®dd R ,Èü১ §��!ÿµ�°�%�/��#4.+!52>5#"#!5!'7!5L2 &È2þp"È& 2èC§ü১ „ ývdd Š ,û‚}KK}}KK�����°L���/�?��!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=462Xý¨èü üàLû´LddþÔddþÔddþÔdd�����°L���/�?��!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=46ú¼ýD³Lû´Ý¼ýD³Lû´LddþÔddþÔddþÔdd�����°L���/�?��5463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&ôXý¨þpèüÈ üàþÔLû´¶ddþéddþéddþédd������°L���/�?��!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=462Lû´Lû´Lû´Lû´LddþÔddþÔddþÔdd�����°L���/�?�O�_�o���32+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=462ddA üàþéddA üàþéddA üàþéddA üàLddddþÔddddþÔddddþÔdddd��ÿœ��°L���#�*�:�J��!#;2+"&=46!2#!"&=465#535!2#!"&=46!2#!"&=46�dd–ddôþ þú§ÈÈÂ,þÔXý¨LddþÔddú}KdK¯ddþÔdd�������L���#�*�:�J��32+"&=46#3!2#!"&=463#'7!2#!"&=46!2#!"&=462ddgddü®ôþ /Èȧ§ûæ,þÔXý¨Lddû´LþÔddÈdK}}¯ddþÔdd�������È°è����!2#!"&546 Kî,,ý,,„þÔ,è,ýv,,Š,ýD,,�����°L�����!2#!"&5467'2"&4,Xû¨J÷*J%ìüÒpNNpNLü ôdý¶ƒœ>þàôtNoOOo�����Û�6‘����2.'&54>"264ˆuÆsFE²66 !^Xm)<DsŸ··‚‚·‚‘xÊus�mé?>!fh˜H„uX£yH¸��¸�����™™�����2".4>"ãêÖ›[[›ÖêÖ›[[›KtÅrrÅ™[›ÖêÖ›[[›ÖêÖ›üoVrÅèÅr���u�ß��5��.54>6?6&'.'&76#&*IOWN>%3Vp}?T›|J$?LWPI¼)(!1 )  H�uwsu‡EG€^F&:c—YE‡vsxv�ýþ!K‚:%A'# "
  19988. A)Y¶ �������Ël� �*�/��7>%!2!"3!26=7#!"&546 7èl
  19989. lý�27»þ�);;)ô);È»£þp¥¹¹8þ–¡7cõs*
  19990. sÈ »;)þ );;)¶Èþ´¥¹¹¥�¥¹þ×þ–2ªc�����“L��6��!#"3!2657#!"&546&'5&>75>^i¤4Ã);;)ô);ȹ¥þp¥¹¹Sþ¬ 9dTX
  19991. .9I@F* L’6;)þ );;)™g¥¹¹¥�¥¹þÓþÎ Ë 0!;bA4Ò
  19992. ���������L��5��!2!"3!26=7#!"&546 62"/&4?622^^<C²þ£);;)ô);ȹ¥þp¥¹¹Ê‹eýíøeoL±;)þ );;)EÈÛ¥¹¹¥�¥¹þ3‹eýìøeo����
  19993. ¦¦�;�� 62+3546&=#32"'&6;5#'&47635#"&>
  19994. ªÈ
  19995. þø
  19996. Ȫ
  19997. þüþø
  19998. ¯È
  19999. þø
  20000. ȯ
  20001. –þø
  20002. È­
  20003. þüþ÷
  20004. ­È
  20005. þø
  20006. È­
  20007.  
  20008. ­È
  20009. ��È��„L���326'+"&546údÐþ0dLþJÅüÅþJè�������°L�#��3266''+"&5462dÐÐþ0þ0dLþJÅþJÅüÅþJÅþJè������°3���''&4766°þ0þìÐüÅþJà*àþJÅ����È�36� ��&546ó.üÒ2þ  þ è��È�d„è����32+"&546!32+"&546úÈÈ¥ÈÈèüà üà ���È�dLè���#!"&5463!2Lüà ¶üà �������3���46&5&546ôìþþ0d¶þ *þ ¶þ;è��ÿþ�³O�#��72#"&5&5&5464646ddþ1þ2ÒÒNüµþ: µþ9 è þ>¶ þ=¶��,��èL���32+"&5&54646Rddþ0ÐLü¶þ;èþ;¶���d�È°H� ��� #!"&762!2#!"&=46®õ ûî õ*ý÷èü9ýäýHdd��ˆÿüuJ���  uþ `ÅýØ(„þŸþŸÆ(&����;ÿü(J��� ' 7(ýÙÆaþŸÆ#ýÙÆaaÆ���™™��3���2".4>#"#";;26=326=4&+54&ãêÖ›[[›ÖêÖ›[[›}d––d––™[›ÖêÖ›[[›ÖêÖ›º–d––d–������™™�����2".4>!"3!26=4&ãêÖ›[[›ÖêÖ›[[›Eþ ô™[›ÖêÖ›[[›ÖêÖ›þ~dd���™™��3���2".4>"'&"2?2?64/764/ãêÖ›[[›ÖêÖ›[[›å xx  � xx �  xx  � xx �™[›ÖêÖ›[[›ÖêÖ›­ xx �  xx  � xx �  xx  ����™™��$���2".4>'&"2764/&"ãêÖ›[[›ÖêÖ›[[›T‹òw‹™[›ÖêÖ›[[›ÖêÖ›þ1U‹ñw‹������™™��;�K���2".4>";7>32";2>54.#";26=4&ãêÖ›[[›ÖêÖ›[[›?<B2!ƒ  ­(#"3D<:–
  20010. 
  20011. ™[›ÖêÖ›[[›ÖêÖ›‘ /O2*(8\6/H* ýã
  20012. 
  20013. ����™™���>���2".4>#";26=4&#";#"3!26=4&+4&ãêÖ›[[›ÖêÖ›[[›––
  20014. 
  20015. 
  20016. ú
  20017. 
  20018. KK
  20019. 
  20020. ^
  20021. 
  20022. K™[›ÖêÖ›[[›ÖêÖ›V
  20023. 
  20024. þÔ
  20025. 2
  20026. È
  20027. 2
  20028. 
  20029. 2
  20030. 
  20031. �����°°�/�_��3232++"&=.'#"&=46;>7546+"&=32+546;2>7#"&=46;. –
  20032. g—Â
  20033. 
  20034. —g
  20035. g—Â
  20036. 
  20037. —g¹
  20038. Df¨
  20039. 
  20040. ¨fD
  20041. Df¨
  20042. 
  20043. ¨f°
  20044. —g
  20045. g—Â
  20046. 
  20047. —g
  20048. g—Â
  20049. þͨ
  20050. 
  20051. ¨fD
  20052. Df¨
  20053. 
  20054. ¨fD
  20055. Df���™™���?���2".4>"2>4&"/"/&4?'&4?62762ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrš@||@||@||@||™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅZ@||@||@||@||�����™™���0���2".4>"2>4&"/&4?62762ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrƒjþÀÊjOÅ™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅ}jþ¿ËjOÅ�����™™���!���2".4>"&32>54ãêÖ›[[›ÖêÖ›[[›KtÅrAKiõý¸hstÅr™[›ÖêÖ›[[›ÖêÖ›;rÅtxiKAÐý¸>rÅts������S°ù���6!2#!'&4'
  20056. &ýÚýöF«
  20057. þÝÈþÝ
  20058. « &�������S™ù��� &5!"&=463!46
  20059. ýöýÚ&ñþU & þU
  20060. #È#
  20061. ����·��]™��� #!+"&5!"&762ª«
  20062. þÝÈþÝ
  20063. « &‰ýöýÚ&
  20064. ����·�]°���32!2"'&63!46&È#
  20065. þU & þU
  20066. #°ýÚýö
  20067. &�����·™]��� &5>746
  20068. ýö^°¥�$,[‡Ç~UþU & þU
  20069. #$DuMi±�qF
  20070. �����°°��+��!2/"/&4?'&6!"&546762R,^ùjù^þ!þÔ^ùjù^°þÔ^ùjù^ûP,^ùjù^����I�Igg��+��#!"&546762!2/"/&4?'&6öjù^þÔ^ùý ,^ùjù^`jù^,^ùýñþÔ^ùjù^������™™���/���2".4>#";2676&#";26=4&ãêÖ›[[›ÖêÖ›[[›³Ð:#6#:1–
  20071. 
  20072. ™[›ÖêÖ›[[›ÖêÖ›ºþÒ.þ 
  20073. 
  20074. ��������°°�I�U�a�h�o��276?67632;2+"!#!54&+"&=46;2654?67>;26/.'&;26!"&5)#! Ä &Ä0 
  20075. =
  20076. 
  20077. 2
  20078. þpÈþp
  20079. 2
  20080. 
  20081. =  �¦
  20082. Û
  20083. 3þ5±3
  20084. ç þ‰
  20085. �X
  20086. þ‰°
  20087. v  v
  20088. !{, 
  20089. 2
  20090. 
  20091. ¯,þÔ¯
  20092. 
  20093. 2
  20094. 0€y¢
  20095. 
  20096. ª�
  20097. 
  20098. ür
  20099. wþ‰
  20100. �������� ¯¦�+�I��6.'&&&547>7>'.>7>&67>7>7>�-Bla‹bŽD8=3™*U  :1'Ra\‡{À%&¢=>8\tYR-!Šq[Fak[)¦²þÝÈ•X1 ™"@&J<7_…?3J5%#/D &/q!!6ROg58<'([@1%@_U2��]�rÏ�O��.>7'&767>.'&'.'&>77>.'&>�'
  20101. '8GB 
  20102. 
  20103.  `ŠH  >JS>H7 '+" NA
  20104. 5M[`/Pg!;('2"&"IbYÏC€e\D9$ 886#1%)*ƒ‘§—J7gG:    8G\au9hªoK$œ]54<<E"5cQ8 .@AU!U™hQ)����ÿÜ�jÔF��?�Q���2".4>&"&5476&2>76&'&6?6&'&'.¤�{nO9:On{�¢�{nO:9On{°ø°FZ  2Z_ƒˆƒ_Z2  Zýÿ# %8-#,- "F-I\b\I*I\b\I--I\b\I*I\b\IÜ9>|°°|;7Es1$F^D10E^E$1u$/D0 "%,I���ÿÜ��Ô°��'�;�L��!#7.54>327377>76&'&%7.5476&6?'&'.P”[©vY,9On{�R=A ”&/l‰'Pj˜R.Mv&  6ýQFZ  *HLh5)k�|# %8- ,- "xatzbI\b\I-yþRµUÖ4Zrnc­1ˆ?1FrEs1<QA9 š§n;7p$/D0  V,I���ÿž��«� ��(��'6#!"&%!546;2!32+"&/&6Z‚8‚%úò%
  20105. Y
  20106. YþChÐ:#6#:d*!ûà GD„K
  20107. 
  20108. KÓßüü����d�°°�(���2'%/&=47&=4674L|Xkþ™dÍÍdþ™k°X>þ­þ»1) ùþù]@ €€ @]ù )1ES>�������L°��'�+�/�3�7�;�?�C�G�K�O�S�W�[�_�c��3232!546;546;2!546#!"&5353353353353353533533533533535335335335335Rd2û´2dôüddddddddddü|dddddddddü|ddddddddd°2––222þpýîÈddddddddddÈddddddddddÈdddddddddd������w—��%�7��&=#!"&=46;3546'#"&=463!&=#'73546oùùŸý¨þÝÑXñý©�zÑ#ùùñµ�zŸ�æ*æ–ý¨dX–þ˜�zdþMæ*æ–µ�z–�������°L���!2#!#"&546dè);;)ý¬þÐd);;L;)ý¨);þÔ,;)X);����d��L°� ��?��32!546!32!546".5!2>&54=–ÈþÔÑÈþÔ(LfœÀœfL(, '6B6'°úúúúþpþÔ)IjV\>((>\VjI),ú +'%! !%'*ú���ÿÿ�ÔLÂ��� 'LÆþŸþŸÅ'›ÇaþŸÇ'����îMÜ��� 7 MýÚýÙÆaaýÙ'ÇþŸa����ÿQ�d_è��)��!232"/&6;!%+!!"&5#"&?62”ê–æ*æ–þƒþæ–�×ý–æ*èýÙùù‘¸ùþpÈ&ù�����ž°�0��32!2#!!2+"&=!"&=#"&/#"&468^&€d,!ý‡02*þÔ*É6°¢%þ%+È*2222
  20109. Á*��������°L� ���!53463!2!!°ûPÈ;),);ýD°ûPèdd);;)Èüà�����ÜL� ���3463!2!!ÈÈÈ;),*:ô,þÔûP, þpX);;)ÈdýD¼�E��k¯���+32"/&6;#"&?62{æ––æ*æ––æ* ùý§ùùYù����D¯k���&=!/&4?6!546¨ùùý¨ùùX`å)å —— å)å •• �������°°� ���!��.#!"!"3!26=4&53353‘¬$ý`$¬-ü);;)è);;þ«ddd�Ü-(ýd;)d);;)d);Èdddd���ÿœ�d°L� �#�1���2"&54%##"+"&'=454>;%".=4>7i**dý]&/T7 È£ü" Lü®Rü™ÈþìQú úþÔú )2( ����J��f°�,�5��3232#"./.46;7>7'&6327"&)^Sz?vdjŸO9t\U>/ v?zS$2451 7F8°%Mþ¹­)( 
  20110. ()­GM~ û¾1==���œœ���7'''7'7'7'77 àNê´´êNà-››-àNê´´êNà-››²Nà-››-àNê´´êNà-››-àNê´´����d°°�!�-�=��32!2+"&/#"&54?>335!7532+"&546Š2(<H(<î,úF=-7‘` 1d–dˆÖúþ>2ývdd°Q,–}Q,d-þ¨!2$'�$ÄÆ(dÔÕþ‰dw}á¯þÔþ ô��������°L� �0�<��32#!+"&/&546;632+"&546!#35'!5Xú,î<(þ¸<(21 `‘7-=|ýédd_ˆd–d22ÂúL!þ¨-d,Qv–,Q(ÆÄ$�'$ddþ ôdþ‰ÕÔ¯á}w����dO��7�G��%6!2+#!"&5467!>;26&#!*.'&?'32+"&546dkn  T.TlnTjƒþª¦:d%ƒËþ8
  20111.   ’VýOddiæp &yL�Nþ­(¢  %
  20112. Hþ YS(22·Säþ ô���ÿœ�d°O��6�F��#!"&'#"&463!'&6?6*#!32!7%32+"&546Ûn ¬þªƒjUmlT.U  nJ’  
  20113. þ%Ý‚&jþªPddOæ ýó ¢(SN�Ly& p®·d(þ­Y÷ìäþ ô����a��L��7�G���2#!"&/&?>454&/!7%.!2#!"&=46Þ�NS(¢ ýó%
  20114. æp &yÆ22·Sì÷Yþ­(–ôþ nTjƒþª¦kn  T.TÖËþ8
  20115.   ’Vþ­d%ƒý dd�ÿý�è��-�I��!26=4&#!""&5&/&7>3!2766=467%'^ôþ N�Ly& pæ  ¢(ý‰ìS·22(SYLddüæjTnlT.T  nk ¦þªÏþ­V’  
  20116. þ8˃%d���šš��%���2".4>%&!"3!7%64âìÖ›[[›ÖìÖ›[[›†þíþí
  20117. 
  20118. š[›ÖìÖ›[[›ÖìÖ›þ9ß
  20119. ‰
  20120. ‰
  20121. ß &����šš��%���2".4> 6=!26=4&#!54&âìÖ›[[›ÖìÖ›[[›%þí
  20122. 
  20123. þíš[›ÖìÖ›[[›ÖìÖ›èß & ß
  20124. ‰
  20125. ‰
  20126. �����šš��%���2".4>&";;265326âìÖ›[[›ÖìÖ›[[›Kß & ß
  20127. ‰
  20128. ‰
  20129. š[›ÖìÖ›[[›ÖìÖ›þ@þíþí
  20130. 
  20131. ����šš��%���2".4>#"#"276&+4&âìÖ›[[›ÖìÖ›[[›—–
  20132. ‰
  20133. ß & ß
  20134. ‰š[›ÖìÖ›[[›ÖìÖ›»
  20135. þíþí
  20136. ����˜˜��–�¦���2".4>%&277>7.'.'"'&65.'6.'&767>'&>7>7&72267.'4>&'?6.'.'>72>äèÕ›\\›ÕèÕ›\\›d+:
  20137. =?1 " "/ ?9 #hu!$ 0 E.(,3)  (    
  20138. *!A 7 ,8 !?*
  20139. 
  20140. ˜\›ÕèÕ›\\›ÕèÕ›  ' "r"v G
  20141.  .&*
  20142. r$>   #1 
  20143.   %  *
  20144.  '"  $  g2( %
  20145. �������¯…���67'"/&47&6ô¤Žþý‘ûPM<†;ý¬+oX"O…\eŠè~Y‡+" ý¬n+WeÉ����`°¬���#�'�7�;��!2#!"&=46#3!2#!"&=46!!!2#!"&=46!!dè);;)ü);;ÈÈüè);;)ü);;þ ôüè);;)ü);;þÔ,¬;)d);;)d);ddÈ;)d);;)d);ddÈ;)d);;)d);dd����d��L°� ���!2#!"&46!–„ü|;Èþ¢„°**ýDþÔÈôô������d°°���%��32!2!5#!463!54635#!"&=ôÈ);,);þ Èþ ;),;)Èô;)ü);°;)d;)þpdd�);d);dddýDÈ);;)È�������°°��+�A�W��!2"/&546)2/"/&4?'&6#!"&54676276#!"&?'&4?622,^ÇjÇ^5,^ÇjÇ^þ/jÇ^þÔ^ÇË^þÔ^Çj°^ÇjÇ^,þÔ^ÇjÇ^ý&jÇ^,^ÇÎ^þÔ^Çj�������¨¨���#�;�C�K���2".4>"2>4&$2"&4$2#"'"&546?&542"&4$2"&4ÛòÝŸ__ŸÝòÝ ^^ Æà¿oo¿à¿ooþ-- - L- 73H3)z þ‡- - - - ¨_ŸÝòÝ ^^ ÝòÝŸWo¿à¿oo¿à¿ -!!- -!
  20146. ‘$33$ 1~¤ - - - -�ÿØ�Z¹¼�[��%676&'&#"�3276'.#"&47�7>32#"&'&6767632'."Õ[v_"A0?! þˆ-  Y7J3$$ þ«)G"#A.,= # (wn‹kV8@Fv"0DÿG([kPHNg8Bþ*­Ö[eb›2!þ‰5(7>B3$$' þ®)M"#!7)/c# *xn‰fL@9N¾DÿH7!$†W]µBþ$&����d�X¯D��D��>.54>"".#"2>767>54&‰0{xuX6Cy„¨>>§…xC8Zvxy#!?2-*!')-?"CoA23:+1! "3)@ +)?jµDH-Sv@9y€²UU²€y9@vS-H-&65&&56&oM8J41<*.0(@  )*D*2Om��9ÿòw¾��.���2&/7'/&477"/&4?«»B�B8"._÷þ{Ôi�BBi
  20147. �BBþåBºB�BB7._÷…¾B�B^*k"5._øþ{Ôj�BºBþFi �BºBþåBB�B»B77/_ø…�����È��è°������2#!"&54>!�"264ªšd:;)ý¨);<f>XþÿV==V=°.2üG);;)¹3-ªýD¼ý=V==V�����°°��� "/''!'&462†*$þéÔþÌþèË3Ò, #*¡þæ*#þõþÔÒþÍË4Ô$*����'� à�2�@�K��#.'#5&'.'3'.54>75>4.¼&ER<,Ÿ 3'@"<P7(²›d–W(‹WJ.BN0 2Uh:**& h)1"37àN,?iB$.,þÍ -<d>‹ª MOW(kVMbO/9X6FpH*Mþ6&+ÐþÊ  4C4%����d�f”­�J��2#4.#"3#>36327#".'>7>'#53&'.>761T™^™'<;%T)ñÅ-6"b Œ"S5268 jt&'V7  0 $ݦ
  20148. -$a­P‹N(?",9J0* d2‚>2
  20149. "“" ‘ 
  20150. 7�Gd/9+DAL!X����ÿÿ—°����32"/&6;3+##"&?62�–æ*æ–Èæ–È–æ*,úú„ùü|„ù���ÿÿè°����%��#5##!32"/&6;3353!57#5!èddd,ý¨–æ*æ–È‘dcÈÈþÔÈÈ,¼ddôü|úú„dÈÈýúd–úd�����ÿÿè°���!�%��32"/&6;33!57#5!#5##!35�–æ*æ–ÈXÈÈþÔÈÈ,ddd,Çd,úú„–úd–údûPddôdÈÈ����ÿÿL°������32"/&6;3##53#5#!35�–æ*æ–ÈXddÈddÈ,Çd,úú„þ �dûPd�dÈÈ�����ÿÿL°������32"/&6;3#5#!35##53�–æ*æ–ȼdÈ,ÇdddÈ,úú„þ d�dÈÈû´�d�����ÿÿ°°�������32"/&6;3#53!5!!5!!5!�–æ*æ–ÈôÈÈdþÔ,dþp�dþ ô,úú„ÈÈþ Èþ Èþ È��ÿÿ°°�������32"/&6;3!5!!5!!5!#53�–æ*æ–È þ ôdþp�dþÔ,dÈÈ,úú„ÈÈþ Èþ Èþ È�����LL����!2#!"&546!"3!2654&^�¢¼»£þp¥¹¹gþ );;)ô);;L»£þp¥¹¹¥�¥¹È;)þ );;)ô);��������LL���+��!2#!"&546!"3!2654&&546^�¥¹¹¥þp£»¼dþ );;)ô);;þoýýL¹¥þp¥¹¹¥�£»È;)þ );;)ô);‚¾ $ ¾ � ��������LL���+��!2#!"&546!"3!2654&!2"/&6^�£»¹¥þp¥¹¹gþ );;)ô);;þ� ¾ $ ¾ L¼¢þp¥¹¹¥�£»È;)þ );;)ô);Èýý�������LL���+��!2#!"&546!"3!2654&#!"&?62^�¥¹¹¥þp£»¹gþ );;)ô);;þû¾ þp ¾ $L¹¥þp£»¼¢�¥¹È;)þ );;)ô);Ïýý��������L��5��!2#!"&=463!2654&#!"&=46&=#"&=46;546&�¥¹¹¥þpÂ);;)þ>¿Dþ¼úúL¹¥þp¥¹d;)ô);déþä&þä
  20151. –È–
  20152. ���Ù�מ�#��%2"+'&7>?!"'&76�6763 ˜,þ÷þó  P''þÒ
  20153. K » ž
  20154.  þS#þÊþÅ  ånnV/Ó�������þL��5��!2#!"3!2#!"&546&=#"&=46;546^�þ>);;)Âþp¥¹¹ñDþ¼úúLd;)þ );d¹¥�¥¹éþä&þä
  20155. –È–
  20156. �����°°��1��!2/"/&47'&6#"3!26=7#!"&5463!î�mþÈ)�8mþïœ);;)ô);È»£þp¥¹¹¥,°þpmþÈ�)8mþÔ;)þ );;)”ÈþÖ¥¹¹¥�¥¹����¢¢���#���2".4>"2>4&2"&4áîÙ�]]�ÙîÙ�]]�ÃæÂqqÂæÂqqþ{ rr r¢]�ÙîÙ�]]�ÙîÙ�GqÂæÂqqÂæÂsr rr ������L°���#��3232"'&6;46!2!54635ÂÈõ
  20157. þ�' þ… úþ…èû´gd°þ¢þVª^ü|úúd22�������L¬���#�� ++"&=#"&7>!2!54635Gz
  20158. ô"Èú 'ýùèû´gdžþM úú!¯üúúd22�����LK���"�� 62"'&4?62!2!54635Œq‹ýóþÜ‹Ôèû´gdÓq‹ýó#‹ýÒúúd22�����L›� ��#�'��762'&476#"&?'7!2!54635‡Ž*MÔMÒý«КÔþ=èû´gdÿŽMÔL*šÒý©ЛÔý:úúd22�������L°���#�'��/'7'&6"/&4?!2!54635^WЛԛÒÃL*ŽMþúèû´gd°ý«КԚÒýPMŽ*MþXúúd22��ÿì°¯����% ! °þþÆþq¬ý3«gþq§üùæ¹�������dL°����+!#"&546;!3#53L–ýD–úôdÈddèü®�þpèþÔ,ÈÈ�����EÝ°���/��'&"!#"&546;!3#53"/&4?6262LþÕ_  •þÈ–úôdÈdd°jþ\ÊjO)è•þÕ_ “þpèþÔ,ÈÈýÎjþ[ËjO)���� °���>��'.!#"&546;!3#53"/"/&4?'&4?62762Lg†%þöþ·–úôdÈddöFƒƒF)ƒƒ)FƒƒF)ƒƒ)èþóg†þöþpèþÔ,ÈÈýŒF)ƒƒ)FƒƒF)ƒƒ)Fƒƒ�����—°���/��!"!#"&546;!3#533232"/&6;546Lþ¢þ –úôdÈdd–d–æ*æ–èþÔ–þpèþÔ,ÈÈý¨úææú��������—°���/��'&"!#"&546;!3#53++"&=#"&?62L¥*þùþn–úôdÈddëæ–d–æ*èþp¥þ÷þpèþÔ,ÈÈý…åúúå����È°L� ����!2!546#!"&5!52LûP“û´d�L––þÔýÚ&þÔÈÈ����}­—����-�1�;��&=!5!546#"&=46;#5376!!/&4#5;2+§øøþp�ý/22Èddþ‚÷�þp÷�ddd33�æ*æ–È–þ…dÈÈýËæ–È–æ*yÈd�����d��°°��Q��%6+"&5.546%2+"&5.54>323<>3234>^%È"%þá
  20159. È"
  20160.  d d 1tû®�5gD‘ þ>?1) þA¿..@  þ¢^  þ¢^ ��d��°L�3��"!5265!3!52>54&/5!"!4&#5°"2þpKþ Kþp"2�KôKL8
  20161. üˆ88 %Šþv% 88
  20162. x88 %þvŠ% 8�������LL� �� �$�(�4��!2#5'!7!!2#!"&546!55%!5#!!'!73£wiþÙÈþpdwþ%,);;)þÔ);;),¼þp�ü,¼þ‰dþ‰d�Èiè–bbÈdÈ;)þ );;)ô);dÈÈþ÷…£…ÆÈÈføddÈ���ŸŸ�&��767>".'.7¢.‹wfü�w3À£ .1LOefx;JwF2 ï¢Â1vŽüevˆ/¢ 5Cc;J™|sU@�������°L�#�A���2/.=& &=>2#!"&=46754>ü¸¦ud?, Ê�þÂ�Ê 1;ftÊpR&mû´m&L!(("
  20163. È""’’""È '$+ þä
  20164. 2þÑ2ÔÔ2/2 !������°°� ��'��!'3353353!2+!7#"&46!2!546LÈý¨ÈÈÈÈÈÈü®¼ ‰üJ‰ ³LûP¼ÈÈôÈÈÈÈüà*dd*þÔ22����d��°L� ����#"!4&#"!4&!46;2¼d);,;gd);,;ýþÔ;)d);L;)üè);þÔ;)ýD¼);üà�);;)����ÿœ��°L����%�)��!2#!"&546!#3!535#!#33ȼ|°°|ýD|°°„þ ÈÈþÔÈÈ,�dÈÈddL°|þ |°°|ô|°ÈýD¼ÈdþÔdd,dþÔdôdþÔ,���ÿœ��°L����%�)��!2#!"&546!#5##3353#33ȼ|°°|ýD|°°„þ dddddd�dÈÈddL°|þ |°°|ô|°ÈýD¼ý¨ÈÈôÈÈdþÔdôdþÔ,�ÿœ��°L����#��!2#!"&546!#3!!#3!!ȼ|°°|ýD|°°„þ ÈÈþÔ,�ÈÈþÔ,L°|þ |°°|ô|°ÈýD¼ÈþÔdôdþÔdô���ÿœ��°L������!2#!"&546!- ȼ|°°|ýD|°°„þ þÔ,�þÔL°|þ |°°|ô|°ÈýD¼þ ––––,���ÿœ��°L���� �)��!2#!"&546!!!#";32654&#ȼ|°°|ýD|°°„dýD¼d‚&96)‚þ ‚)69&L°|þ |°°|ô|°ÈýD¼ý¨ôdVAAT,þÔTAAV���ÿœ��°L����%�)��!2#!"&546!#3!535#!##53#53ȼ|°°|ýD|°°„þ ÈÈþÔÈÈ,�ddÈÈddL°|þ |°°|ô|°ÈýD¼ÈdþÔdd,þ �dþ d�ÿœ��°L�����#�'��!2#!"&546!3!3##5335#53ȼ|°°|ýD|°°„ýDÈþÔdXddÈý¨d,ddL°|þ |°°|ô|°ÈýD¼Èþpôþ �dÈÈÈþÔd�ÿœ��°L����"�&��!2#!"&546!#575#5!##53#53ȼ|°°|ýD|°°„þ ÇdÇÈ,�ddÈÇddL°|þ |°°|ô|°ÈýD¼þpÈ2È–dþ �dþ d���� � §§���%���2".4>"2>4&!!!'57!àðÛž^^žÛðÛž^^žÅäÂqqÂäÂqqlþÔ,þÔdd,§^žÛðÛž^^žÛðÛžLqÂäÂqqÂäÂÐÈddÈd����� � §§���'�+���2".4>"2>4&#'##!35àðÛž^^žÛðÛž^^žÅäÂqqÂäÂqql2ddd–d,Èȧ^žÛðÛž^^žÛðÛžLqÂäÂqqÂäÂÐd2d2dd�ddd��ÿòÿ�ÂA� �6��2632+54&#!"#"&5467&54>3232"/&6;46÷nµ,,.xªªx€þÔÞPpVAbªz–
  20165. ‰
  20166. ß & ß
  20167. ‰Awa­ñ­úúsOEkdªbý³
  20168. þíôô
  20169. ����ÿòÿœÃA��3��2632&"#"&5467&54>++"&5#"&76762ön¶,+.yªxZþ† % þƒ OqVAb©æß
  20170. ‰
  20171. ‰
  20172. ÇAwa­xc¤hþ“sOEkd©cý’äþí
  20173. 
  20174. Ì����d��Lm���%5!33 33!#"!54&#¼�þòªþòªþÔþÔªþòªþò�2�dd,,Mþ³þÔþÔd22�����y��7›�/��2#"'2!54635#"&547.546324&546X^“Y{;2 iJ7-þÔ-7Ji/9iJ£›qYƒZ=gJiû22ûiJX5Jit£����'�‰œ��*�B�J�b�{��"&'&7>2"3276767>/&'&"327>7>/&'&&"267"327>76&/&"327>76&/&òoOOoSÙÜÙSoOOoSÙÜÙþ=y±" $GF`   Pu "Q9   ùcŒccŒcVQ:   Pu "�GF`   y±" $òoþÕþÕoSWWSo++oSWW"±y  `FG # ‘uP  :Q # úccŒcc:Q # uP  $`FG # "±y  ����d��è°� ����"��!#5!!463!#53'353!"&5+¼,´þ¬þ„
  20175. ?,Èd¢ÔÔ¢d´þu
  20176. „
  20177. Ã þ„ÈÈó
  20178. þÔÈüàÔÔÈþ 
  20179. ‹ÈÃ
  20180. �����d��è°� � ���!��! 463!#5##5#7!"&=)+5¼,þ¢ýÚ
  20181. ?,È>¢d¢Ôªþ�
  20182. |
  20183. › ýø^ýÚG
  20184. þÔÈü|ÈÈÔþd
  20185. 77
  20186. P��������°ô�����#3!#732!!34>3!!Š¢ddþÔ¢ÔýÈ!,ý¨Èd!sððüà,ô Èd,ÔÔ+$dþ¢Â$+þpþpô�������LL��2�9��3232#!"&=46;54652#!"'74633!265#535Šd2þÔ2s);;)ý¨öþº;)X>,>Xý´ÔÈÈL2dd2ú–;)üà);öFD);–>XXýæÔ¢d¢��d��¼L��6�=��3232#!"&=46;54652#3#!"&54633!265#535Âd2þÔ2s);ÈÈ!ý¨);;)X>,>XœÔÈÈL2dd2ú–;)þ þÔ$+;) );–>XXýæÔ¢d¢���ÿ¢��Ô� ���� #!"&762#";2676&35’} ,û, }@DÐ:#6#:àÈ­û°&77&P'þLþÒ.þ dd���� ����LL���/�?�O�_�o�����32+"&=4632+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=46©ú
  20187. 
  20188. ú
  20189. 
  20190. ú
  20191. 
  20192. ú
  20193. šú
  20194. 
  20195. ú
  20196. üêú
  20197. 
  20198. ú
  20199. šú
  20200. 
  20201. ú
  20202. šú
  20203. 
  20204. ú
  20205. üêú
  20206. 
  20207. ú
  20208. šú
  20209. 
  20210. ú
  20211. šú
  20212. 
  20213. ú
  20214. L
  20215. 
  20216. þÔ
  20217. 
  20218. 
  20219. 
  20220. þÔ
  20221. 
  20222. 
  20223. 
  20224. 
  20225. 
  20226. þÔ
  20227. 
  20228. 
  20229. 
  20230. 
  20231. 
  20232. �������°��)�3��3#!2!&/&63!5#5353!2+!7#"&46!2!546¼dd^>1B)(üü()B1>^ddÈþ>¼ ‰üJŠ ³LûP°ÈdO7„S33S„7OdÈdü|*dd*þÔ22������°���+�5���2#4!!2!'&63!&54!2+!%5#"&46!2!5460P9Â<:H)"¯ýZ²"
  20233. )H¯¼–üJ–³LûP;))�%&!‘‘!&þ•*ÈÈÈÈ*ý¨22�����°����$�.���2"&432!65463!2+!7#"&46!2!546 –jj–j·."+'þ¼'+#þͼ ŠüJ‰ ³LûP�j–jj–þë9:LkkL:9þr*dd*þÔ22�����°���,�6��2"&5477'632!65463!2+!7#"&46!2!546X/[3oœo"�o£"."+'þ¼'+#þͼ ŠüJ‰ ³LûPk‹6NooN>Q�o£þ
  20234. 9:LkkL:9þr*dd*þÔ22�������°��"�,��!!.54>7!2+!7#"&46!2!546X,þÔ%??Mýî<=Bm�Jþ¢¼ ŠüJ‰ ³LûP°¡‹9fQ?HS½TT¡vKü~*dd*þÔ22��È��è��)���2!546754!2#3#3#3#!"&546/R;.6þp6.d�6\¬ÈÈÈÈÈuSþpSuu;)N\6226\N)þG6.dddddSuuS�Su���dÿÿLL��/�3��!2#!"&546!2#!"/!"&4?!"&=46!'–„ü|¶
  20235. 
  20236. þåà % XýôW & àþß
  20237. ªdDdLþ ôýD
  20238. 2
  20239. à % XX % à
  20240. 2
  20241. ddd��������°L��#�-�7��!2#4&+"#4&+"#546!2!46+"&=!+"&=È Sud;)ú);d;)ú);duè);ûP;ñdèdLuSÈ);;));;)ÈSuþ ;)þÔ,);þ 2222����©¬� ���� !&4762 !2!546ઃþýû 'Yþ¬V/þ«¢ ü|�ýUYƒY(þnþª0Uü22��������!°��/��.#!"3!26=326!546;546;33232!½'þp'½q*}¨ý­20È/2‡úþ––ýŒ22,þÔ2������°°� ���"��!#!5463!#5!#!"&5463!#5„,
  20242. þ‰þÔ
  20243. w,Èý¨,
  20244. ýv
  20245. 
  20246. w,È ýÁ
  20247. O,T
  20248. þÔÈþ ýÁ
  20249. 
  20250. þÔÈ�ÿœ�dG�F�V��32676'&7>++"&?+"'+"&?&/.=46;67'&6;6#";26=4&äÃKŽjI C
  20251. 
  20252.  )V=>8'"d 1*Ã) "dT,Ÿ| -oËtEú
  20253. 
  20254. ú
  20255. GAkŠI
  20256. ! "% ,=?W7|&êF@�Je5&2WO_e_
  20257. 2
  20258. 
  20259. 2
  20260. �ÿœÿæ~� �$�4�<�R�b��%6%32!2&'&#!"&=46#";2654&'&"2647>?&/&6%?6'.'.�§. ‹ü+jCHf7ý" *:þÔ>XX¹P*† €@--@-þ˜ -?0 !3P/|)‚( )f!% = „÷ &* xÈ"6Ô2&„CX>È>X¬83 DÉ-@--@þÛ‚
  20261. # ³=I+E( /—/}X&+ 5!H �����d��9°�Q�`�o��322#+"&=#+"&=#"&=46;#"&=46;546;23546!2>574.#!2>574.#q–
  20262. Oh ..40:*"6-@#
  20263. d
  20264. 
  20265. KK
  20266. 
  20267. ¯
  20268. d×)  )þùk)  )°
  20269. m!mJ.M-(2N-;]<* K
  20270. 
  20271. KK
  20272. 
  20273. K
  20274. X
  20275. K
  20276. 
  20277. KK
  20278. þÔÈ
  20279. "þpÈ
  20280. "����°®��)�,��!2#!"&'.546"!7.#Ô Vz$�RýÄR‚(z Œ}VG+œ0œ )IU!�îzVþ`3·BBWwvXZÅ3 Vz™&--% óó,(1#þÂ��È��„����32#!"&546+"&=Û–g¬T)þ>)T¬H6–6¬gþ )TT)ôg¬üá66á���È��„����33#!"&546+"&=Û`³–T)þ>)T¬H6–6–³þB)TT)ôg¬üá66á��������� %'5754&>?' %5%ý‚þ†Nd––d/“‚\þ¢þ¢^^ÿþåª<à–Ç”•È–ú 
  20281. (Aýb¦¦“¥¥���dô° �����2"&4$2"&4$2"&4¼|XX|Xè|XX|Xè|XX|X X|XX|XX|XX|XX|XX|�������¼L������2"&42"&42"&4è|XX|XX|XX|XX|XX|XLX|XX|þÈX|XX|þÈX|XX|����d�dLL���/��!2#!"&=46!2#!"&=46!2#!"&=46}¶
  20282. 
  20283. üJ
  20284. 
  20285. 
  20286. üJ
  20287. 
  20288. 
  20289. üJ
  20290. L
  20291. 
  20292. þp
  20293. 
  20294. þp
  20295. 
  20296. �������°°���/�3��!2#!"&546!"3!2654&!2#!"&546!5^ô¢¼»£þ ¥¹¹Ëý¨);;)X);;ý±ôþ G�°»£þ ¥¹¹¥ô¥¹È;)ý¨);;)X);dþÔ,dÈÈ�����d�d°L�;��!2+32+32+32#!"&46;5#"&46;5#"&46;5#"&46–è222222ü222222L*È*È*È**È*È*È*���,�è£�� ����*��.62"&%#462"&%#46"&=32ŠW??WW??þù|°|°¼°|°ýÀ|°|°¼°|°°*(£C²²BB²²þÀ°|°||°|°þÔ°|°||°|°þÓ�Ž��ÿµ�È”��B��76+2+"47&"+".543#"&'&676/!'.6éE*  '?)’¸
  20297. T ¸Ž0I' *L
  20298. #3¶{¶,#
  20299. nþÙ  6F82 þà*<SC# 
  20300. (#( ÁÁ (#��������°°�%�C��#4.+!52>5#"#!#4.+3#525#"#5!°2 &È2þp"È& 2èýD
  20301. d È2d
  20302. ô„ ü®dd R ,ý
  20303. þW 22©
  20304. –��������L®�� �0��5"'./#!5"&?!##!"&=463!2èþßEþÔ  1;E%= !'þì†y±üè,2 "
  20305. ëý# 22+.°¦"A2‡Vþªýãdd�����°°��G�J��!2#!"&546#"3!26=4&#"'&?!#"3!26=4&'"'&'#&#2Lû´FF þÕ&  7
  20306. ?
  20307. 9   9 þàÅg°û´LR ý  2 2 £™ 2 2 $ì þ������°°���#�'��!5!!2#!"&546)2#!"&546!°ûP°û‚�þpm�þpG,LdÈü|„þp�dþÔ,�����°°���#�'��!2#!"&546!2#!"&546!!5!2�þpm�þpG,ÈûP°°ü|„þ þp�dþÔ,ý¨d�������d°è�'�+��!235463!23##!"&=##!"&546!2�d�ddþpdþpŸ,èþ¢––d––þ¢ þÔþÔ,������°°����'��3#3!2#!"&546!!2#!"&546ddd–�þpG,þ¢„ü|°dþp�dþÔ,þ þp������d��L°�'�+��32+!2#!"&5463!5#"&546;53!X––Âü|^––dÈ,Lþpdþp�d�dÈþÔ,�������°°����'��!#3!2#!"&546!!2#!"&546°ddýv�þpG,ü®„ü|°dþp�dþÔ,þ þp���,�0o€��� #"&54632aþî5þèþ*����A�2„~� �� 6'&4Oî**þ{î)ü)î*�����2A~„� ��!2"'&6dè)þ*þ„*þî*�����2,~o� �� #!"&762{î)ü)î*aþ**î�������°(��
  20308. ��5-5!5!¼ýL�þc¨üà å¶þ½ÝÁÁÝûØÈ�������d°°� �1��#3!35#5!34>;!5".5323!°ÈÈþÔÈÈ,ûP2 &d2�"d& 2üà„dd,ddþ  ýÚdd & ,������Lè�%�1��#4.+!52>5#"#!#3!35#5! 2 &d2þp"d& 2 ,ÈÈþÔÈÈ,¼ ýÚdd & ,üàdd,dd���È�frJ���32 +"'&476½ 
  20309. þ0Ð
  20310. þ)×
  20311. J þ0þ0  ×× ��>�fèJ���32+"&7 &6S 
  20312. ×þ)
  20313.  
  20314. Ðþ0
  20315. J þ)þ)  ÐÐ ���f�ÈJr����"'&=46 4 þ)þ)  ÐÐw
  20316. þ)×
  20317.  
  20318. þ0Ð����f>Jè��� ' &=4762j×  þ0þ0  ×áþ)
  20319.  
  20320. Ðþ0
  20321. ×����Ùÿù=°��:��#463267>"&#""'./.>'&6è°|°þVd&O "(P3G*+*3M, :I G79_7&%*>7F1“ °|°|°ÈÂ5KmCKG\JBktl$#?hI7 À�����È�„°����!2+&5#"&546!5úX–ÿ–«,°þpþ ² Š�ddd����È�L°����!2%!#4675úî'=ýDXýDd d°Q,ü[u¶}ü4ý]dd����MoÃ__<õ�°����Ðvs—����Ðvs—ÿQÿœÜ�������������ÿ…��ÿQþÔÜ����������������£¸�(�������°��°�d°��°��°�pŠ����Š����±��E���Ø���Ø���¢�����H����E��°�d°�{°�È°�Èô��°ÿò°��°��°ÿð°��°�°� °�d°ÿÓ°ÿÓ°��°��°��°��°��°�&°�n°�°�°�°�d°�°�d°� °�d°�°ÿœ°�d°�°�°��°�°�°�°�d°��°�d°��°��°��°��°��°��°��°��°�d°�È°��°��°�5°�d°�È°ÿµ°�!°��°��°��°��°��°ÿœ°��°��°��°�Û°�°�u°��°��°��°�
  20322. °�È°��°��°�È°�È°�È°��°ÿþ°,°�d°�ˆ°;°�°�°�°�°�°�°��°�°�°�°�°��°�·°�·°��°��°�I°�°��°��°�]°ÿÜ°ÿÜ°ÿŸ°�d°��°��°��°�d°ÿÿ°��°ÿQ°�°��°��°E°�°��°ÿœ°�J°�°��°��°��°ÿœ°�a°ÿý°�°�°�°�°�°��Ä��°�d������ÿØ�d�9�È��'�d������������������Ù������������������������������d�d��������dÿœÿœÿœÿœÿœÿœÿœÿœ� � ÿòÿò�d�y�'�d�d�����dÿ¢�������������È�d�������ÿœÿœ�d��È�È���d��d���d,ÿµ���������������d��,A�2�2������È>�f�f�Ù�È�È���*�*�*�*�²�è�èNNNNNNNNNNNNNN¤"~†¬äFnŒÄ2b¢Ü\ºrô bÊb¾ 6 „ ¶ Þ
  20323. (
  20324. L
  20325. â 0 Š Ê  X * ^ °h´(¦æT�ª*v¶
  20326. 8|ÀtÐ*Ô<¨Ì6`°þR¦.j–°àþ(h”ÄÚî6h¸ö^´2”âDl”¼æ.vÀbÒ F ¾!2!v!¸"@"–"¸##"#8#z#Â#à$$0$^$–$â%4%`%¼&&~&æ'P'¼'ø(4(p(¬) )Ì*&*J*„+
  20327. +z,,h,º,ì--ˆ-ô.(.f.¢.Ø//F/~/²/ø0>0„0Ò11`1®1è2$2^2š2Þ3"3>3h3¶44`4¨4Ò5,5ž5è6>6|6Ü77N7’7Ô88B8†8È9
  20328. 9J9ˆ9Ì::l:š:Þ; ;Ü<<P<¢<ø=2=ì>:>Œ>Ô?(?n?ª?ú@H@€@ÆAA~BB¨BîCCBCvC CÊDD`D®DöEZE¶FFtF´FöG6GvG¶GöHH2HNHjH†HÌII8I^I„IªJJ.JR����§�������������@�.��������Æ����������� ���j��� ��(�|�� ���¤�� ��L�²�� ��8�þ�� ��x6�� ��6®�� ��ä�� � �ú�� � �$�� � �$4�� ��$X�� �È�|�� �É�0’�� Ù�Âwww.glyphicons.com�C�o�p�y�r�i�g�h�t� �©� �2�0�1�4� �b�y� �J�a�n� �K�o�v�a�r�i�k�.� �A�l�l� �r�i�g�h�t�s� �r�e�s�e�r�v�e�d�.�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s�R�e�g�u�l�a�r�1�.�0�0�9�;�U�K�W�N�;�G�L�Y�P�H�I�C�O�N�S�H�a�l�f�l�i�n�g�s�-�R�e�g�u�l�a�r�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s� �R�e�g�u�l�a�r�V�e�r�s�i�o�n� �1�.�0�0�9�;�P�S� �0�0�1�.�0�0�9�;�h�o�t�c�o�n�v� �1�.�0�.�7�0�;�m�a�k�e�o�t�f�.�l�i�b�2�.�5�.�5�8�3�2�9�G�L�Y�P�H�I�C�O�N�S�H�a�l�f�l�i�n�g�s�-�R�e�g�u�l�a�r�J�a�n� �K�o�v�a�r�i�k�J�a�n� �K�o�v�a�r�i�k�w�w�w�.�g�l�y�p�h�i�c�o�n�s�.�c�o�m�w�w�w�.�g�l�y�p�h�i�c�o�n�s�.�c�o�m�w�w�w�.�g�l�y�p�h�i�c�o�n�s�.�c�o�m�W�e�b�f�o�n�t� �1�.�0�W�e�d� �O�c�t� �2�9� �0�6�:�3�6�:�0�7� �2�0�1�4�F�o�n�t� �S�q�u�i�r�r�e�l���������ÿµ�2������������������������ ��– 
  20329.    �ï !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ� 
  20330.    glyph1glyph2uni00A0uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni202Funi205FEurouni20BDuni231Buni25FCuni2601uni26FAuni2709uni270FuniE001uniE002uniE003uniE005uniE006uniE007uniE008uniE009uniE010uniE011uniE012uniE013uniE014uniE015uniE016uniE017uniE018uniE019uniE020uniE021uniE022uniE023uniE024uniE025uniE026uniE027uniE028uniE029uniE030uniE031uniE032uniE033uniE034uniE035uniE036uniE037uniE038uniE039uniE040uniE041uniE042uniE043uniE044uniE045uniE046uniE047uniE048uniE049uniE050uniE051uniE052uniE053uniE054uniE055uniE056uniE057uniE058uniE059uniE060uniE062uniE063uniE064uniE065uniE066uniE067uniE068uniE069uniE070uniE071uniE072uniE073uniE074uniE075uniE076uniE077uniE078uniE079uniE080uniE081uniE082uniE083uniE084uniE085uniE086uniE087uniE088uniE089uniE090uniE091uniE092uniE093uniE094uniE095uniE096uniE097uniE101uniE102uniE103uniE104uniE105uniE106uniE107uniE108uniE109uniE110uniE111uniE112uniE113uniE114uniE115uniE116uniE117uniE118uniE119uniE120uniE121uniE122uniE123uniE124uniE125uniE126uniE127uniE128uniE129uniE130uniE131uniE132uniE133uniE134uniE135uniE136uniE137uniE138uniE139uniE140uniE141uniE142uniE143uniE144uniE145uniE146uniE148uniE149uniE150uniE151uniE152uniE153uniE154uniE155uniE156uniE157uniE158uniE159uniE160uniE161uniE162uniE163uniE164uniE165uniE166uniE167uniE168uniE169uniE170uniE171uniE172uniE173uniE174uniE175uniE176uniE177uniE178uniE179uniE180uniE181uniE182uniE183uniE184uniE185uniE186uniE187uniE188uniE189uniE190uniE191uniE192uniE193uniE194uniE195uniE197uniE198uniE199uniE200uniE201uniE202uniE203uniE204uniE205uniE206uniE209uniE210uniE211uniE212uniE213uniE214uniE215uniE216uniE218uniE219uniE221uniE223uniE224uniE225uniE226uniE227uniE230uniE231uniE232uniE233uniE234uniE235uniE236uniE237uniE238uniE239uniE240uniE241uniE242uniE243uniE244uniE245uniE246uniE247uniE248uniE249uniE250uniE251uniE252uniE253uniE254uniE255uniE256uniE257uniE258uniE259uniE260uniF8FFu1F511u1F6AA����TPÃ��wOF2�����Fl�����±\��F �M��������������������?FFTM `�Œr
  20331. ‚©$�åe6$†t „0� ‡"•Q?webfeŒ5ì˜�€ó@ Â?þ¾
  20332. Úöˆ ¬töÿŸ” †ŒÁ“ÇØÜ,3+2q ËF®YOì&>±é±bÒm¤5�ZŽæH$±ªYŠœ½{ìH jd† Õ‰ ü²%÷¹Ù§y"§÷ö×+�@¹Œ]½«eŸû{úÒûv� Nc‹)»nù“É?~?è�¤hò�ÿž_ç&iÆÊÈÑ�Á¤‹?º>üå^K ûv´-cÛ�1íô€‰2K áy·õ,'nä«à�(ð3EwiàB‚ &©ÿ éÎT´lhØ0MÒØÚÒ†dåYØrñﲬ³ntiÞ]Ýyur•´¼®û™îVXsj¡¢žågMnªÓ™H�W•©ÃÔ r2ô>iT`V7¸ÍR(±¨ÉÏàÿ+ o6ó'cÅÈB°�æë4ç·Öι݇ƒ‹ã¿š®T ]a[Qd<3wq8,Ž…îrTI¡8áŽ0>E¸?ù*E¨ç—¦•#Ïú7'�ìÝý†S ocûÊ·í_‹7&#*Ñ+)½³ Ð+4a°A6¶cŒçy±Ù£†f(bFéæäÿé´$;{ YAÃ1vP-tGøÿŒáÀ±Í"û°•ÛCÂf- W‚÷®šÔ™ÎuKÖ°Kã#­íä¬Ö*K†<Ûü (ÑßëÔ÷×ÿZþ`Ù« åµ[—%êYTŠ¬{%¯ÉŠ$ˆ­ s{oïíœòˆƒÕ»ïvt"pàœ4`Èêß©ŠÏ¤}o `ã³Ýú'neÜ>
  20333. äG5s�zó_Nó
  20334. ’PKÓ¦vmUÞ É¾{z½ÜòîóÿŸøøŒ‡"3`l ’–W#Ô�½^@+�,c¹Éko©�AOpnuµ§Ôzó–zJ)õÜÎ¥÷˜Û1Ç}ááÿO=Þ­¶€x¾RÆÄ`ÁJ‰`§qƒ¥‚Us/¿+økÒvÇ1xlÝßçjl–Elì\nDŒÈÃƶ¯V†±æÿÐjg›{Zdå‰z7� 5ÿß!xmÂ5oÂ[½¿uïû&·¯1Ú‚HBkAâìqrêÎR�Ä £·°�(\ghôÈ7‰ìÒŠy�=†HµZóUPhéÐ$8RgÓÄ€zÂgÍ­ÉN:‹à�1u¬$Ü…¯¤¡ž>Rý]åú—¦¬"Ÿôf7¼— õK¯^'˜ªë½3“+E/¼Ä^‰YU5]¨NB.ÞÊ‹¥Ò8ßÅ+ÎÍ�8�ù,|‰{M|ŒAŠåua|Ðaˆ’ìŽÕÞË…Õ�%�
  20335. lKG¢Pí,NuæÜÔkþcï8mX@ÚÓdÿ̘?ñüÚó¢çYÓ&Ïþ{êö”ø³ÇÏ?ÛPÜ(®GŠ]¶¿ÏÆä¯äOä�ä·ä×ä—är-¹’\LFÉ9—,&§“yä8r¬û´û3÷ÜŸ¸?p¿ï>ê~Ûýºûsèäÿ‹žÐ¢ÓDǤzó1ú¡?\U5q=­ÙtÑzÔ’†&Z�nj¢%émM´"}¼‰ÖtkÞDºwh¢-=ÿm¢½Bíéõ76ñô®ƒ&:Ò»Éqt" Ö1:“¬ëЕ¬©u;ô"K_¡/JdÖc0–l²õ0²Å'^B¶ù8VC¶Õzg°²½¬[ ;Êúdì
  20336. ÙYÖbȃu‡¼©u;œ@ž*}y‰| .©¬'C>\g=ò9àVëÅ�¯·[o†|gð õ^� ž¶>Šüd¼
  20337. 9­ÏÇûäîØÅø”
  20338. *E|A¥�ã*M­[ã[*mOÜßQéz?PénÝ?R)Y�ÁoT&[ÏU*‹•5ÀSÙ MB þì¡¥ð[³
  20339. ­„ßoYDh­Õ{ìÑ,}1<f�&6h¤†'��Ê¥U#V¨Þ­¼¡¥EûD"TÁ¥Þ©Ð¢AD9ƒÿeB¹:©Ä%OœÁ ÒÐñ‚‡ØFuŠn 7?%RG4"„¸f©gÇÁFêº� a=‚‘-³ÕQ—á½y+B½,ÄøÐ2ÃËÖ…5¢•‡ð™„Œxn¡Ϊf*!¡³æëlâ|GXQø ÞƒUp”ä
  20340. ÅEu Â@ž�¦å-ð€Do.6YZö‚-&a>f?›�«“N�Nœ¢ ]ÔO/^;\ÚÂJÊ ÏBÇEsJrª� ÄšõÆ'ò…g/ããÑB%Ÿ¡o Cõêºn•7‹Ü:|õyƒKt²&÷$§Øs¯|¹õwPˆùÄ\i]¾$Z@+Í ¶¶Õ€90x]»r¸­%¾ÈÕ+öRU¬Em‡+Ü°ª£;w u¬À9/I¼Ô7È7Õ¦¹Qþlu\¦yÐW‹N)ë8‰Ü°vYî*u´m”¡±¿éâ©âºm( fÊE½òÿG8² ¢j#I¬½RŽÌùz #q¸ß·ß „)Y ×$‹ áЛ†c_%¿m-{!0-` ;áå…¬ñhyVõäÁ]Hv! Ïta½\KïÅ¥[Ì1{"çj 6@ì–3T0%¥¿éΘ"ÇÔ™ÆZI†Gä›S“÷�‚.³ÄΣp�ÆÓ¬SÆ1eéûÙ“ÄØ›�ù YÁÿv»8d±\±B¡l¡SûþR)ÒÓ†çù¯–®€ {IŠÓ†ôÒ%�”¯>û0ÐŽÚ¦³\ð'”cg½2%4 QŽD¡
  20341. 0Í’3B²"ÉMŽÕŽ&€ÛŠhIÇÂÚ§ÒRg·ME¤¡©¡¶š I½Î(©ÞÕ5U–D] }ò™bí8$—‡ì8¨>óáX ²h•"lµÎ€âj�.%ˆÛ€HHÇ- Iš¦Ý¸#1’C4õÞYÞ7„íî®íYÝ–¡V o>PÊ]¡6¿·˜ö™O4ÿ7f ½~�AJdYFÕ€Ê.–ÞoõÃþy) Æ8lÆ ¶22ŽeŠœ¦Ò1H¡[t‰°@!È… 2\€@¸5ÄÙ“Ê%Z×îüÛkÞ’aõ�®Ü@ú.`n¨3ÊOFŒ¢R(󅥶÷ÿ½ZkLkF íHWjY I¤ê5×ç*ñ6ÚÎeµSbk.¤¼5F,ì.•N0ßÔ™’¹€|”†V¦€||~Nô‡( 4·�ìÚ],ìJp|~ùxeÓÉA¨Ô¡¯5ˆˆ/»Ú»S¤ýäô”Ðvò×Üy?›ù²'_v|rê„ËXÜøîHéQÊ°µÄ“B@= ÝX¬ßú¬B9Ë4³˜«ÃT©ØB‰B©c ­Á«H‘P£Î+‚ò‰�_““ÕYHÙ#¬$ªËÊ` ìFø£ñB;ãµÂ+Û”…BPR°4̼ t­:tõ"ZEºJ^!XÂÇ“à¬q4_dTW(5äÜ€§åÿä¸ÚI±”UŇÒAÍzþ@U6ÿn.WGXýÀÁèHìRKÀÛ&'swM±jŠÊŽ˜‹±<Ÿ”±˜3¦)€–�`#F@  F Ô¢àþØv�oÍb$x ï+²à¼uû&´}‰|ÊX&[Ùª�8F‹-¹E&/>Š/ÑGÅ.aêz^ŠÞ/ƒÔþ})œ²’ó'“x©‘$O=<ÇÂz™¤oä§áA9MØ�&ò~î¡™¹3rµ3gŸœ¦'¿8Ò£\°-¶MDzÈè˜økºÍ5†ù±´A
  20342. ÝÂýªG9©ä|1-Ø! Ç87û[œô¤,mRîu|¦57®
  20343. =Xþ‘¤,˜aJ§Ù›¸^t´N›4ÓØ\fЄ]AzH^7·ªF•èþ•™„&k"LU>}ì>çrBåX(Û‚ªë‚Tš%¿« Jª¿„­dhKÄ”ó¶P“²KÁTFaA‡3HH†C[r;a›À¶d·™‡•54ÈÌ ‰—lL„kjG{¡ì8Ÿh~ä� fR@Ðìü9wàB¨¤àÐ0ë zSõô°âÿ'— a7‚@Ý@N›±ŠÝƹl‘bj3hNî²Xö‹F/Éíe¢s£Ù'úŠDsQ«ñ<þk^Óíò×¼²ýˆZASO¨idºSJãxN4D½³ÀKÓ!´¹Ôù !Ù«v‰¬hA`ÛE–·X�•�¼Ê- ¢P íÄ:Ÿ‚ÛѤCê:ÂÂWÍzS½sÄdO :¶_¿«ÔË`Š:tÁaηБ ¥†²Íسú¢�® ¼IYð4Ç # �ø*ÒÍ+<êq�n°oÔ�¸u
  20344. UÌcww�óx$dµ³ðÆ¿�}Ï�ûÖÁ94Ìýšíü9p¬*T:ú%GQæ…^aŸ‹‡äÝË'¨çeƒôbö¨Šl-ÕÜ*XÝLç%*ź¸.…ÚŠÈ\Š@pR$Tå*KÖͽ¸hp‡ÀˆÈèÁ‚ßã¦múÁ‘â-/“oSÚ3ŽßÂE�àÏÎto¸ž}çжV‡oõeJ `<™$öÙtíؽßü ª]g*ßZ›„µ6q°Àùl’ø~÷E¯«
  20345. †Sú¸/Š’ùi£ÄTÆtÍk‚Ç®à²WÝþ Ü=?j¹�G¢ÒÌÔUUAJÆõý›`†ÒbÔË‘—ƒGˆõQÍAÏ«©�ñÖÎÆÚìcƒûê½WËï©èWSmÝÀ­g³ºÚFËñª‘&©^õúؘԡˆ6;C1:=ÛˆP‰äºÕ`ÊÚœ�VVÿ“ÔE�Æ5"´hO«Xà~«ÞØN3_5Ó�]ºz-þ­ä’CWÓÝtÔ¥�‚Óˆ´ÐËeÜ]°\¶”©¿V¯–‹ÿcÔ#m[ÆkuÞ—­_ʱ"©Éös�H³ô<}xï±…m0båxHÓqb‘a3tfçMTÛÑÏ*]I»
  20346. Þ}×(ú¾œ,M”„�–=Š Ý@ŒJAÛÆÐd‰� ¬Ë?§6PV±ö[ dVãvôæ4jžÒß›‘lH\â÷ÔŒÅè{˜ØòMôå½È˜\º��åYþÜ�€�`9MÃ`Db‡<Á;a#zò†‘<Šx"ó,¨d‚gCi¿`‘c’›:ÁÈâI´â>jw·Ì}JÈÉz§�^:V.ý:×þÚ‹{¿Í¼(ȲB÷æËɦ’ÉóxŽ<Db#"S£¡{ô’PùHu½N�/ë{r6;wU¶æÐòsÖPО“<¤çXÀàYâsÔÄ÷ÞMxu°‡\šb�‘Ús¸$Ž˜xŽÊ(¢‰/^|^*0j~mà¬;#·%J„ÞM4�Çp˜QM׬ð::b\C2gf°°]½zÒP8T™ Uª“QbÖètºƒC½TŸ>
  20347. p 8+6g_2–lΡ6§Hò ÚÎ�džH�:÷ d›<æCÍé6³¯Ø¤ê/«¿6ãE:ÂK‹”"Ë`kJ©<›ÏÆ¢ä=ùvž7„¥âN5·µ`°ò›¶Jt‹Ù\j¹6Í…%Ëž7ô*¥'¥•U•Ù4±:âX+ ä\b�ü’E
  20348. äìôÞaf®ŠxŒ“}Á‰1+p™‹B¥Ë0î6òâ”åýž3rõA$Nš~¶ô#³dª}ÇפŸP7h÷H7b£FªžÂ§…‚¬8ð ³P>øBtGNÐŽ¢ðmä‚xô@�j …‘¸|{Às9à»=þwRÙ/­«oDJs5z>“;Š'xÝñEÐq^ré^=G?½…9Aê¡æ–ÇAä_—£íK%µDÉ®:uikjkîIeÉ潬GúÕ�#*¡†)µjm‘á|½t£¹}`Jæ©Z؈éÖ÷H=4î�{gß�¢¾)¡qXˆMA,šHøŒ7û1‰ëV"¥Ùo,çY#hýü÷ݨSò_ê;‹Ía_Ô—Z^cn4¢­� ‚H¸E«®?‰«°}Ñ
  20349. È�¡»­Üî¼Ù¤=}BžWvÞªUeðåhšƒÚ�GŠ“F�…‰‘æ;�@2S¥Øœ€@Ëf þÂËünÍâ2Ð#�Žæ¹ñfÝY:]¿JyåH]­•-·˜G׌wgv'¡â|ˆÄ0eñ
  20350. Ã_7ˆðÒ�«n+fßÙ¸âàY<«ç(Í
  20351. ª?öì’©‘yòù¡%wm¬+jƒ&&!è¢c“^¡u'�bü&ñhŸm6¤šÎû¹*2 ?´AÇI«¶Æ²5FW¾Ø™[âÆœ¨BõUzïIÎE”“!’m:‹ÒûœxhÔe—ÝÇ®n¼z|]% ��mÙrÁU¸F�Ú¯�”ù®1Æ ‰};!n F¾& gòÚñÿP‰†Ý¯¯;&×ö©œøï$$¸éF«).t›BíQ¨3¦Ž½(žC=ú·Óä¦XÀÎØesÔ;Ýiû«¶­ÙŠ@¼Ñ~üNíÉΡEë ÔSR‹¡ˆh�\éè£úÁBeñoº†½œ ´¹ÎbTÑ„nÎ’ju¹¾À g@ä÷'qQ딎nx.u6bVU&Ô ›]¹;Ûïª!C_ „ ž�5Æ*Þz¹ɺûm€RQu‘ªq‚’঱PüÚZ0ƒ¶}mñ¼¡ÌÊõn½¦^nÕOrÉT¦âÁ‘µÎ:ŸUã'×hÀæ§0nZ¡p^Ré|DFª_b\ò@–Öm�‚èDEë8��Æ{oèGM‰á œq¸ÝÏ}ÜîSd ®C,ûiÀÜšEêŠé/°ÞË[d8]Ž×,MCIšÎÐó_u—,]V™�cñ"—ä¤p°g@ì`"y)‹,;B³^e­žlÚ¡ª2'€.(�ÍÐĘây>à-|Îh­ÜÓÄwšúþê;©jå¥è’íÕ�ÑÒiÔ½±ä¯ê_o|!@ö)ɢݪÄ=ÙÌŒSPz�—éˆ*!z})¼|ƧT}½j‘†E£tC¬Zå¡nŒ�½ýœ*ÕžõÉ4ۆ׽[¹©± ¾9»Ð®¨Žèˆ‘’Ý“õŒz`Wmeôo‚‹|j8j­ï5á�9¼öµ@.úšE¿VÌ/ÌZW@|—�f_ç\"${ᜑv¡àòƒóœÀÈ/¸ò¶;a×:Se¦i3TäGË*ëÎýƒ]¸Æ¡/ÌhÀ2C32$¿Óô¿ü1}¿ŒD¤ÍNXÉøþtì?FÏ�í~n,Pj9.î–>×£ü¨Í{
  20352. 9ýÉEN-v|3h†ò‘CÅиE”•‡ XTàâË;P–$Ã=�JÖ-ÝÕgÝ•ýùigz~q—(Aé<:h1±9³3áNì̽õQ‰‹ãÇ}CLØ�WùߧÂ׎Ü~ƒá Úb™¥"†�‡Í|Ç4u}îð­×Ùc™y€à‹È6°¡2ÿ[ ¥ØÖ\d¸,µÒŽÕ³b�kù¤ÌDåä¾%0TÜx­®{=;öÔ·‹†(„i‡ �ØLS·øß1½˜øý©Ñ3ÿNÏh/¤6?æ'E^ö~ÿÆÔP®{sZì™ZÓK”ÄžB{’DÌtø&‰½Ôz’Ó÷)µUoaù5Q¦3�‘È—ˆr~¿Ž‘¾
  20353. ¦ôÙùF] $º<èútm(š} ûÃÏMB@‡ž[œGxìÎFÓh8�›#}ˆô,£#À˜u ýLaz(ÞQh±4%Óxm`Uà•Õ¹.E¨ãv1a’ž4_'/[¨d±{Fx¨IÊ59žŒ ƒDõ<êì&�8VˆEóFgÉÈ٠芘#õI‘äŸ�2S²Íîÿ_ã©]QqAšnˆÑ_ðQç>bÞ˜4g¡¨­±-®0&E#c¦Üi8¿ vR/Õ4ÿržŠëšP7•£KsOWµN3Õ�vE\bq†ûQß5�Z¹Ú½Vy5]�½Ööàh/ i)Åû�¦Ž-/´°ã¡kµN¬ÑŽ¾ÈÄ#eì)"Píñü {ýKSQ�x‰²¸�¦>aã&µí¶Ž<a,릌HEHÏòó‰ ]”%,eDž³U~W»lý�Ú›«;c¾á˜“÷`þ�? ¡¾p‘M ² lëê.‚P²W7õ¡Ù£È./ôWœ#;Wõd*–:z;E2†¨Ÿîöãúj¡ø9yÉÜAÇS�S8èuÀŒ¶à¬;fY8»m KѯèìÔ„Ô¶‰Í¡>,„  _èg¥´ñ-mác<×n]Ч-®5‘2c¨¹¡®ñz ¬7d Pœzóåµàòð²V„ö“û¥OPvf¼Rþ R¤ÓÆà°“9†Z -ŸÁÞd†÷®šˆ¿C›šñóÇ`,öatÁ=‡k?v¢í4#P è¤BÌ¡šØ¥¸/[õs.<a0eÆ{�´&Ž¢vþò¡a~eÐó8‹è)fä±Ûny’êfäBPLùuñ³Iy²H=Sø2öÑ”Ò"[ÃÈ(Ù¼O@íz*I¸º@Åö0—äª#˜ãÜà,Ð�­ôÅI$Q¡Ïy côÑžF ëa�ßžv"²ï|RÇܘ 'WœF  x?þ+aNƒMö®�KÎ`ÆDÞ/è·nf:X¸I8:H ±IRm]›Kôº6i ü@UÏH*NíÐoF¬àý;–±©›á‡�"W�q£¾d\“‰‘Ð�*C=#ã2Ï6x”7ì<TÏÕ
  20354. 7yˆÔrU>-bH)ɺzï '}¶×¶Ýîwœ!rÁXÎZŠµ ´.:’Vn×;î-î>Š:á
  20355. 6àrÿ½‡UÁcsÕ4k¬VW¬{’ú‰ð#­˜5ß‘0ÁBÝãìÇ`Ü�ÿ0ušÑ".QÊƬ›dB´˜0£”õ˜CžÐrõ]íïà#íºQ9lqœàN^ôÖ³�¯éôh~ NU\´ ¼16š
  20356. ~éè“á”S‘n‡Tòl¢‘\þTHÒ²Ú›-ÙÉ~ªG~)$…oQ7-ë¯Cï°ÌÈì}q%/a™¦³vO°ª|[q4–‚Š’³~Bc-$NÜ7<V…HE€i-™œèRÈF“ GNMà{Ð"3•� û49‡[„j< �ḬWÓ­ ÊãhÕø˜¿l‘nÛà üÈØQÒ¨Ú‰Gcq¨ï@w¯/e qÿ£ÌægήÈ<ˆ£ÍÆ:  êáaé’·¢‘u¯êÍñ”•_P‹` Ýùb{Eëá¦I(ÏÙOWGÝæ«fEyÀÜéABa_žß;O^ŽDQ£â'èµsóåç îÐìó`Dî#Ñši¯:Ñ´Û+ßY{©{Òpå&¶Å\ßRažšÀÁ—gþÏž0ÿÁgúïTùLÎi<'Ÿ7ö¦?ÀÒçX1¹ÀÏCïÖ
  20357. a¥¿éîn0o¹r1Ñ ™/U­¥‰�õ Îo�/?é•â™¯aùÓ_¬pê�HÖ± Gõì´ ¦Â8ŸÝ£?3F‰0ð˜€Ù`%Ã÷Ï‘ÄÓ<�
  20358. Gš]Ô½œ8blÍ�%-,Â)}%žJ”:¹Y­ÒjÐTÍ;Ыȶ5Å’>ž6½Ÿ�wÒ{œV餃.&£ö(†o¹©*õn<§Øn9¡ÁJ–
  20359. "a‡© ДÍÝ+¡† aÊ/»ýººð;7zDØZη{×t�M Mp—£ iØšk¼NPwˆØ‘ͺðH`T ö$23–†fÓöÀÐÚ0šzÆÈ;­¡¦žç"ð]Œòª‚*ŽY²¤é,äQ¡W�Øàô¸lSéµÆÅOŽrW$5]K¡VÙ»Bâ…Üš…I¸ŠkÚ|ß=²&Á[ÔèêÞÑÞÅ58EÓR¤0Þ‹Gk«sSîñÁnãònnuãúñExK�Ðrô¢¬Œ}‡~mñÙ`ŽG4u{ÐÑñ=]6f¤�÷âר
  20360. BoÖ&< ™Ã±c;2 ®P$Ãǃ{mW_cžõª'B6Њ?$½^z[�C—Y¹Ý­™é¥jÐNó~ þ¦Û®0¾»›út¢¯ú°Ûâ„6/)-‰1:p$Dꥅȗ
  20361. ®
  20362. ,'³†üyàõ±øÁv˜Ä …nœ‹F³T×Ñ�™['a¦MbÎJ]»%�&î¬lc6&ÂèIpFå�Ä ¨ÜoðŒiƒªÄÉþã5± ø'r¨äËår‘(q¼ïè�ú®ëî¾z6Á°öžîÉ(5óÐáEôàÉ¢ÕŸl\…Lñ�kº7«°1ÅY4^)bٗ¦8ù¼yøÆ�ªäÛ
  20363. NžØ=ƒ›9zT–^[T$‡dkÂœ QâiK%áˆ6Žµ�üqµéçõÌîfO|àÚàcÐ8$•ji^vrþ.QQR"âYárÄŠãâõ¸ ¨Ãkø’¥ÞrŸº¼Kˆ¢µ<QI‰"·@´ïêR9 öÀ/½«\&7Y}m‰gÒŠ7»œz6¸-Mùu=‚Àé,õþN3O\º6ŒÃaDAŽ»Þ®ðLd^rëÉ/.®>û æè
  20364. N·eíÏRiû4¦¾Õ!3Rù¢º�"�4¦ˆÈñúšn™bámÉ-y[X¦¦ÿÏñ."Æô!”øÜQK¯åE\N�ëµ4gÕ ×�ø§¿¦ƒï±aN¦p‚ >k)9ÁÁ0ˆB�ZêÌBs
  20365. ö¥yŠrŽšer«)v¯¢®Dóëtèrv�\ûvù[­ü>órµJmœ�–
  20366. aœò«µÌ¼›~uÝêêÕ�º>µrMZœ°˜cíB<øã`)\y×t|Û�ïÿr'<†ô˜à>ù×Öþã[æÃŽ—ï­èh7ëú­þZÅŒ8caI�!¹ ´p⢟ÍÌ®�,¶GÃí »k 5@ÈÙô÷ÿ`ôÉiw ˆÒnО8pŸv¿ çÉé*��²Â'O
  20367. ÝÔüŠ² ÝA[È.¡¤r�hóT pR?+;Ëÿó\*H‹sLqÞæëUš¹f–â:ql-ć¤ ñ*6!…hç+ˬ�{h·‰ö- jg±kÉMMÉ×P#ã¶ä:¼}‘±¸{/ÝëîVËßŶC]옙ê·&[³W$Ú«^ß#àû¸¶4fWa\ ‹Á5ìð躺M[6ž½)T§3—•›~üÚέÉÔÀ
  20368. ã:. Z”¦¼¨`sÞi(ÍRô©Q…¼²Ì|/ú`ù
  20369. ilÏ^°L# §÷òf¤-ñ×;-C;_ÜÞù*ù{@EMCooÂ_¤œÆÃõ7¾TöãrqzÜFµ%ׯ|™šU<Z¤ÜoÁ[TA=Ž„Ð'DPJ]´;,U9¯µÊQ›±ÓpŠžkñ4~€êáÁâ_�Cª^™qE¢Å®�œb �SGsÚøßíY…�2N–A®Òuí®%ððSD„‚ ×hj
  20370. ÿy;9$ß´IA¨ÕhäEO�Ì„á²Ë}
  20371. ¨g‰³¬…—/+ ùÕƒ“ï5�JYÊ @äGúø��ü¾‚ê®f2�¢´—Y Äç/¸Âß¼™e„ß·¹±|vÞ/¸"ÞÿÕpå€Ø~刋ñTãô8OKór*ÒžÝ* †ƒÀ4hià@Q›™3g"Ñj²Ÿ:ô$û•;:”ý¤fàÍü–÷Œ,d½®®zÍÈÈšÙÆԌ꺳°«u%ç Ë£}Oõ&³¾‚i2Uè, @Íkêj%u?Ûã4§NœKmöÞùÐd?5ÉÝ“;Ê0™Yï�Úüe}sZô€‡ª>EÆ«Us^Ýœv{ ë¤¦fQ<Ä�¡‰VPüïÃÊTfͦî?¥�õmØpÙP*�È&¦÷ÐQ‡G‰ù{cœJïñEPe2)ŽxP½0AÑßÍûMɪZH¶j•"×»"ÙA¬ÐC+zq‰mVzá–žóU%ØCµ�:@1æãðW¹Š î[y)ÎJ@÷o±b% ÷j”A>)NÒÇ€Ôiç¼$’AóˆÀìt`>Ì?f0g�ÿH36pè6áÌD|ûM›ä áö4N�¡°
  20372. œ’ 4J½JÚƒ¯
  20373. µj¤ž˜Æ‡´ó\ íp 3ÓøŽ£8�À¦ªÑã–Яï”»­6p®ùV?:¬$‚sDùÀNúµƹ‘2ï’n’,¶„HÝO\‚[¸øÕ¸›öKÙ-)�«W~¹iém™?ÿ®ƒTÐ:°ÌðÞºUÖeYŒÓãŠ-#dJe)¯±ÚÏZªÕ5”?ø$»æ¡\d©W<·¹¹,Ɇ†š;¯Ø·¸Ã5ÍÍòS¸Õ¸¯¼—T«T–ñšÎÌ„f(�PY°v=Q ~DX*¼ßÝ8ø辩s- Â˨®Î€55 ­ X¢R¥l QCÏá¤Î á“øÑÀl|òý5Î{ûÓ¦T\t꼕+éï£e»nÅÛ¸‹’ÂPsÓèlû3™�ùUO©[üÛîÇZ»ÉS3åÀ�îŸ�*èì,˜ª†ß:ÛZþ¾ÆÔL‰›¬†ÕS��ô'̵æã*õòŒ*@¨ø�ı~xgno2±¹áˆâ-
  20374. …Œ ³W³Š«½V�;äpZå9�?~„«$«6Ÿ<”µQr‚bQ8&óse•ÉEb¯ÚQ,·þ^|B²µï碘ïVd¬V-¶(Ü]ã .ïèËŽ8/qhV¡nR®ó®QÈD‰*ùU(*1hç1Ã`Ø�QL{…�Uj `àÒ"šo3�Ü»æ™V¨l…µ: ÑíêÂØÀ jaFaàžE­¶ÌžZˆ‹g1±·zü°Ì2Ö Õ:ÍAuÙZIf6–ƒ2Õtw+Š‰‰f�§D�‹ïÉ誩CL-}g»µZ³0>Ò„óxJ¢ýÿÅ>\î�ÁëQ‰¸AÚ_C¶i‚hßÒbl] ‡6ÞÕÞÜ4*šA˯É°üqX‰¤7„»YòX.€-¾ŠÚÕ¸•aɇÃVâh¬–iKg•ÔÏqN³RĆN(r'Á]¼à%Ù˜„�…­ô�ˆ@3ÔÍ€ÎÂ�j§Z¬÷J†.;üãnmÝú¯ÕÎ,SûûØ0x¯³ÃõøØÍ»£OF33­Ò§¶…«<$'Û»¸G—E+´Ú}¥¥Îóúó§…'1ðf3›ÆýÒyÐ5Ý/&¤Zœ\RBô7dmíô]æ¼8§§Â\Íý„3ß‚„Ȫ˜@÷ìo¿ûTé¿3eu^·W@Šªü”–Ž¦e7l–!Bã,Às‚äæ1ÜÍß$šäò¯ÛZ§ã&Ù’ç?¯âdCéá �(YЦSm>‚J"&ptÞ܈ªP㇄BF¬ø´�Ú±àÙø4ŒGá5œ t^Ć$¯Þòj-aã �g^ÁÊ�C¤–…ƒAsÖT=k¡TS,|€ràåš9I·½BϘЬ†ö'ÂìvG�A¶Î@�ÍtÀÌhQÕNj†&€åT=Îxt;2]¯P¡|T- LÞƒ’Éç¿ñe1ãݽWÃZÅš*MrH5?„ñ‚=à�ýÑo°¬"ëÆ9ÑK5Îø=«'kÉ-*•„èA¦E| þ Þ qÒ”‘_?\£7%öŽ|M6°fª+““+’S*}çW�_Ü]3ª¨ú¶fmÜ®ØÒ˳ÒÜm w!–—î÷å.ÛR#‰é¬ª;Æíú¦±q qó71ŠÖä$•ݙկ_ÀóiKà&ìJ©Î¬M®Š¬öÞÇemåVÄ5PÏ0>¾¾ Q�çµ5ª†W•©H­Ih×åù&ù4Ò�IlÓE7}âsÈéÄm[cȾ좄|�d^ ¢ì÷%Uvé1¦D“²>“.èT¬Ò7*é=tƒZ¸_§ãŸ¾1Ð¥:=0pZûš6Ò‹ŠN„t�(åuíÆ�­; ÇBÒ]³‘$€k¡ÚŒ€Â.ó{ªFÄ*/UZ’ÆNüç ¦|oqŠÊK—G;^Ö侞9N§ûeÿíxK‹ ’¡¨\‡whþøñ~¡òòZpHÔb‘‹Í䉸 »ˆÛ[k¶8âÉÍÌk÷â.bX.Q¾Xp¸xYa^µÐ"˜Ñ#럙ãB³wnb¤¿óå�uÓð ém5žF²½~>ÇÐ8€­ÁbýúŽäN:Ýp4 µ[gv^
  20375. B½ÓFÐUzû)?œ¼60�ÐFÉÉ8˜‚�Â/2 ŒC8¨Œ®>�N8Gî�Í%ló%èÝ5ºFH˜{4„6h§Žï¸4Ž%Æ# 7¸è›ñŽÍúËx óoºÜN tª\•'ßȨ ¨ úæE£�Žæ½0#ƒïj¸NãVïÓ¹dà?WlcW��×ð‹ Äí
  20376. ž½Öµµuû-“»}2„2¨¶¥EN�¿}#‡äµµ2H^a3ðõ»¥r»Áqs§¤°ˆ„-�S3&Èïô„f´í‡£ÌëÎfwl.š=Wø8å„,õàÒcHá®jžcTê±W®‘× s�9ò0žî”ZàDÎM“ú¾C2’ZM’�Ýû�djµŒtŸ"8À:gí{.Ʊ°Ð1Fb6ƒ1Ç8"yÔ¦>˜õ¿ ’­WÀ9£ë ÓVšŠŠö ¯`×j¿ý®š�¿Tò””‘‘€<I£½MÔ±W'%­f&¸\yäZëdkÍ´èùRyÑjw˜æ}ùˆÐ€Ïß[8ÂÔ�†»£ÇbBí ©'d'müoû'<�ø|EÔÊÍ5êõ:³¹Ú‹o¼š©É>²µr,nƒ©iÀ­Á <Tª¸S¹¹Ÿ>¥d³… ÿôéqN§ªÝ .g+ ïSÂë¼ Qúù·�¾ë �áKaB¾ŒÛà?_í‹ÛQ�E ‡“µr¸†ÿj¤î‚h>ô•E¦�Ó›;�C�×­7…‹·^q¯
  20377. Æ`U¯eú#-Ÿ˜·;oJ˜Ä‹ãÒæŽÔ�>) Çý‚;Jgí£Ï×­9R;Ogí¢ÅýiI7ú}—â8K¡’œÛ�q¦j�¹ÑeØ“£+Ù—'nñÏ·k3‹Á­»üeFÏ�ûžì…0±šò¯ßV#©íÆp¥MAzb^PŽ÷VÏu¤Û~Þ1uº—Ò“•wnÈ ^›.II—¡Š_ÆÌÚvdW®Èö�óÎ[Q,ÍÞè+L¾b‚í¾É¥å„Æćq¼þ 9«V}ï ”Î�VÑw4qUä3&jÛıHYb¼ ü¹ˆ ¿tt�Tœõˆ7Ï�ò’«ÙarBwP9?)Ûu•é‹T/Ùa£•ŽA19–±kªM
  20378. \ÓäPÝßs›<ØTaž�Ðã@‚<?Mâ (ê¼.¡,'%?,Ç%�a~eÎëŽÀ�ŽUá–0µÍ/zQÕö(Ѹý“÷¤a™¬ªp:.6«jÂÿdF@\V®4¦É{ÓRiìþ ˆÍ8é¯Éªnuý®Fï˜M_†§=¦½õZ8á¤HãîŠl‡sy5k%õÌ|(ði9 "Ù6äº}Ô‹~WK„ÛŸ‘hY©kŠÊö¤—\àû×l“RmŽ»´&Ò ºæ¦ñØò0¾ïÁbû]gÊ”µ¾"ÂçÞ€D^ý²æ¾ÞŒ¨jÿ±J*)žš6¨µ‹-YbÙhÖà÷òé
  20379. Zý¯éß=Þ‘¦A,ŽÊ(Ž�K#Ð –²OfÈJ:î;¾I†¾Ç!6Yi&ûdÙàÖ%m®86#ªö™Q�µÒÔÌW_‘öA›v}?+èGášÊú cc*ÿmûô’g`Ò>…õq±Ø+û£=Ù[5ÄÍ”·¶Ö×?²9£WÀÉ+^ýo¯^Eàã8s�)å�fç —2aôæ­QŸx¤·i‡é& NE>"^NaäaŸ;fŠÙÌ9]NE& t^°ÀCLz'âe…8ZRñs&6Þ²7_�üãcyJž‘1 Äþ@TZ°?S�D2û
  20380. ‡|ÔPõÔËOÓŒé\dªRïÞðû7zHÕøƒî±9iÈ�‹Q#µ¿¶‚zr³óc.ò4ö†GýR�4ÎÈqx¦ð¾<2~X’hµ÷náãੳ¨Å2ˆauB­NCÑ�+›¢k—Xó0Ñ aj5n>Þ‰¨õ²e3övÞ§Óôé<¥>�°_²Ÿ� Û uH: �XR�ÿ%~9á!4öüoÑѼ¦è�3…ºâ”8?¶‚ Î1d#ïÔÑü–šA&‹„„{A!i6 ‹ŒíÜ/Xa�Ÿ£á㇤=W‰;|ïðä)� Ðg¾~£ ?*¾æ‚½Ã }¿ãÚ§ˆKtÌ>5|­EŽµÐîÑÜÕ.§ýôAûš Qñ6üú ²€¾(6
  20381. 6Ñ”Æ7�–Ú÷<9ùù_ð•CÁ f1þëÐŽéi8¾®†å», V»4$ÀŸutÉøœø£ÆiÁ,.`v6r â£òŽP ¯½gFB�ÉŽÇ
  20382. tòÃçÚ C3½;˜ ,¼o“æãœx|
  20383. /KóMp©1S_¾‘X.f÷V�ª†#¼U>È’Èõˆ#Böñ]µ A�‘IVoÀÌІϵÀ‘¿üGTV1nr+£ÎOXÂS•% ‹›³¶™f§OZ[Û_ý9œû‘P­ß°÷ {Gln‘%ß#ÚÛhÀdw¿H ù=† ¸y©e/íªW¼³´¶>Ò,Óö¬°IP,*MV•ð„~ºK&ãe¢Ä‹»ûMì½£=ò)‹qF¿ S¶ß´"ÉGÑëTšF™�*¹LX,hŠ[—´º“§wŽw´íeñWQEÙxÚëº ?áè“{^Ú†EŽxïh»�iý»¢×‚�„J”³ÃÀH�¥|ó^ÙÍ“Š…Ée*^‰Ð¯.ãuÚxE™èëËb#î;›’ôÔ�<]z]\íƒ×�¨wÚN»ho¼chq¸E˜£=ºçâ4Q1¸7ýÝçWü½Ì“lÕ6�᧿­HE_Ì£ ùqyÿ‰á YRŽ¤Û«<x=ÔcSßXy!=0û8Ç—óxÖ ˜�ôþ?±{}¢ÿÀîßF_„üáÇ ™zø¯‰kt©É±ðˆ7³ÊÚ‚|tû§+a®m¸<xe$‚ée–�ãÉ�ª×<[¹T÷¦ÿ�X[þáš žø£Ùö�¿s»VÃÌ‹«Þ§UžÉ*³áŒh—S©K=FeËsw uYéoÍßÙ¯nQ«³=NE:[Ò(t]å k×|ç@‘Ù¿uZ\9{h�±�v€ÚÜ•Ó†.Ú¡úsaƒ‰$u+Ÿq¹w:#ãæ?åeúT‰3=ЬлÐ!µpìPL`Í:…“ÝÐR; ØgÊ® �Fha�Î�;¯Ì†5Ie +–ÛØõ» �×bt06AW40TÍhJcc<&ÀmJccà
  20384. ¸ �ó¡OCn«W?üùNÂiþî¾o](XЄûŸ{÷Lzì˜ôÙ;¿ðØñg¹ï|Ç�ç>ä9~l4sæVyù­™`Š×Uß›,ùŸþñ×Å#_Êu´ù+Deêêí™àéMÙü¢~h³qªë²‡’·#YúÊæñzü$;Û 5ͯ9$µË z²>ÿ
  20385. ¾*jõOŸ�øŒñÛ$œÐ$O/¯ÀÃxRí½ƒÂtýf-}*žoïɦøÙÌ|3†M;xÞ¨¯U”•µl/.ñ~XÇŽ¯Yá¼4™x3&æë×x®";¤$�KIö’5ÛdÚ­ ½Êáüú‹~w[ÊÔM9OØã%4ÒáQ¨}éS^žìt–�è@ÑËæw[›Y;-Ýöÿ�Àºs;¢b¾ÍwH-* ï––Ãim½¶IÊ-¶1e/•~ø¨TNN®.òp²ßð)H$ûë«Wïß~�Îð�µÉƦí¼O
  20386. ( é9è†,Ù ]gM6rê+„#»%ƒà/süw¯Aœ$õŒqÆ4ËO>
  20387. d9}÷�+ðÑ$Œsôš³ý?0£™a,>�y‹¹Úˆs<ðþ=†,ð‹c_*\âƒDí¼Ü}È2Mí°ÍÌT8/í4ægæ'Ú¦ž�â8'û}"‹Câ*„\9½#Y�>z$ŽæöÔ7c[s“|"$}» ymÌïÕÀ«zQx 5·%å oùå“$j†kÐÎp)ñx½Äû-:º†Ð˜|?�˜oãøf§‡gFrÀžß2ŠS‘ÇZ÷Œq}qˆŠµ …o€,wyÅO¡gÊ�CF1Öl˜çŸ'íL5T3õò3ûÑðyª¦M‰9Ú2"s”˜ò5uD•‹6ÀÔ-Jì‰U†bsºÏ
  20388. «O)ƒÌw¸R -2æ/5fÜ<ªBQÌ4kŒ˜ê�­�G¹ )%ß¼ã<dÆàĪĞí¼3È2 `ŽaØÃ]©ªS{£K%ô\]¦3&�Šp„“®®Ú¸Úˆ”CÕ¸¢ ýœ©ë†¶“,÷À Úù^éTÐÙÛ7¿h¼5™uûlDÀ£xÚ·¶—ñL'D¶ð„rÃ6úv Õ·fc\þ£ý§µgAê‘Â�³ †²@�?¶½žÂØÁ‘ œ•GFæÁVA·l,¶µÄ:§¾ •i#~NUûæ“DV~7¾�k·K`!ˆP–ìMX³üRÍÆ$#îTiih¨ž®omÕ˜Å<.8UmÇ<’Î3ïÓéESä4 Ü«�úŸV9²ò'½™bvÒ{¿¡ø?îVVÞý£3�×;”U'Ö¬‘Àµ1RÙVé{BÇôÆîiŸëº4C RhÜéŠr6~˜Ó–�J”¥PàÍŽÕ÷M‡ 7GŒÐ�-,NLo¼ô<Ÿ²¶Ñ£zç÷••2H&|$³²’¼<{ ¦Úœ“Kä_œæÖÿmmSŒ)>r’Ï›f@=šâBF™‹ïCB�±©‰‰ƒ‡&'‡F}@©&ÓÈÿ„y×ubâÐÁÉÉC?'«êåñçSæ49+—Óä±Cø®³íIîð¤ÙŒ+×ç˜ëf/R«Uê ÌîC °Fu:C*£} †T:º¶}{ÂÜݽâ²·ÔuªÎ×ø•¬e[!®–>ú? ‹ÄåýÚ¸¸"ÇM
  20389. 8gzƒô0\HkƒÔZ³:Ähå­~™@ª+ô#«N�ê Öfj¾çyµîå‹ioÀ!„B÷ þñô·“±R'©5>Ú`Úò[!ÂÄTˆ`mCš� I…Ñ�Ã}¸n
  20390. �>Wßô!M}UËavõ¶4�€3)!§kcÈ‚²ómþ?’Ž Ýådïw•ãv«!×”;XÏ¡Û¨}½8ívt•ëÐ"Ó¼# kÂvXŠJ™±[“l�¶[ZÝ™MÀ§ñÃXC3lê–[ ÃTa¼Vj‹¡…ÚÊ»¥åŒÑ¬"Å“Ñò t:‚(žêà¦ÈÁ<¾cZóve—ýQ›ÇîT…Ÿ qHá‘i{ Ò銀Q埓'Á“Ö»“i öPØöï¿­èüȯáímKÊAçIŠõ¤��BFƒ
  20391. £=‰‰µâÖTá…½¶à(âœ&TSŸ?/ïØ�A:Ö·¬»ÐžV§(ø÷@wïFa^ã¦]…Œµäo]*Óñ99¬R¿iáñ_Ôò˜À™þÎË2vM“€Ø`P§“ôf¦´{QYÏ«íH#V7vÅ7ÌÒ° q>@àó«~uɘ׆Ax°Ã/ƒ«xÙ°Bþà3£Ä Ùô‰�tƒÊÁy†b0ŒžnG`Á òEÚDìÙ�äA’Ô: ÆPØwIÓ7ÏìnWÓ÷2ED<hD�&Z˜ˆÃ Π7Í3á&úÍë)LDË4;Ü7èæÑ´?$­îËk@Ù"ö¿"L&~§ùö1ʺf«14ŠÊ±|îÚÙ7Os�Í}úÆL1;éÝ?Â{1$�ƒ¯w)™€1}Ðà0è~7„Ú# E5Šª`Òq&o ÇowÞÍ ËÓ_“…é´ŠªÔ8Q1Û�Gó»»óëùÓÉŠùêù08å×h¸äW¿e ˜+º²\êåÔ‰†R‹ÔÊ“ÃU?w®àeÙôïOÙ�ÝSx�AUÖÌž3˜| =WAµÍÝÅR�
  20392. Pñ°tO%Q"1Y×”!so%%­^�zÿ_hn,ý{?ÔÜø"L¬5±_D6©îì+êïÊËSbÆ<�à§ÌgfJËô¥0äbì_ç¡ÑxÔ-í £;‰H«âãââW‘:G˜MðiÄEeÌIuª®vJ]~mÈÙßØQHLKkì»ÊhbžA>}.(h•Ü"‚óãU]¢9Iíh_îV¯@‡›GZ0C
  20393. Üpb ó:ã™L 3�¡tN*ªN ½2¿Ó!¼3Œ� Ca³—yn.•ÊÝÉ‹Wâ`̳Ü}±QBÌC�ªÃi Á¡8*Ãï{57‰¹ìO#aT¢ËB½Ÿ‚½Uíoþi§0ç ó_ËðÑù^
  20394. ChrU}~rÈL 1òzÿ>..ö=%GÁš›GŒ£ ëüo ™�‡ ŒEéu‘P³Psؘ޸èó8­ðüþP¨Ÿu&;æÊ*Œëù|i&¤ÿPbÛÈ›°²˜hÒ;´[—€|y*cƒVšh†Ò¼Ò(ÿ”~Î_A•qU2·½ÿôGIQÇ3`®^Êvþ=î@¬ÜK'¤µÐ‡èËZ#4sJ=º¤:sY©è sÚ¥bÂyj ¯ë·S_E܃"Žª‹Š@ž~‚Ÿç¹>­86ºñ#Îy±Úäå[ïècòSï„¥ÙŬ–�”òò#­SJ”GZû®yvvÝßSùÑ�æ‰�p¸waTšžÏõÅ/,
  20395. 9'Jkv%%.†~oò[ÌóŸ 衧üœÂR±Bj¢ŸSèÈ€*$'øè…�©pçS¥u� à+ç9\¬í_f+åòüù8õu\,¶Ê�ÓtæåðpžÑ�ÐkØ®J0hó(]N„QÈvó³W¬�ÇÌ7ó •8«ƒ6:ÜÖÝ£Ïâ ·ñWc“¯Y_i>ú¬ŒÝ"‘ßR¡çõ’â�(Óe]Þ6ø¹ªRA%U—6&´F]”½7@̳k3X h�?ŒÁKïà®Þ�Q¤2™Bk¾[<o¥-[ �s~Ÿî0¯�]Tœ°Ã2ÁÍä¯hÊñÝJÆqîK¹v§«Ÿ(32Jºþí//W…¼,ã¬ÃÎÛzï �d$2ÑcA´kP”¹— §”Kÿ+€î­Ec¥ ÛÂÜà[Qžùàóôùûiú—EdVÃõxR8šäBÐ5ÚÌÄa=:¢�KQ˜¶�çÓ\ °@ÆV»^;KrÌ —M{ü÷ñÆ{#þóC�w}{^,í§$0Rcÿ\o¾«Q½Ñ¼Á×¥PüÊ$é†YÊvpà®>?.ÿ€Ã.K¡ÈKAbŽÌ6ýÞÄ5¿·kò’eŽ+]²F<HËe"ª;{wN‰yx/Æ×å&f檄/XZ[Ÿ¤7»š¶c%ßÅ€5½d•Y_Ÿy"Ыߞ£2\37×
  20396. – k\Äë�²|FO Š’´68Š¨ñð…‘œœÃïü½„�ÿnKðzR"�ƒý‡ –Ÿ?/7Ð32š:аá>Ž°eöWH©Uò«û0OÝק¾5…´øÿ ¤úîäe3H‡®coÇ>l]0¶2±ˆcý¹‡ÝHÊ9š{Z {sOõ–!¥A,þ7†?Å·3�wä¿ŽA
  20397. àFjÚÿ¸8¸Bí&8U$G…¡Â�µÙßé$µY5˜‚†FâL…5nÇì²Øò1–”> qóº2££.«6“e—é
  20398. î ì¼Úõ—œ+˜–@/¬¢ð™µkíb{à÷(�Å7Ði=¥É{lÍ�¬Ý‚­âÎ濦ï 8«…1g�(»üè%ÎÓh/ëEf¶M¹Ò�ÝtŸ�5½Ÿ̼vg½oÚ ê~à©›WKi父U«ßأݖ­w¬RS‚EìFíßT¬²%ª `=í‹ø|*=1‚ò*Žù»ý·S§Xö¬€·Ø^êòÓw)l–ÃÖfQ�HãúŒ(YSþô„SËŒK�·æ1ÞØâíW]µf™Ÿ·°7ך³^&ýpô@T'.ìÀ%3�³•„à š�¯´ßÞò»ù5ÏzaTf6Ñë©A5ÜL•óXÌ¡æ·Á|ñL¸-Ÿå–ηêÄT×g{A)ªî­®FÑ•."hü“ùj¢ A;.ðâ~Âþ …oÞ%°è ýG#Ñ}&]Þ×¾cÜ`C»hH9xnN†·Y Îlð²cÞ¤\+v\EŸ¥«Æ§1¦D9K·Xá)2b.¿ó­“NôÚýW¢§ŽÜQש$¥/£”|6tð™Ã32Ô›£´7¡¡¦�–2¸ÑÛиyuü0e×ñ€)’NØuh'dœ¶Ãî„õ�~xY‰É ��‘´>ÄÚ# bˆ"k3Ó𠼃®Ì: 9¿º¢vˆú$ПCÝ:Ê)H¹Ë> Õ¦šzÇÛ;e“d\jmfŸäOÏa%ò9š‘ˆcK›xÓÐÛ¥Å!k©%H�ÞDn“ü{YÜ"“{n_Ö}
  20399. ß)9ƒ= _/û‡ZÎ(éù>lú¶­÷YžŸÖV÷‹gQ#§ß­:QÄ•ÈbwƒÇ÷Õ$¾zw±ðÙ®‹#¿»ãU˜?|ÅðïGÔ΄hÁzü{ùoº$wñ×Ïœ�´º)|Vh‰Ú?»Œ ZV�7¾%ŸüGûo/£×†‡ôéEÏ"¹KÓ²… ìµl¥p76Î�-z !Ál€4n>”¼$\á×zV?szûqejìQçëé]m‹›æ^æ=^µ ä§í­¥! ²ºl…ôHB4sL i9}Þ2¢^×ýKÐ5ÅOBú)èíO ­çv^~ªêµýïÝ€x¦“rm\KÚ&G^Ð5�CçÐL¼}&Fºò”ÀËâ¨B]K†¡n3††|ÍsGjyðkþO¯µÚbåsܽæaW?R6ð¡·²¾J�ÂÇfhãÚ2 ÄÊlBS§\=¢jÕÕV—Ê*”ôY¦“^¢¢Á™„˺^E)Õè*”\½Ÿ 
  20400. ‚rÔr(a¢@ø„6nÔŒ£?¥}ÚdL°©¦�šg¢IvqØNcÐÇa�‘Æ®kŒÍ÷mLŒöcÁA!¤±hd¸£±Vëðµ¹Îòwc=¢¦æ†–áæ–Õs_Ò:ŠÿÒ—•¢sLËí£g>‘œ—1Ü*4-%ð&Ëõ0Ubƒ)Eܬ�†*b¸ÔÖ51—Äï„ç ä+è+;˜Ž<…«†’`!q°fÍÎMù*Æ,[/GK+{×®�,>CâL�Œó�R%%cŒ³ÂÆÃ~‘’'EG�†A‰®GºÂ=‡hÂ䟔Ž°8:IDìN)ÅWÌ»áAF)ucw'qhÍXè²L@a„¾~Œ6ÌPc2Lã"¥A…2bìÈU ™À&Œ€‹ÿ ¯9öA#ÓQLO¬:�E€9k§©’‘ÆfÞKF•b93tºL$c‰Ë¬pÿLzÿ ¿5ÔdÚp¢þðùÛ°>$`œ.÷ï«~Xó=¶�¡ã?„ N�Í°/ŠÄ©L®PªÔ­No0šÌ«ÍîpºÜ¯Ï ‚b8AR4Ãr¼ J²¢j¿}øŸÐ Ó²×óƒ0Š“4Ë‹²ª›¶ë‡qš—uÛ�óºŸ÷ûAFP 'HŠfXŽDIVTM7LËv\ÏÂ(NÒ,/ʪnÚ®Æi^Öm?Îë~Þï÷‡à ’¢–ãQ’UÓ Ó²×óƒ0Š“4Ë‹²ª›¶ë‡qš—uÛ�óºŸ÷÷ÿ�b$œ«tV&g®Ï–íÁr>¿<Ùyóå?�’“˜�ûfþ{�ç´·�£�‰µ›ž%îµïÇÌ~ßZûþaÅzW¾¿¼÷ÜõÝ2Ÿµsv�ïÀÌò�™ÙeW«�‰µ‘à����@DDDD$""""bffffÖ}�X ÓO„0ÆcDDDDD¬µÖZ›6Wò08BÖçI¥������������ƒ.H¬�W������
  20401. ¢ßˆÇÐ9 �‰u„*¥”R*J^}€Ä:M”´$I’$IÒF‚‹™™™™yÑŸžûÞóÀ_WÍÆý<G<þ��wOFF�����[€�����±\�����������������������FFTM��X������m*—ÜGDEF��t������ D�OS/2��”���E���`g¹k‰cmap��Ü��À��rÚ­ã�cvt ��œ�������(øgasp�� ������ÿÿ�glyf��¨��M��”¤}]Âohead��QÀ���4���6M/Øhhea��Qô������$
  20402. Dhmtx��R��O��tÒÇ `loca��S`��'��0oû•Îmaxp��Uˆ��� ��� j�Øname��U¨��ž��¢³, ›post��WH��-��
  20403. Ѻ£å5webf��[x������ÃTP�������Ì=¢Ï����Ðv�u����Ðvs—xÚc`d``àb `b`d`d’,`�H�J�xÚc`féfœÀÀÊÀÂÌÃt���!
  20404. B3.a0bÚ䥀 ‰êîÇàÀ ðÿ?ó�ÿ@u" Õ@aF$%
  20405. Œ�1– ���xÚí”?hSAÇ—¤iSÄÆþ‰�mß½44±­Ð,qÊPKƒ qÒ ÒXE]²(2 ‡.¥Ô©ƒ]´‚ "EœD·
  20406. ­¥¹ßi]DÔ¡ZJõù½\µº8ùà“Ïï½wïî›w¿„ˆšˆÈ�V"±F¦pUÔ¯û×â.Χ(ƒg’KÃ4O n«;âN¸‹îR{¼g`'!ÛÉP²MùUHEÕ J«¬Ê«‚*ª²ªªYq”9Ícœå<¹ÌUžá9Ô!ÑQÓI�ÖY�×…-Ïó°¢KCõ•è+ Õ¤ÂÊU)•Q9¬4©Jª¢¦Yp˜]Nq†Ç9Ç.q…§yVV
  20407. ën¬×)�Ñ9»’÷Ê[õÎ{“ª¥öºv¿V¬å×›Ö¾¬ö­FWb++{Ý>·×�¸a|ã€ü*·ägùQ¾•òŠ¼,Kò‚<'ÏÊÓò¤<!�É£rÔYwÖœβóÜyæ<q9�{-]öíþ“c�ùð]oœ®¿I‹Ùï!0l6Ì7‚…Í�áØ{j�G,ÔOX¨^´P¼d¡Q»…öÅ{,ÔM4°c¡(QBXè�¼m!ŒK†,Ô ·Y¨�Ha¬2Ù}«Ì˜˜�0B«AÔ)Ø�F}΀,êQ8ò¨�à �‚'A5î©(£>W@õExÌ¢¾DÄÈÃ&ÃUØd¸#› ËÈÀ&à x õMx˜<·aäa“çŒ,l2<€‘�M†Ç02°Éð6óΠ^†‘…çP¿$Ò�6{¸‡,´#›ÆžÐ{ MÎwpÌBïá8H¢þ�#³6™7adÖ&'~‰95r
  20408. 3wÁ"Ð[žEt’ØÜW‡:ýÓ­:$"ô™>2Íÿcÿ ò5*ß.ýlŸôÿäN þ/öÿøþhþ‹±Á]GtýéTè�ßß��Ñ�(ø���ÿÿ�xÚŽ |Õµ0>w�Öm#Y¶e[’%YÞ-YR'rö„ÄYÈj¶°D% �,@ØBØKZjHÙÚ¤@b¥¥¤-…RôÊë+¥nûhK›~¯åË룼–¦¥$Öä;çÎhµèëÿýþ^fîܹsï¹çnçœ{ι Ë´0 ¹Œkb8Fd:Ÿ%L×”Ã"Ïü1þ¬AøՔà AæY£Œ>,ÈØ”Ã㎀#œp„ZÈ4õØŸþÄ5�maßd“e²ü ?ÈœyÇ=�¤�øI:C‰Ç “DÜãõ(nI¤�xˆL ‘.1¢!„P'™JD‰t‘Hj€@L4’ì…P†ô“h' )ÈbÒ)vHŽX,fù1Ñc\'²âcGÍÖÀ±„u˜�>ëŒñ1Ù ~Âtüà?ññ„éø!x¡øÁT_qâ?qB‡ÛÐF‚‘¤#ŒL%½©DÀÑ›"¯ä?Y­øýŠºÇ¯ÀƒºÈj??8>NÑSkem„²¦AY³µ²Db¡4 ÙJ)¤•;•@¹j“ÅP$
  20409. ˜ï'qh®8`›ë;aŒê�XÍÃ6C�ùFâ*„dËYýcá±Ú"ÔŒ‚ù„Ïù£Ûø'?hÆL¬Vã—ŒÖ,½>c‘eË3eV¹Òh† =Cû‘Àš†éÇ~äõxC½�\((qb@ ¸4ð‰x†K&h×�Î ¥©4\2ºÇ±6N1|-Ô;­Ïëj›ï–É YuÔ@†ájêî›Ñ«xú¦õ†ži¸äŠ§þmKó ëÛÙ�DøEöw¦q3ÿÌ·.»¼cAw@¶4t.Žgãñìükg´Ér°{~ÛÓWl~¬{ÿÖlW2»êöð} Ã27Ð6a2Ì\€6o”z@³$´ñ¡ÞëHÄSÉÞHˆ «g®›Ñí±bõtÏX7ó0KštÔÞc1Á,«Õ7—Bò oLëè˜Æ�Ô6Ä·6[,–æÖ%ñiáZ ¿‡,’l>T†pòK³œSGg¬\> ñ�#»øAö#3Œ«ØEµŽy‚kÂî6v®ìÚçè…Áºç†;u3Ó!ZIÎ8ì˜M�†k?³8¶C˜£Wq{`ìC*‰Ðh>H��Ü1¿_söÙkâŠìh)œ›ž®ojªOO'»
  20410. !~dXñgÏûB(ô…ó†ýÊ0< kOYxÊe§¬©±Æ§Ä­5k¦ —=d ã²ðÓϧ> íü+ütÆCç-o
  20411. Ǫ†„/äÃõ_koïܶÿ¶¼sñÕ+f°ÿÎOßz±tpÛu7-™}…dõíþ9Å sàˆ©e Œ³\9.H4’!0�¥S\ ʱk2™ï"?ip7œ\2z§ÙÔÔlÞ°Ñt=¹î…Wùç\!ûKyOXimUÂì¾nov›ì ÛÇ6²:½èå 2Æ óLZkAýAÍ^âqCæ™Þ” &PæˆïaFÆê¥Iª0Üã>þ&ïù…Q �#F£Qý»Ñlæ> A³·q*˜O‚á­ýãÏÿ‹ÑȦ�æ_@27¦ÌlÄ,¨‚�sþø‰Ñè¾fÈ ¾6âp7üÜ©?�úÿMþ›Œ‰±1vˆA˜Ü2‰¦]$j"‚‹;‘vÛlk~va0¿ûgì¥j£úÜzþ›¶ÝRD:ÿg©×濱cë6’ÅÅywú%ôgâ(þƒØ#'´ÎuBµò#ì=ù_@?ƒ>ÆFØýVbŒ0žaá!¬aL4tXv¼¡ü:ÅFööh÷²9‹ïj^µxÞŒü¾¡ézÐÏ}´WnŽ}7}¶×»j“¯ÆΚÎïi½H©�­¿º¶ÆÁÞi¥ýÅtêïüKüSŒŸ‰aÍXEôºEºbbBQ1ØÉöf”t‘x†ôF騆 ·-"dqA÷×Æ\ê·~F`³»è6²iä�•+À ÿÔ¢Û^ȲÂ}שï׆k&»ÝĹ¾»íÈà<- \èœ;Äâg1>¨w†0Ü0ßvòÉ^x ìÝÝ7lÛ<”šyÝÎ}™ÌS·o›9éÜ-Û®ã¾6kžÐ±lË´¾ën¹ùðŠ‡o¾åº¾i[–uó—§~¬æoà`jàÁ•Š{i×\C4,"iW8’J�oñVò„bp¨ûwˆ²Cýªºß!‹;Ô'7×D.v¹ÔÇÖ�Ô n‹õoZ-n²ë¤ÕÁ°eùÏP‚òŠio4Š~LYä/zmþw_�ÿò�¾ØìgþϽŸþý§RÞÏ"tÞ Ó&NoN€¥)4ÆÉM ³CÛG2«‰\j²Ê8�d-É@>#ÛOt^¶Àì5¼+x͘e.^á]ƒ×¼à²ÎÛG 8›^æ ômŒ÷(ÓÆt1 ÷s™Ìbf³J›°ßÒ —%‘Œ‘ â<‰�¬4ŽÞHâø”ÝÅ@ešê÷8CÈÔòŠ,»5<Â(—åk²c5Y®I¿þ¶ìÍØ—âùAøú]|Åךål6+›Õ=øHVãcb´KÕ‹B´6ßi4• #´‹_Û©|&ó>NvQŠk#®pW•=ä¿uº7”ÛHÉ°R$ ç÷�î ³[5ì‹™ ™ ÌÍÌg¡ ­µé%ð1Ïä9}¼°ÐûÉÇþúÏ&@$&¸¨ÿ¹÷Œ¡l¬”ð=Ó1RIñ�ò}9æØ#ÎÏ‚«zû??1z&®ôı_aÚùc|PŒI[íÝ:uÐ; ¯þäÇl¿Ñ->k4ŽýæGõ£ñYÑm|Zô�wà }û“ÑHnÑR=-B¾ë™õü ~åm¼�§‰.Ù�± .ÀÃõ¦Mz^,—»ë0�%£ñ°Ê8®‰Eý«G¬Ä**|ÿsg|oÔò±ŠÀ¹zOýÿ¿Ö¬0s–¾zâÚé.¬�ãWN�¶^± ‹„yHk<J­’Ýß{nÇÂE¤Ýh¼
  20412. TG·~æ’ço]¸ðV²á¹‡††zn÷Ð�zdØ,/À)j�l.ùÝ w<w ¬¶?5*F qH|ö<f7´[ÿ6Tõ‰dªê“ü„õ©¢×?ìC8­êSì'€øN
  20413. #½0”fñ2^~7¥¯:
  20414. œm�ŸíM I�ˆ`Mö:ÓŠH¦À­ÏF²Ø9ñBä§Þ:ïáŸýágŸ÷ÖSk·ozíØk›¶ó#åSæoŸÌ¨oc3¤€„›¿A¢™'Ó¹m×¾¶iÓk×nËÁZ�-ÒyúZP ËÇ= Uc™'…ŠÊê¯?&È�èK¡—Eu£lÎ;éª÷><�v3t{8-Ù|Ã'
  20415. ø«eêøa~ÖìÅH94²Èx¼¢×AÅ-³@üy bT4@0ìb#]DŒDÓÑ“½lj€DSio:AgÐàöÄS½ìP z:„;¦¶-á|yH"r ·¤{ÒB{\ˆ´5RLi‡6öAƒáAÖæã–tM¾]èè�ÛßtÓá›øaøRò±KºûàËC¤­!Ø1ô´CÞígCÞ샂ð +ù¸³1EG·!ÒÚ€ÝXzû––®î¾éÙ›nz–µvÜ@±x™�ôíô›Ê-#i^ Ïxñ*�$)®ÎÀWü’ã¤=ÖO\fùäó€[WŒ´“öþX~V¬?«ÿîþÐ `Lei¬::v4Öß$?‹=Rþó˜•a#ÿc¤÷]8YåÝFJâ™b&'{%LCìEÀÏ¢­‰Í ·Cf�]Ç^$Šù/ÍùïÒfߪÞM;ÀÚ;«óÉœ… ¥°Ê�„6ù°CX�ÕV¸¥À§ð#êÆX~ FðƒÚ<ç :þvC¿¯cºµyBpLvŠ£¬�Ó1ðÐF”v#ß9†
  20416. /êö8VFë©01Óà­_Kôí?Êæx�>£}úÔ#€G7ÔÑ‚\WŒp!.@ü¸îü»±bùwÉ¡+{Üoª�Õ­#»Ô�PÃQÒ®nÄ«66
  20417. cZ�­�çD‰¡¥â’Â(. °Ÿº�uï;n‹M}ÑÁ‹Åý?»œ‚ªžävÊtžÉxíêF»�ì²{É+È–�²ù`¢
  20418. ×=Ÿ×" rPÏ€l˜DîV̶ß�¤¿±™•»?ã�íZ@ë¢Hÿä°…]�º[˜¥3Àö5€Ì%O ¨¼ê)Þ\^„�Ñå Z;ú˜>�F÷ºtf›-IºzÓ® €ç�Œyúu�1Üu™o<å:Éoa:uqß�‚Õwòykk â‹œ‹}0?jv²«X+ÀèæÝ}V»›­ïäG$sþÚŸº
  20419. ?2ò6ùª¯†ý´YÊI5c‘$óCfýb!¯X¤*|FÏÔÖ^º$Üpº7ïpäí55§ÅÝ߶6[¿mµàjg�¹¨°®¢l>�*öñ KO&
  20420. ±‰8÷Ü�¢:Ç°…o¿êÖkõ¢‡Kåm~™o¾Sä-*4¥E¼}P/ûÚÍ%  k:¡e×"å1AéJˆ–èÂâCAXš´¹‹Š8= �LƒÅ¢>°Ü±a¦åÿ—v{ä|K.3 ÆÛ×:\B¬xǤüwðºå˜bÉeb€Ï<n­/ñN��ç…jN¶j�OTQMâÿòû‘ßÕ§ îå±gð�[
  20421. ×¼1®ÏJò[H*èd÷ÿéØJê(�R¡Y}äþ¹ÈÒ˜¤c¹hC;øay«hŒ�&ŒC q;7/SG—nÉÒõy'^óûÜ9w×”[¶yËÒF`4;ëÆupX_#��6Qy'�xCØêq/öQâ€P&ÑNè§t�ºî 4pÞèÁéÔ�qD÷2/عÀÌi=õµ­ÑXû܆ D£A�<Ûú½-�®>>Ö1Û¿v‰HÅ?äf¹›58Ôó †þ%Í6›$ɲÜ'p¢L^H¯âXÎbpI’VqnÖæ¿�ÞéAé8¥åK”g'i‚!Uz†áSEšªI×ßûõÞ5Ù÷ýN=ñ»ûhpÍÞVÜ?¡›(ìEÅ ÿàš½¿¾V¥³rûÍ?Þ´éÇ7ž®ýõÞüËV£Ú‹‰É¿âµ.´ãOø¹Ü;°÷•¤ Ñp¤� 4ž�NéRZm.–OÔø> Mu¾�L'¬Éj5©ªâÓ`;´Mt‹AQܶM„›ïôyëVí™ë<`‘’ $m)Þyš¤Ú³ÑX„™ÛDaî:ÌáÝ�ªšq»1�JöFq³15¤ä-Þl¸è\ƒ…3‰~X¡æ-2pFÿDðe‰éÖ/ñf!¯è2®½iç:à“=Ãhýà{ü%Ü{t…^€�¶ *ÄPˆˆ…ðBͽ]îÎYÓD3ÀØjd úÓÖÔ*æw|âê¼GLϽ}ùË‘k7¸�ÇÏ=0×ä6„o¢z*­ž¶âzo‚ð1~Jçw0ý0SÏÔe“Pw%¤”�#@BJB À  %Ùø+„’ ü'¸½œÀ;¤%!&©§ )ðHÈq î7fÉqöH.§Žæ²ìÐÉç�!ØEÚÇŽf³ì‘,ü9Õšƒ$9” æH{~iž€Û ŸZ³ð)O|‚�!"‡üD.K‰ÒQ a2Õ
  20422. %©£š2WŒ¥É‚\ëŽ{é*™õB{7â,˜9.ø'ew U^¨ƒW¯�&Þ$»r9¼µçrcGõBôçwl¬¦òÿä’lö<üÑú¾™Ê·îSQÂã‚…ˆ�hì! i¿Ñ¨vãîÎJ :³Y?üñ#ù•¸_Óm4²ûq[ð‡ýýËûû }×,¼EóõA{VåПºˆ‰œ®ÎP|žDöåg©?9M©ÅÇId?{¤)®ûÊ/ÂðÐ /\[ ˆ«JùÒ�ƒ¹�ë[àœf4G>ËÁÌÁQ€K ó^  Œm×â¹ †¦›O—Çù -7wê]ËÌê„ô<ÝU3jÆ�,ÄÉäˆ:“¿Y“µqÅ~ 0³™/¥m‘¬Åµ@CŠ—CÜF€q<·é’y¤xËhúŒõÄ\ôŠ¦0=—RgYìd‘(õ¼(_ð2’¸ŒØÉÊa³‡_Ä{p·M …T*¡‹0žU­”T¶˜Ù!³if$ÔŸÔ(Wâ¤q¥RC:P a3=b²Ñ rK1'-»{ Íö•HèʽHý1Êá'`Ùkϯex¢$’¼.¹hŽ{܆`¤Fé¤ z›EÃ0®øc5xfMÑĆä�¾}ç�ß¾Sýï•S¦¬œÂÂKÅ]Nëf'ÛpPιS§`BmmHÒv9Ä4ሄ^ìm �D $¡˜Š�,€'Ü„ „ pìWÉ­îgØdV/L¶;–ª×MZL­ñõó“ê­µ¢H>{€,ßë�·ºÂΘ±ªã×÷Ÿ쬷ΘQSo ÛlÜûùsÉ¿hýùÿ?A¿ˆ2qªÓÐ`ÀÝ5 ƒ€œZ€�&*ê“X1L5:Ù6¢ë´öÏ‚+ÙÝßêO]ue·j�õƒÅ¨%?ïÛ¼&ÓØÑaW?{ï¢Ë­Ë2[þ}ÉÒW?ÎÞJÄbòÒΙ›¥kÏ-\�»Þb7‰sIì¬kf&ΛÜfê¹x~¬¿·nì™O-9÷VÚçÎ ”~cˆW"È—y)b\)„2MrW±Ëfˆ;MíóUë7¥ƒ'[¯ÍÀ�ô¹’-c/ö´.¾Ø¾”›æ¨uÙMèþlŸ&øš.Óõ9ÔÛ) GêÑÚ!Ã!W* ¸60CŠÑ„#”Üq£ÅçŠÔørqŸOÝÈKÁZOÎWqù,Æ8Ì�/Xpã�ðÏíTšÉÈ‘±g<>¤)˜‰[J8£o`
  20423. ;úÔS\ÓSЧ¾Æö“Àá“%š†h~ðÌpÌ|J˾F~Kì=E0Nî¸QƒXßÇ©ÞÇ*çþÑç8;D7öQñÑ1ªµQCÃ% *E‚yëy}ƒ¡ �UG?>üI`æ>Æê÷'Ê6<ž+ƒí�ÓÄÿ3IVògÕÏ®�yOŽû•ªQ$WBv®ÛH vî…¢è[ýÏ� 2ÿ+ý£ �Ê'ÿø6N¸ß†<úÿúžÛÇîÉ•¶¦— ‡2”ÿSñ娚9ÿ³X†1 \•â”£ûý­Ìdf>ÃBŽ~¶²ÊÕÍ-ˆ”t>¦W�]Ùìp©PrœîZ[±²'žÊåÈ+¤�ÆŒâµl†9]ï8qã‚ì‚C§é!Œ¶' ë@AA¯OuÿШäª
  20424. !?M\…JMÍ­ÍfÇž)«ß•Ë=õÔÉw?A•N>Ï–ƒžË¼}újQ<Ç�pÇ ^Îñò(»€}¿±½½1ï„+¿“2Çàq F²÷4R¾„´iHÄ�—îITër8ÒÐß^§™Úù!gm­óä>¸Îÿ�´Î'á÷ÆÞÚ¸hÑÆEü`­sÌŠo¹ãÎÚl¾ñ…Û!õ(9~í¢ ‹oÐàþ%#ð)þ~ƃúj$Þ@€Õ”ˆLp½GåOa{é®Íß¿fÎìé”)°zèªØ”Y×<þõ¯ïØñõüýÛ~°ùšÏ^õŸcàÒËš·sóÐÞë潺ã·Þú�²ýÂÝ´N•RUâЛÕRÔT”Y%8ÛÀ­¤òKÌs3Ãq¿d]^©QTb' œÄzx¯)îH´“�FÒ©P„mUÎZ¼jQ&œX¹ñÆ�åoŸß<0¸jÉYG¼±ŽÔzê]Š‡þÙ$8cÖÚ&ÖhäyŸÝ¼õšÍwΞ{Ëê9^˜¼æÁsfß¹åšm[våÕÀ‚“ÃÓ£!É(ZíAs�ÈÛ§ÇÎyÁBŠ¼Àü•Œú8RiÔ£B­g6ˆ{ËUm¦’tyW!bšpÇ®d nÅ/yÌ‚áʼ@vÅÓ/©»�Ô%Çcý¹—öªŸxñEn’:üå4YÃýõ²¼,yZ-ækr¶—úcH&öÇ^È©ÏCº'È®'^T®Ç÷“5ºœîóÐÇê˜r)(Š(IèÒJ™U׌&#€ÝŒ! +YM.ÿJï«EX^|‚ÂÂÞL–«w@´�Ú¾ìò¡ZsgßYÓæ´ºˆ…ü\ª�ÑîµxêÔŸ ²Á¿xÓ„µyºý—LïõCyo™…’<ñQÊO$)÷W�6¥m%݆®r݆Õdõ”™‡Õ½Õð’�{¡üO‰bþ�pÿ»AE܀ʌÞg ÐÎÎý²ˆ¾¤§iòï‰�œ~ºA¤¼¢™òßO"mo*î!ƒÓ[TÀœŠ�òm¬dHÑT1Ó$…
  20425. ÉPÔ�4^ÌûsfcA3·ß,ˆêXA­òPŽêbâksî�Yà†‹ šyHˆhýPäÍËâ+b‚W�=}¥Óû;¿¾‚µ¨"Z&x<SySVYíÖ&=ªþ4Ÿ¼&‘è1Jä5u~�è,Ó¿¤zïeù–g^QB\/¡PÊ„%�+p‚re|Pn¥ ¤T’†cZ>?¢çï–eòžV"_[‘çQ©/…5Y�ãá|Š±àqI£ö/\§Ó9ö–Óçããªdi°ÀEBh$ª�åvÒõ ±€…Ó wOL¤ …êÐúfp�a ¦,?HógHùf2¬ˆµRbî…²L
  20426. v >ÞUÀSo™–°^1/,šˆÄ“¢vc«°Yò GmôÀŨ�Ô~¸Am�êzª Ë?Ç/¦’ÿ4ÔÎ0‰�‡yj̸pák²î�¶2«öH
  20427. «ÆeE€RßbéÅÏ/"M 7ò5u²lÂ[ŸdrC‘&YÍ�Ü&I�
  20428. `!>pû˜;¦õåJ-�b�àÂ--.à´VäMÚÅ4>©¼Fj¿–/î5ÀºÎσ¶¯£²ƒ¢Þt5}Â>Cþ*›<'ß÷˜dµæ?,cÂø¾üïd�Gfëåü¼2Ò�0w�ã6óó˜òL¬h"ÜfõKä¢×òÿζp;ÕÇÕǿ϶PÕd¨cÿ©1¾EO‹šÑi¾%ÿö÷ÉŘ(DCäâïW¬·‰ªõVé2š„I)ˆ�TöiÃM›êµøF�TÛz¡0ëÁªµù›U¯õ Sµþ7V¯ÿ mBW6;›nYZU¢zSÏTg>(“h……îF"âÞ½Të½·‹¤ñR]çßûLÛ¶™|¦ûLx‡[Õs,'NU|®€¯¹Eà<ñ4)«R–‹Š pß*Š¸vU#¤gÄÃ*ñg˜ò·jÉ™*=�~܃¨ìA‰SÜýÄ“ÎÍîA J‚Hwä3@Nur®bw™°�ȀʌxÀ}[ƒ`ð7º½’‹ø¤Z§ËÊ›tPlh Õ³¦L.)NU‚}¿¥¡kqÜ'ØÝvÅéõˆFQr×·úŒ{ˤóS]óZëLùÿ(×@ã*úSfÂ^‚–+uöPe_k#Žñ•.É8éÎÉ‚%��Õ ¯,�…ª@•›£TK£¤Ñ…º§Ÿ
  20429. t`‘ß‘ˆXÔAD;¦‚b†¤�|pßAºâ7ð}qÒ¿é2
  20430. @Yû`Ý~¥îÁµ¶ŠˆiÔ¬K½û0jŸ÷ÒYÕ( žøÛR„úÃÓ~^ˆ¨Ò§8ƒ>…è=ãF"šËœA[å‹ÓDqûvQœCîŠXõ|Zõ‹sO÷…þ<NǦûcêPI|žèÛÖ‰¢ú2 Ö�ë Äů�Ð1…úQ|îëŒFH\[ îÏT�k˜Þ½$âÕÔ3’½ñXÓÙ—ÿ5ÿ�Ë®A…ŒqÅ_»írvÁô7óßÈ@ø�vð2Ë€Ïýi%«Êm‘ØŠ²f»—�P¶ú^{þovvyÚfVÔw4eåw³ ""Zd¿[ËÏT¤CÊ­"Ù›!CÌÆ›ÿåØ#^îÏê
  20431. ÔïZ¹’�fRÌ4¿¯Ãx»�p¢VërSK\·ÙýBÃß]Q„
  20432. ÕóóB~#”V*ØpÈx ¾ˆ^¼­(ÜÒëo/`D«ïסÍ.Ðô± õEæŠOWTvõÈ·6 íçÝùúM^~EyÖló¬Í /öÑ«çÀÇŠ¹lŽQ˜6M«©ŸŠq”":}H»eaãÞÀ-EYˆ"­þz"ôÈ�VKF5€’‘Ê8ª/7
  20433. tÑê�Dè€n#D*'—ÀÂÜ^I×û³˜³øµüZ}pITmdL%÷7½@¥CÞ:Fþ¢By%òž�Æêõå’ã× ¯KS<K»ReëÅÄ«ÝsoºkøÉ|È�r‡à^Ósºuí›~·ú–Ûïw“N·_µVêP Å6;‹YÁ\Ì\ÆlÐm¦ñÏëI£ì"�†ˆÃRð
  20434. 2�·Îts¨0÷ã^~’áõµ›î
  20435. ÑÝ;ÄgELc„7¹Áãùž"û�–È÷<^‡âí¶Ù$Þg$²yª¾ˆ©s¨ÙL×´©Éä$Ö �D�> \ä/Íf.ÁÙÕä³F;ÌæÿkáPñ•ìb‡d³z7Ô�eͶ-6‹b²y¶ØÌbÀaWjnh7YôLáFû!½4ƒÀwßâssF�Cºn�h–Ì_0óû…’> á±M½Z²« °ò‡€ïnC휌 ¬ÄÃ*#5/OöUÑN\(3oÄ@…[7`‹Mg8xÏßg¬e;f\yñ½—|fÖ¤©Þ‘¨Û]ëi5®¨q5q&Ö>¹'ºôâóï¼áå°ÑßÙ353éükÏYê­‘œß=WŸ7çâ+΋yxþIÎe<¬¾“ûÂP�Ãh±X aëêv׸‚Ó"ÆùŠcJcú›oHÌO†Cu]³L5‘®«�†ÔÒÅk““¦ðÑ–†ó¦õ„§]xóŠ¸æŠ ˜~ÿ#ª;!‘ÞÛ)B58¨/P¬í õõHšÑF#0‰°B(ôÊpì}ÑFstÒÜM|�¹ÆlçˆÉ)]tϼ&ƒÝ–™¿,ã™—nt,¶h[ÐäY4ݬ$žwQ×’µ,Ë ž@‹Ñà�Ækåš`D”ƒg]rÿ£™·|êüY}ÍVq’wRC*ÔŽ9[o»ÿ©ç§×Î�ÜdðX 6Žš&Í=ÿâÍ}—íß°À/*Í�\�Ë”)³ƒÉ5gOò˜l�Ó¦¯¬Ø}ÙÙ1:>OýŠYÇ�òs(•p6Ÿ‚[‚�B/tçˆ�*Ì -n:±½ <Цð�øè)Èú ¬á+�Þ°~q_}ýäÅëoxt>L®¯ïƒV– FßÈßG¼@dÎ9×Æ[<ñs/¼í®Û.<7î±ðÖsó§B²Éždï�B'·wX‚üœŽ³Î¿äü³Zéµ£üáW²ÁÕ—Ù>2²½?í2ȳ¯±÷8›ç¬žÕÓ={õìfg�csC³ÜåœÕmãå –ÛÏrâ¾õe ¾#Œ›‰E>ˆòü45µqo:áJ£Öì¼X«°^ioº“P,x‹µfµ:/y ñ¼¯n9§�VóÑ¥S§7=éºòîè’u-í\¸%•KåϦUv¶Î¼,»â³€„íÅêZ=Öv›ûâk¯¿¤NÑ*+_§.ýÚŠŸõÖž»iýšÚƒ=w @¥æl¢m˜röô>Û�O­ÇÊo,VÔ²’×ëÉ�z &:'ÿ4ðÎ5¨Ó…!êÕ9èpI 0@I[ÍPU""©sÙîInv‡R>ñA¸Ž˜É9tæ$ç¨3/«š³|k£8y´iî¬�šE û“ßøÝc8óÂE×!Qè\Û‚} %Aš�f4ì s*®A8�¦‚A³Ø΀Ü>D®�=5uw¶Öõúj³ênG �z?2”Qª/I=î˜ÛfýHýè÷4Ånºå“]™æ¾€ˆYmðªG"³É2äPEÝH™Íf¹vZnž<š—PiA_Òq/³ŽPÉDÕ¿ð ã¨$$Ž~%NyhrÜOdM\‘-þŒmŸ(ˆä@\³º�#½„ÔêƼ“ÒNïçJŸOÔåã>a+ÿ µuJ¨*(%�¢FP„JÄW””¥Š¦½ø–ßð‘,$)�ç÷)åÿ˜ú³’ÿê}×ÿ˜
  20436. B\­–àÏ_»ïúÇþ¾w¥Vé] 0†ÑT¥OCÊQ}è¾ë5±ÐÂâ{Ho*ä™;;õè‘žÉrǨâêõMÔcå5­ÜãÑ4S
  20437. : ´ýMŒ‹îæ›7�(kY:멪¸•zÒ`ˆgp ›J†stˉý±v'²¡¦eðÒG^~äÒÁ–içD›»1šš‘Š6ºdA Ø@'N ðŠæ±³Ö­<?ÓÒ’9庳b¤ý„É©´EÃ�:�Ýh²{ëáh«â0ž vÛ§˜Q~�{©"šH”ðƒßGQÔkl”<ü:Ê›^g£/ïó ¹_i²«´‰ð ó¿ÐÅPœ’›�¾®>N.Öô?Îf²Â…Ü1˜ób•ŽzJý¡±D ì¥V
  20438. o@7R@6Š<Àþ%IF©Ø0êmj= �[Ž}N‰âÒüÛŠ¤57¹ÿpò©yŒÄv4@<mЭá¿Á9TÅòp?�ÚR7ú�ú¥Š0Ò›š´ÚQÏG¸[j„¬ÐÈßÙÍziß÷·b“´ú�~ƒð/)wC?â±ï רa¥-/ŠC®n“™û.Ä•ÛH j63¨€’иŠpø‘“KrhëÏÏÂîX–êIçÆŽjß
  20439. ¿‚o­è1ÁÅ9
  20440. ŸfÔ\Ž~Ú:-¦ÔÑ“K �4©±7BYÍö‰Ì†Žy%›DC~e“èmÀÞ@Ñ]Ñúÿ%Àrþ©ÖÙs4T® ™Åâ®ÐóÖG-âUg�õ>ÏíûH‚OpVÖBì�Â]ô{9&ÿ^6¹|Ðm’õå _PLLI7Ç’¦iÊ®õé "'T }Æãï? 4»ó¹›…|‡¦[FÇ­útu/Ù_y;Z”¼?Û£H†K®0W�z¤èc#¤ÙÙÐ)€Ž~.rÁŠÄ¥+ÊB‰°Š±&J°“ƒG 0ùË[ýÐäÙü‘.Ρìr·ŸO³kŽÝ;VC•‰ oX¨ úÍöKÛ�Sß³ër¶t‚åí²í„:z‚X\±úxm‹ÛJhÿ™x¸ðÐN÷ÇhÛ5¯ ¥Kè`…;ydp.Ec›4²XžD<-´llµÛip.»^ØâpÕ×:� Ùu�/î»öü™.«ÅY[ïrl�¯_æ4¸šã½ÉkzÎ$~Dq…]7/T_<è�µˆ¼¥Þã4K§$ðÆ–˜ÿ ™»ð&w“«öä· †ž©S¡¸7ÿÿµ|K‹^ü�Šø›Žâ¯7íMsMGýáùçÿ°èhÇÃw”…¹Ã㢴0]?²´˜fjaÍ5aŽi�–Цè6C¼2ôno• ¤“Õf ì=ñ–)õd^Ëÿûövï qNcãÔŽ´ûþ‹l=uÙáì]?;¡fâù-EÕ~äìöáÏnÏvøÕ}5�¸Ï×%»šë¾÷ýú–ìèOÕ»³dë�¿=„Z%v¹Žè ӳРn¯K— u ÐÌ“*J¦„ê�#1äh„u1HrìÐ o»ý}ÿ”õõSZâu=¶‹îw§;¦nÏ—UØ ï‚Äãä•ü` FÝçïȶŸ½En?»¥þûß«k&»¢ÍÙl9 Yõúí�d«†gAâÃ8NSGáê³ÊDŸ09M‘AK{Þ€K3ÝŠ„­ª�[_]’%W4zÖÛˆu9é\~åúåën3ÔÉê~ñÉzir–„ñé Ååô¨“X3kâ`PsÄêøÜÊüâ’nÇåïÚ=mùºÁ]‹ÔƒJËks„ÍóTÓ9d™ÒõeYN`}ž¯/û]U#Æób˜;R̨“ÐÀt,¢ÚlŸh*ö¢×#JB+
  20441. (´¡iGx\}~IÖ³F·Ýv@T÷Ëu†ÛÖ­¸êJ¨Ú
  20442. ±­÷ÌÿœÃ
  20443. �@-Lœ™¨áwäzÃY§îg—”úÓâw‰`wx-ù¿Øö´(dÙ¢]ƒ×ÉÛFÏ3_÷øX�cY’mQÔƒç�ßWæb¤-©ÐF ¡�êKõ5Õd-0bƒâ¨ç�ƒ—֨“T+æ‘_ïZ„xÜcËÿÐj*`ûûåˆ}�|xâ~¸LÇF�*ÚS*oêŸMتêA­Íó–²ýîTž1pÇ7µ1?‹R t>éó»¶R'"ú�‹ÀäÆÁEÂyÓ)oƒP�7ž”æ‚Å%«ËÀ$rÃvõ¬ QŸ¿û½eE”ÇãØç”+�½»nùzlÝåVlÝFrktÉÖ'µ¦'?R®„'ZƒCEÕI§Ky» gaÎö0þ‹ü¡^áê} pE;…õKq{ÒáT/ù?ïi"%íÆÞ1ÎÞ’ÿbñ-ÞÔ¾qÆ›Ì˵ƒÛ+ ¢Š8Æ]ÀÊrI¸Üú”Ú£V•{¬dȪÍœ¹\è•AÍôÓQÐvOÄSÕõ]0.ÛêúN¨ìX9s¹Õv¡b?OE~ÚFPU}ož[YîKårÀéÖðñA¹ÃÌ“U%‡�§7D€w ýêöˆqÔ bá/í‘hÈ íáAÙ±‘hPbQØ“JB8ÕI ºä?áI%=ÅX‘tÜO¥;¹(P‘hºLìd£Ñ S •'hÿݱŸ>|þùÿT»‘¬ÜV?Ù,O•Ýç"\�`ª7‰ÕãíÁ.‹2ÐçÝ>Îæ¹Dá²Í �fÎÖm•g;œ�-íö„ÌCŒ'œ¥Öéu¹,»¡¥Î z—A`-ÇÙ¼¼Á$Öx vc“Ãk2·¦[x–p\cÚbüí“l΀ÝihµsµœÙivðaÛÃêM,gĨlñŠÁMžà–zÓܳ›7JvÞÔÙÀË‘V‡RWÏ‹N³•ÝäoÎ4‰(Ú-„µXB^ÒCl&Vnô±nŸ¿¾Án D4[k6ž³†›ìN�×&µº}f§“3Y¼QwÐ@$“U$(Ǫo¶:-üZG¼…#&‹Å†/…} –?ÄßN}Æ¥¼‚7íA!M´àühöøW>£æï?iX²pÊýùr›¼A–Ù¡àbþöó?uϱ›Î¹³-hñäØíëå6;»êSÿBõ#/‚µé@Ñ¿J Æéþ
  20444. !%Q­)”ÀDq:{JI^Þ‘Ë¡õPY7UGçÊ(ÂÀ¼Ÿö¡h³?Hmÿ¬ÈÑŠævREˆíHŽôçÔ=ÜN`P)QœŸ¥Žæ€G9®ÓFM‡ÖSáMG§õ@2¤E‰$Q
  20445. µ$Çs±~ä’TkNµ"×9®Õ†8ûcêF¤ñ^ê"?+GÙ 
  20446. ^÷*¦¼gUlFVx�ªÚU™poC¨°ž.XCƵ�Š×µÍ‰×qï‚Kê[¯k[¯ãöK—(l�À;ö ºÓ¡ínè�%^ñ�RÔj­,$)§ ø·Êì1‹‚n.¿�ßG÷:CÐïfŽÓ(ßñ,˜íÐ;š„Ä´©ôR—¿Fëž_~ðÎã^øø;¼ó¥Õ«¿D¾ô;6|/jGGSSG„›G’ӎļD¬ñzbRï¤/X?½ñûŠÃíñUÚÇp14u˜$`¾ß[ßœH47õ7Iò~¥‰~Iÿrêß™sùù#èŸ6ŒÛ+‘h„ºe€Wò6@wK“̸h6, ‡1Cµ"à�‡·æ©Ú=­mÎèñ�e°AòÓóŒâ– =¾àôî�@“z—ÜÐÐá² ¦sÒóls³]ô;kklµêÓr¬^"sƒ¡é�’Ü>Õ&Õ„¬-[×ß{ÅJiÒ´9[‚ݵ³È©¹-ç]±dÞ¢µ²cÒ µAnµÛ¹ƒägç}ê’‡¼»6hTï–ëüÉ–´?3s�ÚÝ^k­úŒLêcY ˆ1ëZ²´n[÷¥ƒbÝ´¾E߆ŒçÕ¤Íw¬ºàk3Ôf™•åˆ>† þÿfMäÕD‚è…Õ ¸aåñDðé �~}&ö¬Á@¼£5�u gn¨›OÈ¢<¹­'` &bÓ¬¼±-6à÷®;ƒÁX÷"‘d*²a¡wÒüÞY”¦´vÖÔt·L³ð¦Xë¬Ö¸kñU�ß©ø­ü·aîèÔ=HR_Ã@¦£Ä+j“2—öT*‰Â£è%ìÓ/͸oƤ ¿±Óyá‡ê £—»î›1ƒÔ9/7›  þ~Æ7áýŒ´_“ÛùoÃÓêÖ+‚þ$DüÒ¯sÞIH�:çr£ ƒð ¤yiF:Ýå¸ðïäv�÷ËýÀ(Œ¿d®O":¦ omØÿÅìdM”8åÒ ;¤žZ9uêÊ©üHCg\›K/*‰ŽýÔ™�g*¾-óIèÑö—±¢ˆ_ÁE¢œ‹RqîR'û[¥fõ?GÕU�½Ao‘vb A$ÿeõ]¹Õ/‡Ô¿ª£o©?|ƒÔ�ÞQâm–4™G¢Œƒ7ñG™83�Ú3+ ¼74‡z*)¡$Ý‹JÀØpDµî“Núj5pÐq¾·“e�Df/�ÒÎ>ÎÛü‰è´à”%é–Ãg‡Wµø¸{…Uóë:g,ênŠ¯¸l²¿µU‘\ŸÏt™'Ö¬ñ%ÒüÑE‚«}àòÍ�íu¢úC›èꘒÍܻߺp±}UË+^b'‹�’¯«o(5gã¼VÃBÕIœ¼äOEüm>·ÑÀ½©þ€5yšzgö†}úÁ¥ÜüA”©P-øP/ú€�Þ«�ì„ò Õ6Ì)¡x5/t;1šp“1”L º9õAܳ|÷êÝÑ)ýµáåîX]m��ûókFEéH/ñ4}:¸,oLMªoò®»6]YãMó5¢Ëê0u[›ßyÒ«ˆfVêh¾˜?¸äÞE-A§_iï«�ßÝj²ñ Ô.
  20447. 6|Þå5’`#ÏÕZ-÷svÁfq˜ÓŸ�›íês·Íš>¢ãÚwêÿ î7C—å{ A“ú…ŠÒÖ]B¾ëÕîz,i÷H'dù„äávÚ?’`E‡•�
  20448. üx,‡öm±¸z‡`ÍF[ïê2aõv‰hp™%(ÔÌ’öü¾Ê‚ÉýÙ5Ô¦;GÚÑŽh”í¥²³¹\Þy";|"«Ù�Ê–©�rx‚zËsèP‰HCT×v¨P$…éõly}‡iyhvMŽCù…r)Ý#Ãx®›¿-Ü.(ót%fu»ôÊ€(Û…eÁ•UU–oâ²
  20449. ¥p´ÔqeÑË¡å•—¥sòy¸iº X–æk¥`É>£X¯@2Pø¯. ¨2ÍŒ>«n„|‘Ê,/4—£Ôþ}Âò  ®ð?Aí¸&ÍJŸ†Åær§+�­ðÃÉ��ñCV“]{ŽèìZÍ0�- úùA=–ä
  20450. Fø®$ë+”Óöñ%U¸Z�y¢­ÂÞ—Ž°Ù²RÕ ·Bƒº)¿÷¥ŠâwT8úÁ(áaÙûRÁΣ*-Àª—ÆÙs€r5v êÿ!^tZ:/ÇK,'±ÂêF  9€»=ãÚæGˆ<�§¸CíÑu“"$º-¾î²F÷óS2ç(óÉF
  20451. 0Q©Ü+X�š�ðwÈ,»]=b÷h[qžB‹QI’ þ§ú;)"ÁÅŒšÓ9ÜÒ2ãšô6Ãr?çÓ}lŠV Ç=b¸[˜µ£j¯¢4€Az”ó™Œ÷KÚkQ?TÿÂ[%“É$°K¢Qõ-¯Ñl_@l/ &;ÿ˜Éì°¨ËDrª?P_d£E1ý~ýz—â^Iº~b°÷§ÔrÜè¼e¡uŠ¼f¹­P•/ÍÕº#Ü Eÿ+šS\ìG‡-ØR4¨�« ‘S®óÖS®óVä¿‘; �ÎÈ*`ßG¸é*5'Çäûd™Lº
  20452. ˜¯ÿ~¤ÚÆê à…5¯”FšÒÆhb` 
  20453. ½ê�œú³Â4€ý[b$~¿Gç£NÏAX$òÛ÷ß~ô‚ }[»‘Wß}åê«_Á‹z×6múÒ&~Oñ%Þæj/árÍ&|_Sˆ�ÆÒyã<ç�-â*LÏ›ø«Û,©·JQ›z»Í¤œð«·£ÙÂÉçÑ|’V|�GVW~öË<mbl»¶©œ�ÇËÆò�B¹&Íö©Ì­jš šy¹ì\r=´æñ 'ç®9á¶Häf)šÿ¨¬ÜÇÔ…rÓ w�É!;;vs©ÔB™ 7Ó€ž¿'òkëå*«úirµ¨ˆ÷Šbþ/¨Kû+Ô”WÄÑR™ìO �ÌÿÅh$!`‹1õ[¥r ¾§¦ûŽ(›a\T™R²šòü¸"Pž?]Yã;? ÕÂÑ…ëyKRXâWòOCzó‹£êÔÜ©ÏH�jPnýâ[°¨å¿Š‚;é͇Gó“ËqÎÛZ.ÀA¥ý.*�@/¡)WQHQÕâ«ÙU…L†2^…²$,T=QÞêå�(J~ÉBI¢UP‡J�° ê=êWC@Ûï°‰8&¢~Dõ«ßW¯æäìÓk‰[½š<ÅÕ�}ô.÷"S<#Aë«>Íz ·ý ê¨
  20454. àH ¯œ†ó³¨EÉ ¤º²Yîn‘¢çH4ûr7P?99­Îæß¡|O-µ·5³Š ²%ã4µ dzêO/4ùL_Pså’TÔ>¿LQ›ÄD(ú ˜ÚôùJ8òÿFµÏ+)jCb
  20455. ›MuØ2Xc8$ñt°}œ&<?¸ö9lWÿ¦~½Ò¿Í‘åÛn“å90AÁ=&W=sÇÔ¿À—œ_V‚ýéÓ}¢?køU(�m†øutEÔê*¸
  20456. ÚK%ò õtñÜÕZñp¶J³Ã ŽB›W�·¾P üA lµž(ZÍL�·zF íýZ²}¤®/‡è¿40”l™V ¬² ‹i%L·ÿ^V`‚jpŸPäßËžÝ×5QV—ØVêk¹ÐÅzX8¹ÄÏ^s³�Å£W4U*u´ }ŽLÊã8æFþ ÿ ç~ê3·¿B›"Ió/.·èO
  20457. =7B¹JAÓèô’§�î©¿KÒßQ-¿|—¦’ÕVw|()8¨éC™»¸ŸªÏ%Ê´¥�To×lásù7*ØÂërevðÙ¢üáì’6m«´“Ç– £â�ÖC™T¾ÉpT'Ç‘pL!èjR C4·š¸}aºöSm‰°ú[��%¨4a.ÅÑì²¹},—LŠìõBý¯ð=×:Ý�'©b¹�ë“ dmã¬û}V›š©è‰Y,êtúö;¼ÜÙ9­ž¼ÂŠ›ßï� ³:\ôI5ˆ–fDAû©¢™uìIœÉôFºH2  @:2 ß!°Ô�ÌŸjõ-ÐýÉ@ ÙµÀGŽûðƒ“ˆ`vKcw¡™I“lar�º%l›¤EsÛ
  20458. ÑêrDe·ƒT¨žibš™¦·@³…„d4�¦›•ÇB’DH†¸ Tœ. ]‚ÝK¶*þËÕ·sè\m«Fá:�:£”4v»ÏX †€<¸;‹Ú»r—£þÕð%—ä²Ä6ðaꇷï½ýû¹Ü¥GÍÂàÏÎØùÇùÇѧ¬ í|°â¥g…уÁ‚�†h§�vìqtJ÷JÇÖKÇîÛêH¸^v‰Ž½œ­³gpñ§.ÝÖ?뜸ËB¸ÿÞã0¸^q÷8¶|fìS[¼t—ÔåØCx£Ò”œ¹¦þîí׬˜f¯Ð¹
  20459. é^ùFB‡
  20460. žPi©ÐWFpRßU
  20461. ©:̓ D‹Œ}ãÉÍÙ�v“Éïþ�ÛŸúÊ}4ÀÙzú/½ö—F<„�«P莣\‘ÈU¬'c?ÐÒ4›sJ ä‚Êçjj>§@€«Qr¼-ÚÜÖ¤þÎU_o6ÇÕËq7õP1êŽË¤+ÎÛ¾rc6ªI
  20462. ë\ ê(*v´2¼�4Uc(Aü Ì£9ú3öŒæ]Çz÷Øü»­;0'¡=äÛÑ*,e5Õ6ª»VÔa,ÌqhÌ*ôë²P@wȬ°G²¸/ÓOÖj÷|ÌFImÇ #Pzë;J¨wÊŽ}ž < ‘ú ŸÀz TŽ�út‡ˆ~£`ÂȱGP%;? ®5(Þ(u¨”# ”ÇÈvÕŠIÈñí#9,?G�ù¡¬b4K]ýQgÔŸ]ÒE[à phʯ§‡ÛG›¡à+` ÜÄĘp ?Å@á>!Ú}"
  20463. ÍÒ½¸Êr=ÔCÀD5ï 62¾¦ZYêèå��?à× ³ÖiðËA�¨‹
  20464. T(øE U•Ju³;"}©ØÕº#–ê‹Lˆc¨äÊéÓ—£VäòéÓWþOû›&ÙCIÔ™úÛÇu8*烞QæçaðQ^*z(¨L­|JÓ�‡½^Žf©p1¿ûõ„0À4~œ�Cˆ³Ux¨Î*ršV²*�N9Ï€„׳¯Pðú„Å«sñÜp¶ˆœ_LŒ‰ŠŠòÍá3ÙZ"}ˆ&ÓrôO¿|lõêÇ~©ÝÈk¿C¾/Wj><ËüSÅxÔÀåMêbS“¯–—�úg(]½J(Z#Ÿ†x©\$OC6¿8-àf:{êƒS�ҳ蚨oý4:œÓËÜ)Ž¥ËWb¼"uÅiu·hŽŽ~½dãÊéì%û¯¯ÕB�±ûóAM
  20465. sÍâÙWH.gvÿ%ùç4ý–ãvø+¸œ§ð=¿
  20466. ðÕSêG‡Ï‹jWHWÀæçu>…–[ÿB{[çuûɶsÕ;la›z›iñÕÝWß­Ô\z½ÆåCðäƒÛÖ|¥ž\f·«Ÿ×�te¿º&ÿ¹ß•+Býk�«è/t�¿
  20467. Ï CM�„ /@SÃ>Tm
  20468. ±G`vú`?þ�ª£ôþÙGÆ(Ù,zb" Õçðe¶¸üAÞ×AÞiàÿ»´š7ÐÓéQ�Á¨R<Æ"i X ¶:¸IÜ‹(a‡V¾öœúã¦Ëç§;4Réù—ó]}—Ïœì^þá«Ï1ÜvîÔµ�þÚù—7œÔÊ=Ùpù|§[Jοœeíµ{)­eÜüÝü#Œƒief0ó™KðJâq²"*öF#¬(©¸GjJF�hŒ¸‡Xè#ш·âµ�£ñÝ�kš¾—5EÔR¤PÍ΋ㆠ^p C©eoÿêíe…€:•ç¯{6ÈÛ¬Íï5ÔÍ�s‘ÅÆ™8‹XÏ K6×ðV[�ç=çÙ}V+�ÿhͧ×ÀßJŒ›lÑâŒZZ›5ÈßW‘‰±”;®þTýé†e«V-Û@ÚH†êIðÙë¬ÎD<Í™[Ç)Ö�ÍÀßÏÖl^bÃXeòÙNN±„¬"K]£@Œƒ×bŠ©šË?.æH÷H
  20469. gzXaÆðÐÙ’Aîˆ}MO¦eýXÂüH§N�r ÐóÚŸW¨;ñhtñ»gttOöyu3=–Âü*פîÌåØ¿ C ÂFGsh9JîͽZ°-”k‚’]L-Õ~hÎii¡.ê49ÍQr5¦ñ½I,VÝ“ÿ…^jf”»_}Ô,“í¬Q6?Ì5åÿNVçÁÏÕ
  20470. ÞžË�ªYÙœN›å%ezËÜqƨï>ÁZè  “NtñŠÓ1š �a Õ%þž=è yÏhÞ™«« H¸Á—ËJ�Zöš?ý h½vrœkÊÁ@åmÍY`®^insðêF\”*ö|Lœz!/?·)(“0 Éâ
  20471. MS4(šÈ—hðØ{²º™’æñ-î'×hŽæ‰ëoê7ûcCÒžÊ?‹6²âñ’²'|ubˆÕ£@´þ�Ì!³býÙ¡¡ü»Ðf{tzø…1UÒA?=Œ@œáá t%˜ä•‰ÀÌå�iuš“[ NòÈiáD ±ˆGÝT@Š:Ïp<ü(õcÓXéÉÆUm�2Úϱ7z›ÚOòíM^öFÏ´YUfwGsüÁ“#‘t:Â/‰ªƒ•¶Îå~±OsÞ]µÇF×ÿÏçÝ‘¯ž(úü(^È‹Á±?Lû�$ÀSʽ… WzT>mì'_§‚údŒ®ÐÔç:¥Ä�5®Lh;¯H7ÜWgzêgÄZÆÆZb3ê{2d5�Jj¦Ä9Þc+ãù‘\vqzç²DbÙÎôb ©Æ¶�g ù"l@צ�pæQB½b�ýÛS Qí>€“+d �p²¾î%}¯L!“�™ƒ‡òçšcdwHo˜¸Ææ×p€x(Tì¾pÄèxî¿ßp#ê�:dvQ qŸdAðQFdÜL³¦K¤mÒPRËí ¤pU?òlÃëÖ ¯ûzg°-ª‰¶…ÔjPÙî©b·ùG×aRõ¿ú&^qÅàä>uÓ8¤•p&ÃӮф ¤`íMGSŸ®¡®óÙܵao°ñã¡ÜWÜ›Z´aâÌÙŸÝ°·V5ŸÊR¿s2NX ÛqGB  ¾O “ÊKÒg éôðÀÀBWþý)Sg\õÙùêžÓ¡läË÷ö]zöÀ<ß²o-_þå- ø±›ÆA£ŸKMqÓ­!´Ã¦Si­gyñüý¿ÄÛ°]Kû;SêÆT'�ã©ókPqÉæeêÆe›7cZT{~*‡7‹bê\H…?ðjÙµl3•�P œïоwïT2²ðjŠY;Ö�)ºl DËueytOTøï�Újö¡üñU¶H­í¨úœXögɬ,õ�W´ÉÏ¢^ŽÚÂu¶¡![]Øv”Fèç”|
  20472. ã®QGá¬h`(¨# ƒR¼'5X©D§ÌQ ÊqMË6gûc'býúu³:'—ôÿ™®H( „?¸yÕµ¥ú¶Ë6£~.òe¨¬[n ¸ªŠÿ*€±U«yZsÃt 9ï‹›¸R!GÙý��·©�ù“MM$ÚxŽz€¬$]êÓ{ÐÃL<ü}ù�ç4ÞÆàJZÕõê~ÒMVŒÕ•hy× >@u�»Êí šå…î�+³¿Æèôõ]áß2FqO8jü–Ñ¥°WCÿ»Qqíˤërw®‹.Êì�ä„«¾Þ¥\õš_´úü§ãôöyš¶\O¿nÔ)IÍKGR§êHÅ�q”¸ÜIÚÑÅ.
  20473. d+u@Ï´õÓ ê¾k–ÙŤ}9¥êT«v6ö*x¤g¶e7?—™Ã¬Ô}õS§éÕ-ð íAUÛü‚í OMlJ ÕpÛíժݧüîÕŸYw–Õéhœi6û\fAöZc,·rjFœTå‚ÐMj8kOë«51‹þT»¼ýqW½_ÙnéØ`•7®%³K«èÜéWÜs–d0š‚á:»Ñ`´¶OX•ÞùÒs$ã4¼?:ÿSI1¢�¢W-¾Pr}ê²£Š §9õ.Ôû& Pš™^f
  20474. ³8(ºW¡I¢ÃÛ`¬¢`@5a}ˆzµêiþV ¾p„²PÔ½+:–£d\jÃ"=üa€j£Šð­ä)W§Ô$qö{ÇÚÖÍœ×p)—Vüõ®|£7hj�¬ŽÍöâ—³õ»¥Éâ$·Lëè˜Ö¡Ê9›\öúŽÚ�n[ ±¤k{lG‹‰Ä.m „m~ÇT—ÀºE‹�Ûù¡Ñb�È­¶m¹`
  20475. »—wònyæP&—:P¯LJØí–YŽúéÀŒÕ_îp™NW¨‰ž›zVÛìS׃]7ÖÕEÚd“%i¸ç™¬|ñ ¾úèÙÌEÔWMÁ“™7râ ÀÞHB¨´Ë6þ`UG¹ZˆæÎ� ø9 N2l2ÝÛÉ…HY˜½(šÅ—ÒÔÙiwœ½Ý“[ýÞ`ªcZ¨–R;Yz=TrÒvH�þ9ëc. ¡Ö²êGäŠÒº6»*pÕüÎ…�'»[â‹:ú/˜ÒªXØ¥œ´CYÑ…Mñ˜ÖtÌÐ-'º]£n,{@üð cø˜Ob¸þæþÂIÑN‡.”xÁN� ¹F9ëÊë›�Nÿ­Kóß[º£ÞXÓr=ÛôéWÎmó �°Ý�°Æ¦ØY+�¾Ê?sýJõ¢Ä×gÌXµuËPý¹¯%È—V^¿Ûéè[­ù‹ ··ô„ÔWˆ ¯;éúWæ ³xv±iÈ/‡×XS3±åȼ”2¬¤÷Ô©Z¾<FŽ¯=0Vó[%•R~ËŒÏx—ÓäyÑsÃÕy?§Î˜(O†q _ ”V-ÎøaQñ*Q1 ‹t$ŒjÔD„pR R~‡zÇ¢ìðp–"ð]Ÿgw�óÕ=¸%GV³§ÔßïŸrtøõ¾�>ÁÛ f×2�Ôå/yòÉÏ?ñí»ä8ð®M@ÓQÔÎ*Ë„ÂýÈö¡¡íCäXù�k¢÷²?MzT�y?±àÕZËÃYu׳)ÿãé]Í•ßô1–-ã—þa�ÿ7jô‚~”ÍÄá
  20476. .dãÄá
  20477. » –Ä'Ó·½¸š§º“VÔøz£tXKþÙ2k̹d?¢§z‚§úz¥´ÙKŒ.º>,¡¸BZ¦¿`q„—'ºk–Hèqy¢û°æ¤5¯¾j>aÇÅÅ\CÙÕ#ÊçH;#pÇø½Ð7lº4¿}” ÖIR¸7Œ„°ÞŠ0§ûœð$âì=«VÁ¿úÑö‘í#ì¸ä_.Ñvª…sð{g><cÆáÃê˹_«£ÅÐO¨ÚÝgxôçñ5&Ç?ÀÝÊÌ ';zº„ÇaÎæaØ:zÓ‘ èQìFꉢ‘ ®^éÂMFÑ�°³ÿ9Ûç&­£A¨•�„·ÕEbŸû†Ù½\±|ã3ÝgE}"+Ê>ƒÁh!­îÚA·b¹/p7¼Ðî™=Üz—Á©¾mi”%—ÍŸš3)^Ošj¼<_ãU�¶NY63dsIr£™´8E—jñ¬ßý®Uð´„*Ï 33Ï|v ¾ãè;ÔÛOÆéB@ñ�ù,—ü,ŸÑ\cwd}6k.žuØkÌF9þ±'Ìä�2Ð6D]e±‘xÜG¾J³K.×½}†ñS«†$ƒ@ t"š;2�É©�ê¹*¤Ž”ŒÛ4§Ü1_ƒäxõ7³ÕQ§bj´Xˆ£§ß9›„§ÚQõ½;®#Ï�{9†Ôe¼I
  20478. š-ìå¥�br B<ÞÖ9òdpzœÜIVªûóÿQ:l„+ëséi Õ#=ÑìT¬ð¬�+R˜Ñ(ªâMÞDC$â
  20479. ¹Êaç̱ êONgÄj1ž9˜¶›ÍÄÜgqXkè„}F«Åèðùd¢¤×ÖÒc¶ŠG“,µæå&—Ó.Øâ˜.^É·wwc�ƒ>ÀE´_]3ûžUˆ±|ãt{JÕfªçª‚u_ù.º\�ÿºþ*êö²W•=ÌÅ}ÔlNçÕ�o+^®ïßVÌ£îé‘ vØP£>~†‚s¢¦T¶jWz~_¶¤o‡gSÐ}-­üDñTd‚ Ý-TÀAaÈêYfµ²˜Ç3,PATcm²Ú Õ¼4gã¸}‚½•màE$BŽ„w¢�Ū8Ü>«¬9�–ä‘ì¸JWâ�©°O¥õ/9ÿPªJCÉXA{,™@c,tEJ¯ËTÈj½¾9ì�•8QÊñ•Óõ&¨ äHŸ þPÁl~K%Æžù1€¾Ñ»¹ ü-èeÈD zxN�›»Xuz�’Ý.9½ä}‰MÂc�&œ:¯ê”Z5¿ãÓ™8·ø% ÕµÕ½øm³˜¼ïomõCBö:ÐäÖá‡l´ï˜8™ÎßÄí¤~óËܦ¢E²¿j•T§ßÁí¤YH˜Yá»vønƒV^IN]]ÂŽåCXkg#Ås cÀSûˆB’$‰Ã�=’$�ªkø}cG¹&ö÷/¨ßzç»ß}çä¿çÊƵ_îÑv6<�7¸½ý´IVGG™�úg*lôŸ\RXS²T‹‹®)ÙšEî¤Ê%Y uôóÁ~Q~>X¤¸ˆÏÐ…±Ö`9ÓW‚“k*‡@_ÕŠpM¸]0¦*ƒ�%ãaÀ“3XíŒ�K¹Mü|ô{†£FÔ”»ƒú‘
  20480. ì·¾d7[Õnò¦Õlÿ’ͬÆD‘üÜÌÏ÷@¤Úmõ˜ÈÏñ8‹Ÿ›°e ¯cżô#�gH›ÐÄdd@~.ŠjÌlÃlÉ›�äeRcxîEÌä�(( Íí™K�ž™Ïm¼êïGëX”A7¾×Sõ·µ@[lÚ×.%ÈëæÕ£nMDsˆ]n€_Qî·• Ú5Ài?zûÔGüTèG3²¦T�@e èi´�×,ˆƒ°r¸�
  20481. O2<°Ðè•éÒl+³À°/,Á–%‰¹­m²à ¼ÓÛšXØn›|–Eš›¶÷]˜Žˆ¢l�í™ôœžÆÏ[m<’|#¹z×+„5ˆ¢ 7&\5Sô-˜{þüAEß×^Ù¸ì¬t“Kä ÂËέßçMñ©^rq]‚îFmÞC%2þ„vJÒð)W-Î}OM"`Õ9l²+ì=…%"«çë£ó­Tò˜'8ÂzH3QÒ�ßûÑ©ùYìP~V¶‘زèNiì¼ÍÜ 7ŽÕðÄÛ›¿ ëÎþ?w1ê×�xÚc`d```dòÍ?ÌÏoó•AžeP„áBYñtý?ðÿÖ;¬"@.H�c èxÚc`d``ùß
  20482. &ÿ]a½Ã�A‹Š�_xÚ}S½JAžÕS<‘`ŒÚÙ‹« ‹€Úù�Âb)6â ˆ�>@DÈÄ"èX\o“ !‡­Žßìι{Çé,_¾Ùoçgg“˜gÚ ˜¹#J†VYp>uC4Ó&*Ù<=$Œìð¾g9ÓW@.0Ÿ¢qêò‡ú- õñüêñÛ;Æ:pt"H�Uåeèܾ5äÕçü Vg(÷[Aãx­9ÏÝ!ÖÞ´÷EMŸ�êß—ï4þN†&Óž×ðwj³tþ™³ÔžeσèLpŒ>†w‘ï†õ>GàÙpfz`Í|´Þâü^ªaÙżø>äŒÇð¶)Ço© o¥²‚MÜg+RŠm¹RqÑí,÷«‹RJ¹à1—ÔÕX‰TªäN7t‹{I–E—\îFÿë8ãU ºÉÌmbÍù:f—N±&’ýj9ÌY�xÚc``ЂÂM /^0úá�K˜Ø˜”˜ê˜Ú˜Ö0=avcÎcîa>ÂÂÁbĒIJˆåk ë.¶"¶/ì
  20483. ìIì§8ä8’8öqšq¶pnã¼Ç¥ÁåÃ5…ë·w÷)ž^-Þ8Þ ||||[ø5ø—ñ?˜ °JPK°Lp›—�…P�Ða)áá "Z"WDmDWˆžc3KÛ öO<H|™“„žD–Ä4‰ $þIjHfHN‘<"yKò�”™T†Ô©oÒqÒ[dŒd¦È<’•‘u‘Í‘�"»Gö™œž\™Üù$ùK
  20484. n
  20485. û�Ëw(9(MSڡ̧¬¤l¡\¥|Hù�
  20486. “Š�JœÊ4•Gª&ª ª{ÔDÔêÔž©¨ïQÿ¡a¢Q ±Fs�æ-5-/­m.í*� �]:otet;t¿èiè¥é-Ò»¡Ï§ï¦_§¿Iÿ‡��A‹Á%C!ÃÃu†/ŒTŒâŒfÝ3V2¶3Î0Þf"a’`²Âä’©Žé<Ófvf5fwÌ¥ÌýÌ'™_±°p²h³8aÉeéeÙayÆJÆ*Çj–Õ=ëÖwl$llÙü°5²}cge×cwÅ^Ã>Ï~•ý/‡‡cŽLŽuNN+œÞ9K8;9—9/p>å"à’à²Îå›k”ë676··-nßÜÍÜËÜ·¹óó0òðóÈòhó8ã)äiáçÙâ¹Ê‹ÉKÏ+�Ÿsª9�����§�������������@�.����xÚ­’½NAÇÿw ‘h ‘„Âê
  20487. /‡"‚TÆDñ#J$Š–ròqr|è!'‰Oá3ØØXøFÁÞ§°0þwY� …1Þfg;73;3»�Âx†ñE0C€ q=ç®Ëæq£XÇ4î°‹GÅA$ñ©x ×ZBñ8Úƒâ DµwÅ!ò‡âIÌéaÅSä¸âùXñ ¢úw¯°ôÛ.¿0«?ù¾o–ÝN³âØ�ºgÚ�ÖÑ@\ÂA´`àžsbˆ“
  20488. ük`§¨sÝ¡}›,ì«0©YƒËa Dðä®ÈµÈµMyFËMváYd°ÅS÷±‡í2Œå¢Äé0~™>´/ãŠqJŒžG
  20489. iòô<ýÒ#cýŒ´0ë·C~G²�ÿ²ƒ9ee Kv«¯­Ð²[Ú·{&V(Ó¨1j•1…M‰Zqr�7±,gKÜ¥þXåè›­õå0éíò–›ÌÛQY{Ô
  20490. ªý›MžY˜¹Ð¶z=ÉË×a°:[jEÝ¢Ÿ ¬² BZìZÿ=nôüs¸`Í+oÍýÔÌ����xÚmÕU”SgFá샧BÝ]óýÉ9Iê$uw÷-J;m©»»Pwwwwwwww˜lîšµ²Þ•‹³ó]<3)e¥®×¿7—Ré^ �üÎèVêVê_@÷Ò$zГ^ô¦ÓЗ~ôg�Ä`†0mé[¦czf`(3233 ³2³3s2s3ó2ó³� ² ³‹²‹³e‚D…*95ê4X’¥XšeX–åXž†1œ4i±+²+³
  20491. «²«³k²k³ë²ë³²³ ›²›³[²[³ Û²Û3’QŒfvd ;1–qŒgg&° »ÒÉnìÎLdOöboöa_öcà@â`áPãpŽàHŽâhŽáXŽãxNàDNâdNa§r§sgrgsçrçsrs —r—sWrWs ×r×s7r7s ·r·swrws÷r÷ó�òó�ò�óOòOó ÏòÏó/ò/ó
  20492. ¯ò¯óoòoóïòïóòó ŸòŸó_ò_ó ßòßó?ò?ó ¿ò¿óòóÿf¥Œ,˺eݳYϬWÖ;ë“M“õÍúeý³ÙÀlP68Òs䘉ãGE{R¯Î±£ËåŽò”MåòÔ 7¹·êænáÖܺÛp;Ú›ZíÍ[Ý›�Ƶ? ѵ•Öµykx×~yÑj?\3V+wEš×ô¸¦Ç5=ªéQM�jzTÓ£šå(»vÂN؉ªk/ì…½°ö’½d/ÙKö’½d/ÙKö’½d¯b¯b¯b¯b¯b¯b¯b¯b¯b¯b¯j¯j¯j¯j¯j¯j¯j¯j¯j¯j/·—ÛËíåör{¹½Ü^n/·—Û+ìv
  20493. ;…�ÂNa§°SØ)ìÔìÔ¼«f¯f¯f¯f¯f¯f¯f¯f¯n¯n¯n¯n¯n¯n¯n¯n¯n¯n¯a¯a¯a¯a¯a¯a¯a¯Ñî…îC÷¡ûhÿQNÞÜ-Ü©ÏÕÝö¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôú݇îC÷¡ûÐ}è>tº݇îC÷¡ûÐ}öôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôú�©îvíNjÿHMÞp“[q«nî®Ïë?é?é?é?é?é?é?é>é>é=é<é<é<é<é<é:é:é:é:é:é:é:U¦>ï÷ë:é:é:é:é:é:é:é:ù=é;é;é;é;é;é;é;é;é;é;é;é;µ}·ê­VÏÎhåS¦èèø·ªÙo����TPÃ��ŸN��AM���������������������LP����������������������',������������������(�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s����R�e�g�u�l�a�r���x�V�e�r�s�i�o�n� �1�.�0�0�9�;�P�S� �0�0�1�.�0�0�9�;�h�o�t�c�o�n�v� �1�.�0�.�7�0�;�m�a�k�e�o�t�f�.�l�i�b�2�.�5�.�5�8�3�2�9���8�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s� �R�e�g�u�l�a�r�����BSGP�����������������©Ü�M�M�FîÍéŒÏÒÙ£(uÊŒ<0DãB/X ïNï ˆ�CCê^Ç rmR2skÉËPJ"5+–gléW*iÕW–/Eî‘œÓ4#¬Ô£U¦~²f‰‘UDÜĹ÷ˆ«±àJ·1á/!þþ/žºÊsª7’“kŠ•”(ºˆ¡hNøé8o�íd$yqŽ¹1³âÖ9ƒ@-‰‚HG’ôµS"øFjôØ 6C3”¤&ž‡ÁøªW51ÁÓÜ×BŸ¯aËêQaR†U/õ¶{*¿‚Ëï�‚=–@dôøh$¡1ÉTÛ—nc+c’ÞA¡§¼ •ZÉ€¤@QÑc­a‡ÕÞl÷�2>ÊK°Èmó' “ËC‡HMĬfB‰X�,¾YòÂp¨e¢�
  20494. î�¸UøØ*Ò”zÿ
  20495. m‚ËËiO1nEÆ.›„ä hx!aC
  20496. XTÚV¢Å©Â‹– —éR¥š%¥|Iä Hð�ÅÕPƒ5"Åb’N²µ=âøƒrÙ/_åRŒ›”™_ à%Ò„�uzÉéÒ˜Ö5’2Ä¡ÒãPÚ)žÔþžÆÃFƒ7S‹q„FÀ{náia�·¸@DÐsˆ;š}9⬥?ź‘§Â R{¦Tkí;޵ǜ×U\NžZø›Q-»^Ôs�7òf 0˜ÊÆS3A Ü _n��`W7Pp˜»ôài«í³!ðgØ/à_p»ÁÒZ€-=Ã×¥~WZ#/á4 KF�`´ »ŒzßÒ0Û| D‚ѵ�ì�‚&däI‰´ŽüÃ�Á;·Mì”{'¶om†”m¢ I !wi9|H:§Û§À»ç÷Êþ¾{û~ö¹ýqº¸©Oøåôî© ú›,˜ ‚L]&„J0ñ•Ù9/í9&ÌYø è“°{;÷ú'À3`’e�@vH„yDZ$º�„3�ˈDx28 ƒW€ Cx5xw‚B`£$C$'ãÊEl…y Õh¿ëÔ€ DJ
  20497. $(p�½îQA”A܉A–@'Ç$ hpÊ0ÎV0 `�ºs¾ªeÒ$É4$"t2=f´˜4„A„{Tk–0|rH¤öÄУï`L&±´sÔh¦]”§A<£¡‹²`R´'£•!ƒ‹�1N¦;£_Št3Û#  âòëúØêVãê *veÑF`E O$Ž{)ÙW=p:®ÞÖF`Š¾2ÆÄ2Ú“CëÁŒÒ^×.Êć˜¡ø–øGþ<<?¢éç~zк¢©å¥>û.pçNe2ê‹ïÖ´ºÞ+YìsÛl:ÂÃË¼ïµ Ü«u5©¦ÞîÐtÀu•^8¾Ì6èóÈ„TmyðQÉ%þu~ôòš%~1rÒ˜aýwßš^�ù_©Z£�Z�a¢ƒ²0!Ùè�¡·úNö`¥.Ž uqÀ±çêYB¥\™¨ó…„ÊᨀÔê…[eð‹îîþ:@ êJ'EÛ�,¯3ubj@�p¨ÁÆäð´f¨Éßóîµ·eW9( óºå ´Þ…‰³æ=‹l”G¦à7gj âSƒM6Æ° ô0ƒÿ9ò§–OË‘¨�üí�l§®B¼aªÝ�ò¯  ƒ<¦çžÇBÕ™(VRAp¡fù^°ú¯+g9 qÓݹ�ŠMÆt]»Øª�pëE�•r@]‡@ó©V�ŸkV¥
  20498. uêädé^ÑX �å–—R@?EÕöY2ô¨˜Éï]#àǼš4ÀJÞåKöÁäÖ'ÃÁ¾d²âPC|mãmånä#¾‚$+48u'…�çe&û¿€[n[LáÈù’ž±%{BCDÚL:^! ‹‚ÓbÆ™:&Éÿˆî‚g3“-3Ðøu´è­ÇæÐð¹ƒb iLZéÚ‚W‚FSÉäIdÍñ¡6.‘k5Pî„l7ž7üUz’T:NýN¡‘—.ý"€ªåü)‰Å—ì’['ß|U"Aƒ€³—‚I•�Ûv©wÐÛØpë™í­t¹dk‚ˆž9Ø›Šå««Í9�n¨D‹mq¹—7I|6›Kbcƒ]¶Mô“©²ÄÎ÷—è¶B�A�€BøȪ�_ôJºT Ùüq Ð 6@—§„¸F�—‡ƒžhd`G®�Tëñ·:MÅ7'à…L,éIh—ÆFP »Ê~j�½ŠŒíÄ ¬$¡„ Ä3™hAÝä��’-SŒ^ûÚ†�…Ðä-%qeÏìë~ÀÆQq«§¬ln"i¾ž&�‘æÑQe?FlKï¨"úAsÀ(Ý3Y;"¡LžÚÔe€tå'ÄRz<MW!¬ßSŠ3$rZ:ˆ’b¥-^Ç„/ƒ$Qý·qõJB'WdáGAO³¨Êã`.Í( ßž±o¤3öB0øÌÊÉ‘ø1å Ìp(®Äí(*–oõ^ÉǪk“†J`vñŒâ±[‘‹¡C|9œ=ðÙåé#„œAöÂQ˜‰ã# ¢òÉ7;.]L:î¿Äϸc®ç€ÐdŸÂêi€ˆEsr¯¡�âó6?æ}¯†eÇ@H-š�b»…ÑÆ–C¶1;®”™è. �v. ±É¾$`T‘ùöÂüù JW¼ÄÜÙ%BËZ¯I04ÄÙøÆ^:kU,èöC‰^êWVF©ÿ¥Ú`£F¬b‘¾(ñOÙÊO© È2<Åß@ÔX™u‘��ðg~ÖÉ‘ÎW št‘&1\ô1§LŒ:φ�„"‡!‘P¶Æ¢Ã è3/ØþÔ^¤øÇ°�q�ˆw`IA¼äD
  20499. ˜)°q£CÐfâ€ÑO“× ±é0õ2Y29®3N°‰fãpà„¨‰é\�˜CÐÃÆahö÷&°6åpË`âÚ�z³g‚B
  20500. hRf­�ž­]; ]Ì#pw_t(›p qê¿�Ù·,ÏÎíbdk‹R‰ÕBŽËèÚT?Ùì2¡Œ—À2¯cåF„y2˜™%¬ÍÏCÏnÁ9 ÐŒ…0›ñÜ÷9E&#×l’T__ÀSлg¶)eh/Ú·+÷#:FGot÷k5Gbr;CbË´Ü:ÄÊÒ#½¼Éœ &�Õã�QC ñwÿ’…™mxlN‡«qˆ ª€éPÇ´)�Í�3f-v5K‰¸¨hý·0A×›¢§Ðj»nSp¬ ÿœ^HªÐG·FŠÀfÝ�¾ó‚HŽ "%[Ñ»‰ßÍ @ � Ûèp ÉaÁ¦Î±�ì$$�œÍ‚Å*âÂ_Ü\Àï@>Mœª1 0¨{=æ�÷)ž€ ³K %�$C
  20501. Âø‘9ŠMðö¼ë¼4c ê€EotjÍÂV§GDŽ)lñ8“¯,˜\wÀ¥à !�%$¿×3tÉ TBz’žÒ´ iUJÒÝ[¢Çxgd„Brï$Å!eqˆ�’"J>࣠)\�~¡‚Š‰3�(^ â R€8#>Öb›äH€âG'7_ fÓ«cκtD�oAA߃†(q™B<ý`Ç­`VˆüøéΫ”©Ö˜Â*úbÞÏu‹P­4v@—+•Ê.�’îQåÔ¥$V‚¡•í@C0
  20502. íR¢ÓÜ�P[‘z:X¦H#eäÁ òs >?úEÈWO>@IØ$|s¬žiâ
  20503. ES¥²)0AŒ?£9•ab,¶�@KšñÌ©o&îþüˆ¬Q´%¬ ÏžLu+›
  20504. Â+�H|ÌÆ�?´NKÌ4ŒÆ’ÓCnPtè³ 'OTòœÒ.j5àÄ´8ÈÜv¶wÖœ�«I¥&•+ß`¼ŠyS��caO[#¡g°§Q§œ€¸Údª[îK½I矗`ôÄŒLPýÓ¸ #°Áœ½ ©)2Ò7aTƒäëi@c\Þ�‘î ÂâÈ0nêC»pòß–é�‹4͵Ž�xö*ñËÐR”zÕYâ„b‡ÀúÛT[\úkU™vìHʈÜq’p঄IÂíIëÅ—) ‹bB X”PºN´…štzí 2 Iæ==¤ ¦³ˆý¨Ã;}†bŠœàqþÓjiÞ†§a²#" ¬Ÿ>1¼‚�°1äA›£p1ÖíÝP‚§OÇèO—ux÷Qôù°¹Î
  20505. Fϲ(úhÝ„©O'MDxÊLíK$ȵœhæ& ù‹¦Ð�1ŒïÄ4››Si ÜãrHJ’P°t�DMË;rMã‚+”ö—
  20506. *–àŸíØ—5u2$ªf3’K ß<ùP²LçrÑc‹I)�˜Öå^ëda>
  20507. %Åàѳb (Ÿú–@,‘2f,~"¦7ÛR;®EÑŽ;¬­”HXå(ú¹Ÿ4Š2ZäÝ'�TªÛ¿ö‹�„”½2J+ÿ^!#oŽ„›”Y~4Ø-׃òGW*ð!ßÃA•0&8€fä{`¼½øàWö=’DP8’'ÿ= ÖR¦ g©}ôiP>“Ê#¹Ëå¹4ÃÒEÐBRY®Æ^4eó�ý‚§N8¸�V,[B‹†ĨîD#�X†ø]²,Öèâ«LBsNC> +¢íoÍê^x¨ì§
  20508.  ÷•�újCì.4ÀYa‰_{e¦A2=rŽðØ+�‰­´Ö9PO»A!!
  20509. ×}´YÊPJe„—çGnš±%xü�1¬/}RgHØša Ž^3-Š© ‹5
  20510. ¶|‹qS§ÐðaWK{ 1al`IÀ1Ó ™ÆQé¾ëf_yyCZ)ÄL3X±] W6@DM™Tø<.„«uëGÎKŒì8ÙDsôÚбWæ‘r…Ý\ß7Z\ÕËÿòVÓ"I¦¢ŒõS¡§®dµ‰>CŽ¦ÈU�j�ßÉežÉÈÓD ®3MÇtWcP﯆–òÓ‰6#3Qךnቩ…°J\º¡Ã7ž#磱`Ø€Këë¤ ©×lV6 &ÓTŽ’ Þ~îÚl.’�¾¡ <˜˜BP
  20511. £*´!zRZÄäeÑ™»¾¾Ù·T±#£CéLH±¬ÈªWÅ)ÚD›†÷“p®YU#ÉÊ51{WJ€Ž¤4^Äf³Ì¼Z°öÌÑy6–Ó‘T2™dÎ4H=êB„Ҋɬ}œ&݃êÂ,aPçv+:2æ~òÁ*0¼°¢ˆd¦É“ÂõÖƒd ‚øáË!"A+‰r��Hn ¡ÇàsAäÁÈÚ—U €ýø¤b H“ÛN6þ$.ÐlÀ};½@£¡âiKà \¬Ò‚:v‰QEÇ�:,|ýªQ  Y0|Ç%Ö@í° Ü�äqcçÓÑdqh¯«è«¹vÜCÍGV†°©¸¯-(шm…’1»®âq89KF–Öä
  20512. "2±ò}RrzóŽ,j^¥ÀqË\…Ý–#pƒ»+õ`flš³½�â:k ´t–5E„OaIÃJ¬P @ps­E™j1ä4;6öô/aHÎ.¼ÏÓ°T�X¤p“L‹¸ÄL8¤½Fç„Üši¨lí1–²YØŠ8É %�!/Áù{­¨ÒÅñ éœ‹ÙåÆXœ€ºbˆ•½…�NÉÂxp»ºäPWê½ÛíèÄcI9g²*þº¿î�ƒ¹œ%:Ö»LËÞuŠ‚CAOÂŒ­™%¬/Å“´(Y¢³^ï? Þã�&I'ˆÈuh[x‹´–Qô$ÇzҵŽø‚ ß³ž�‚(=V×€Ÿê ¾mð­ÅU) »ílΠΒ¾Ìiœ•d㦈™¨½~f¦ùjGíµÖR{D€%>®¥�@”…”6‚¥¤1‚œ`Æ!Î ` ņ¶wYó§‰Õà�k/a�0A†«Â¹ŸÔ�´ÊYh²¯—µòˆdìæxš‘k:fšƒÿ漣<ÕØÙWL4�`8IYMBÁSlcäÖßÈà™-»EÒ‚'ÎÚŒÅ:,ÿD¬°�çÑÙøÆ©84Ó)~÷ÿ2·j€Ÿ–Ç i¶·B(Lãµ| "a©š¦¯4,¦b8§”¥Ô“i 94¦åÔŒÒjWщ° ©6*�ÐTð£†c4gŠÌ“¢×UMÉb³RÇE�²þª‹ò…C5‘Æ)jäÈ´ ‘­1�6pbÃëÛÆŽH÷§ªFxòˆñ¹¿—¯«Ä£�%4âòQÙÄC‰Êˆ§Å $9Ò:ÅM>òEÖÝaÜÆo«�ÌŸ^ÂØ<IwÞ�Ygq�7s[†ð’ð -yÐ1ع5†äaÄãMKš×�æRBÇY€†óFq}¹âç±ô8ïÀ²*ÈNtå�'.Yb„”›¤ÍðZÍûvÅK
  20513. (Ê]&ÉœŠ( Õ™¥ý2¯:0Õ €äo¤Î�Ñ…PKiBH4Uð¹X,Ž¢�[ˆð$
  20514. 0­mX±å»Ø´�‚ ò¥fë5ð0± VR ©8ê%ÙÑñÊÞ§§Dt°ÃUŒ‘s`ô·-BP�ÈzôP”së°Á¦vIë¶8z-¥t1DiB
  20515. ÒÝ"˶ÜÈYTJ ƒÄ.š?Ô0Ç7à€jL¢ÃNžú[2ÿtÈÂĮ̎†�æ� ù#þ6?E×»†”Œ×¡®ˆ:ÉžÎY;ƒç¬A&q…êSØIRÈ)Éss
  20516. 9*xÒß0Bj)mìáH§A¾öhyÐ�hòMm¤&4ÅŠ…4€ €‡ÜÚg¸ŸVæ&tYóÚ¦ÏOCS0³Y²ô‚d7Mv�Nïj)wë÷AÉ(¬âo "Í¢É[¦Ö
  20517. E`›”þŠë7ez¸Ä�†�»Þ-·QÀ]¦6Û+BcaÍ@^IÂ:²Ò»´Þþ¾=ƒ—š­ˆsSŸäÏncÇùÓ 6 ‚ÍçOã¡B„4½ˆŸç L¥¨ÀGpãB‰q/<•zAãÓCÁ¥» €ÔA~¹ÉxÐ0 6rih£Íh¤IìØ·O‚N,:oÇÁkìçÚöÅ/ó¸{H°,ÛzЂgÚfÈ»z—¯Ó΀5ý�Fõ²TrÀn/ät``l†Á™*H6jT¡tG/xøË@P@(„ÄIèp Òeº!ùê`wv,:Aì‘œ¹N£ 4}09zÇqC�ìä$r�ìüM`Y†Q”’ øMää•«³÷Ä(|éB!í>¢ÁØ>«O pwj A*@›�ªŸJäC[h&3�üëB QbýÏ©8 …:ñ“%f~�v/‹lâSäÐèÒ0ÝèþÐð0a“·¶"<TX§@Ç&°ôà°Jg€ 3Ï•ì¤éHF ÕÐoï–éI8«¡{þ¸:YTèób( ˆ°Pëjþ<za{¸…wX¥oa•04 ž3ƒÌlÊøGȶN’à0>ŽBæ8(f úuGoÇšÈgyñÅ×t£_Ãy~ÀÍ”Ž
  20518. Ã%ä…°ûm�†L
  20519. èà!I$äX<T+Ê3­œdqó
  20520. DöMåÔtÌõ2|fEV([â]‘Ndb�œD3Sp'RŸG¬m—K¢›<œT�äÙ°�}½5iÜ·µʹ—àÌp¸ˆ«¿#Ä&jF ôZµ'”®’2ï%y9¡Q#2ñH]w¬Aˆ}Ævf§âØжè%ú³éòöX¡Óš·ì)”X_ S0åt£(±¤“-Ôî€â°“jHpÔ÷Ó–vœï/—Îô詵 ,9®w<`øE“ˆ
  20521. íìF°agAÐÙ“ Ð‰t©´)lœe
  20522. ›øÌ;é ¶ö$9ºŸ×ñ{æCù¨‰�œú()ªÇ?¯ñžÃpƒ¿¼IFã’ø¬‡‹¬¦—žb3”Òñl[):˜drr]Ÿ?†ŸÕ–˜ö?¸ÉBdÀiå¶DÕåÖÅõñ7ýühJ¤Ñ:
  20523. ½ÀU%næ3aƬJ.Ì>t0ƒÏ€~ÀeŒPˆzËÍ]¢Uìg Ð�=_±?ñºµº.j#+`li‘¡ BŠñâM5›Ò º¿Å‘GÒpŒž7«a
  20524. †Ö’�%Y[UG9æ™òÆÓ@\bDêÐY…’{‰�{¤ðED0®—
  20525. Ö$� Qø+FvCð`ݨì3°ýQ¥ “î±E\àÐuC9ÍáÃ![€$êlïßõ šú�êù6ßD¨oÙDgÀGˆ*+�X!¸�%#‚C€q‘ ?é­8ZUB)U@o¢ÏpgÞ©¶ZØq…¡¡É8ŽÊ9øžÇ|ucácAÑœ¶­é°•W;©@á" €Ø>P‚Óïåh_™�Ç9}.6€„�V/ÇO:à3´}Ž¡ZS ±µœ{:ØÚ~’óþœÅyŠk¦cO6;OÎBá=—bVñ. R¿k‹
  20526. oñ ¤ÿ^±GV=áØ }ïoI"+ ô
  20527. ]w‡�×FªÁzÏ·ä®ö`<“Éõ²30�ûh÷ŒÅ3]êRfú—¿859s¼`K…M€¤8ñË
  20528. X»Uqˆ<‰˜¥\˜“ÆZOàssè¿M’·&j&Ï ÄÖ÷ .§%Ÿ ÒPÊBL~^äßÿùGˆËˆ‘3páD‡¬•:í¸×£Z¿£Á¹¨©<\ñ«Ç i¯¨ÛW̆¨ÈÂ"(”ƒ:áÅâz‹©–X–~ê�Î0PG]8�ª¬ƒŒˆRQMNT�¦qfÝW~!Ý0”R%Õ‘�0ðxvGFy/Fø-›Ïwúu‚/ôî*ë+’Æ \õÂ8@ˆ6¢«Âþ©´‹»c<´àLƒ;c�[šû÷ŠÛÙº nr ŸQS'o£QuòT®{qÒ��_œÍ¿�ƒƒSdª»A*ð:mò8Yuz2ÿPB« ìHh`l´k’pèÿLLh
  20529. cEb6eÛ��Ò‹ ?!„™>| *=V�ü­»Kî@žë“rx‘0ÓG`%ryr[6êŠY3Œ7ŒÅ ‡f*—*n•à%9™ÚdfÃè1ó1Þ¢Ú�^'Ìý]‰š– RÍßèq�ÜÔ.Øê÷�,œö•‰Ó^%„¯lÂÚâ ã½eØØ#wWÂÑsó56!Ù=âå!q[ö°ÄØ Ã�%ÈÔ®]ó‹5^:€½m¨5©)?�V b|šuÀ7f“ºìw°œæÄð,:çYe æ†R%”
  20530. ò[À›�î Éo gæF«AzµFP¥›òŸÀÔx›¶î{Ïíöd‚xíÖwÃ8Ž˜–Ù”{{L> ®‚d¬�2Cä�L‘º¨äLÞ,œLÜè,„ò(àmSìø›ÃØåå$=Ñ|%�Ö�luè& Ä…”83ãÚ
  20531. N ¢XåŠx ë \VnõÍïžJ[)I›êwŒÄ/Ñé¹»²Ú ²| GźÙØY×Áð÷DHµ˜½*›Sýª�îè¤æ’p6®0Óc�J2ã@ÅW´%Ѧcï¼_^Ó$Ñç#*:G§®æ6Ž¡ïn>ÍD;úù¥�~¤`9ëhXB ñUŽ«JB_вˆ˜ùˈî%ªý’´w'¹$³èv|#T<68çªKM¶Ï‘-Ù5U+¾¶¡'íB
  20532. ËĪN…‘øŽbJìÃOv'Èì|‹„+*MŒ¼k(dˆ }›CÚ˱@ ³Áq°³¹&ùaR%}´
  20533. Ë!ÖVЃ‘s3w2¦ŽÑa²2²ÿŽawHæz¡/��Q0ðF¦ Ù]~;ž¥Ã¤�ËÖ NDùP
  20534. mü˜K3xÞŠke_™£  ñóþS¯!�¡V&=²²ª²ºvç_PÀ�L9؃Y£¡i¿
  20535. §NU­Ó_¶¬¯)–ƒ�J6Ý9‘f*ÊðS ± �1�7ÚF|¸BR$É·y,Ʊ.¿ÀÕ&=uqsáó¡ODÅòB›ÈôR„=çÙɳ—eøؽɇàB®¬ä¬ÖH­¡®ˆ
  20536. ª2lu'�h7^#ÿS…)£Xi2..P�e¡/@FÕKÉ‘$é](Ø%à|–2ÉðY1pC�±8tÁùIøã11N//+\»“p¥jÔÄïôd€”Îá�WÊmé›ÃI=ß½·ÓY“Zx¡ÔMЉPý8²“1/ JG«õÄ^U ,PÈd1O®ó^¬yßpq”l¿�£2hÝÑ$øjvñø‹þª­ÌõžIšö%‡Š¨§áèÔ]VæÎÖ
  20537. .�'[+WU8Á­[Žå†Dê’³è,ß»¾-=[ÀåÙ O
  20538. wÿƒ ¿Eê)å3±ø¬äó¿J&¥dïقݶR¡¬—S–\.° •5J$I�&ó‘Ýoª·Hȳ~› l‡½Îz>€
  20539. Ux/õHñÐu;š?Gt®{?à³;óT¡ŒªH äLþ|Fú8á†ð²}ˆ¡{ú˜p:ß2tì͆<L¤CA`²¼ÓʘÆâÇë“�§„+' ‰—‰‚¹ªoR0D?AûClIþç¯Z1¬¶›F?j᧴ùõä{^�œEµdGIœµT°º¡&#eJ} ÖÄ É£_m¦Ü�i’³ÐA3÷K["ošCÙTJEßž4Ëc$ô„jÝ�bYËnathY�„`YG�Èãei‚µ¨ñ(…aº#ps¼W�ò±Âi-1òÇÑb™«,ÊŽTécmªå bhv9jhÜô3«tè4Î@zöK±±æꙆfÑjÄ–Å\$5Pü…!¼hR¶“$Pé
  20540. M“Ñš`’³ÿªÀCôC^%2Ù]u Os•‡LTx“íÝp¦Y€Ü!›UÆœ{°Í'�Ð’á¤ÏyLð +Ž°lÈJé‹8ª�Êß)@öw„$F5t4ÕÛ¾­$Ã,£²34aTþ˜&‰†ÕÝ„¨UiõÚ+¿äì-಑-›ç,®ð{!/\ÅÂüÏ‚ŸÂŸ±'& ¿S¬Å�™Á0xkÀYÿ‘Å0I¶)«'Ýöíâ~¿Ö ´ê«•jƒõ#±m!–-TQ`•‹‰=¶=œKRÔèÕ,.is¡gI&jf‰-IÍ(ÿª~ ²Ž³o¨‹,èiž€©å‚Œt&Ú\í�èØ`Íž¹¹éÒ•,äY†çGÜ‘uÁ I(~[Á!2=ÊÍý âø¸“¤hÙåˆ&I™¤ê{8~4œŒ
  20541. ðj(*��aA…TîRþ?bÚ0„I“³Kë¾Pÿ
  20542. ¸¬ž€M ‹û^c³œ´Yf3Œâ-®¹J¸óºc±÷rø;þružêGuAÁT1?Q‚‰à8DŠpy‚y†+‘Òcž¦ìŠ@6!Ë[oËÄÔf£×Zp­�×âɲè`$ÆQõÈ!†²O­‚ á4«Š»|�¬ÇqiùŠL^·Ø_Ç€M+žÆ¾Qb²¹#7ÕƒØìX 5=žÚqQ¿çî¬!¼iëçùm~•‡ù÷Å÷ÔÜ÷‡u…Ý¢êçÓÜ r(48zrŒY;ã*1ÃyNkÖ$9jÖôÊip+ˆq] æ°gèi™f”ÑîùÒ¦f…Ô¥×¾ ¨¤×»‘>a·Ëѧp6ÑÏíÔû·¶øè5Y"LÚD“Œù.Šr¼ØV“ß‘²ßS_ ºÚÊkþÏ]»n&úH�¸z§~¦9‘æ
  20543. ¦p $§4Ù‚”�'¢{º& ¸«ÿËM\ŸÎ°éч¨®!ìq®i�à ÏÄ(.hš'Ë B± T­²Ÿ|ž{I„6cLò¡.¹ž£ë¹�iI¾ê«¿\!à;§àg`1â ᾕ˜j%C ¹o�3*60÷·EŒ˜ØŽž]tä‰.×-%0 Y‰KÇ_nft] ·*VFCÆtJ’°ÄTÔ+¤\WZ�8áòÄâ×gFвàÙ^
  20544. Þžf�¶ 5šI=¶×ù#6ö.@õ2zÒÃ;Wš`ÿB/Ä™QøŠgí°ühŠjyJ�Ó°€N²AX¤3ªÝ,õ¤›� Kä6è’ë6�Ú²ØM0®T@ Ž…O{¡£˜4kj£|"¬ftÑŸ”Û„Uü‚<-üÞa†®Õæ5b�ú)í^R±°8™„ÎÁž:†§il�¾­ÀKaÇ6@µæ”Ã!ÀÍÃ] buvÎ�$ ‡oUÇÂœ�~:.…Lût–èêe—ü Ç€¢JξP
  20545. l$S[z–�~Rq39é’ºô¶9ëQïË/�m"•%ʤ‰¯†¼7Ÿš Ãî5MKLŸé‘§"Iß�G„ èXTÞŽXL¿FðݧV j‘p^¡/MÃgÁÛ»{¶¹»wô
  20546. ì*øº€ž9ÿð—ÊO¾Êˆ<Ë"aôÁþ÷Aáîïˆq¿»¢†.M—�2@möë‡p¿^Ú'“wß•möÇkxO8 ü$[ó«&Áü|Y‚Zyý`2_|%r—“/åJ?¡QùÃṈl‰3ÞÎßK¡E$–wÿvCËh£û a@÷U€1©Mø¾%0?1*¥ –$GÓZÓ{!|ÇÊ¿À$ÃßÛ•Â-òÙªEv;�‹Í“:佋Ÿ`BlÏ˸ ìŒ§Çɬ›oQÝ0&‹•ûþñ,†F?¡ýÆä„^�s,‡c“™ÁhË•ÿ$ÃEücl0åºw`ýâ�º¹Åˆ©@/€r^l˜8cT·3™�Ük@›ÜúJÂÝ”´uPÐ&ʪNÉódùJjT�K¸ªi ·é*u§»éX–{t“j~½É¡}ùñi\BÈKenâ‹Èµ|NëÖê šu�’ï#Ã]@lõCZ$iPæa½ã¸©t04y20ü sØÖªâ,AuÆ!QÒØBäÏ–ö–^ìˆ@VsÉ‘€‚\ÞZßaã7©ì¾‰©¸âш³»6-Tïr±ÀäU˜� àu“Œ~ë°1HÂJ¨(<αŽ‚ò½�Ó³bRÔ–¸qi Ïé梬J?íeÿG�Á §*jVħ "áØã†:Y);�-Fådô!ðH£»ÙG~´•u¦x cb�6m•¼ø)&;ñ0‡ÏdU?‡8ÅX~ïŸ1Ñ2�šÛ¼¨t€ˆI�Øxè5ÄÀ{(ëz„ê
  20547. Ü'¿ûÿ[ ÅƒkŽèZÐ…ØìéÍi,ðÅb™1̇‹¢Íá`º±(ôªm�Há�Nðìüe‰K¤°ßÔ/
  20548. [à´(õö#Qô—GdÊuÎT©½^øm³¢¿%ù†ŒÅ!(˜7Kgé…P=èhøÏ•ákÉ�U+ŒÂÆ.[Òe¯‹Ïм³CÁ�ž�ÿå"GDÿΨ£›<*<ÖÏþéh «)¤` A˜U @O]hýlÅf2”…!HžçÏF#�QBÂé=uȾ9f´h€ó;"R„¥Ú�’KÜ3-‚(G )¼P±áø¡¨ž¦²T],7ÁecÞ
  20549. ë F4hH Ós³73á–Ÿ ¡² âÛ`àºR–¡Tíwfͳ;6Bó>Ř 9&ÈâÛÑÚÜ‚Î?’—÷ø)À\¨Œ€�<&Ŏ™ð5 LÃJu¥@YžÝÝ,�냲ھÛ_wÂ0˜^é17ñððöìpÞ»‡*>D”8㟘ü°_)$UźóÊR´!jOFôÖ>{ˆÐ’‘ »t,¯-…bPµ,m`D"/ŸzðAâ ͔إêßQZGÕ&U]�xejxæåLwvõ~²œ=)@ØB¯Ö6Ê?!;53/ps@tƒOZS7©”§Ø™®’nŸØlxèûîÿZ?áƒZù—j a²–{ýû6—¥ÿL4›Š«1Ÿ 2¹´ù¯‹Q‡iÜý&Ö¥lƒˆá½Åì]o= 7Äļ ofüЖür MEV@ƒâHõ¦èòû/èýaD¥Ù¦ëH•ƒ®®lK5)ÂŒZ OE´œ˜„3Á¦IG©'г;îD'¶zl(‘ ÷�EŸÏÑ$�Š.Ùœð-W R'\w+)Âw3æ꺾ù¸ @Û%RÔ)ÿ.ò~Š9;]ô.šg+)Ø%È�ökÕÎÀÒ‰³¨^ÒöN€W·>b1z:s†¨oD
  20550. K�ö²ºÂ2w[|>9â®vWMFâ¯uÞ`¹ëÍax‡chÕ«õU·�`*ʆeû]O V'6ý‡ÀƒxÔd?¼H]_rõA»£+zÀd­F›¯H ÄÊ‹<¤…Ç´£ÕÆkUsFzÀºòÏaHÖÇ9-³œ��˜ƒgv‚b‹=ÓëL/žE»)°Ä.˜½x9j%Bã) $—ŒéAËB¢�æì ƒÛŸt b.bÒAE¨žZ�RböH(‘£õJÿyaãˆÒ9Wj0f¤ßF'›°Xàz¾Ã ï$DQ­6´ëžqƒØ` oÊÐ i=�áÁ{#4¤©FYHù@ØJÐ3 3i~‘tYТÙhkH‡PÏñ×÷ý17ÓàॆYÜD—"Üp—Ħ;'³16€Æf—pu‹ ô¾>þF›oDÅQi¨náÌ’�-Ïç @P#äš«‡ ¦h“j Þ‚ˆÅ€f´¶C– –�ƒ7°”T5HVXÉpíöÉklÄ­Œ³®]™ÚyXrÆ)?ͺÓBNJš Bƒ÷øä½#Ë›9e”�&&»_0•Ó=®špZ�É6§ªh¤Ù)ð Ì—ƒa bÀŒí=(p)‡âÙåí¬;Š.N•,“ÃWí^ *hÔºŠC—îm}E™7�iõà‡6Á‚Ã÷aËIívͲxpƒ*Ac#4‚ÿýûŒ³Ç Nö&ð`)®Ä‰ˆ£H£We›ƒy7jl¡ï°�oÝEh_n3 ­ ‹jp?ª4èp2WÀE'kT_ã &£°!È–jVl˜HíÓ»_kÉšáÈâöʳùaYùŒ ¡ sÎ@ä[…G"ÊÓbYÕLÛÜ«X¦ªi� ÕC�˜q8ñ&úz��VaY{èÆ#I@µ§�­2˜Žmó!ôdŒ[1 …AàÆ¢šÿnKèðòÕÆe×�²å/>ßdƒm†uX:xÊ·\„âpòN‘ûý©l�+ƒH+cÇtSǶ‚æCÀ±[íà~3ŒÍeÀ}6° �\³,ÎñÉ„˜×|¤Yòݧçø˜§v]¬'û|¿žŸë&í–ìMô2° dõ¬�dsàx-((76”©aX›½m=ÕîÓŠ¿ãQˆ—<$ªª�€üóQ†˜„º\�“
  20551. Ô ªqiéH阇¬‹‰i'i¤”$�"£{S*V�wF‹“/°t<ìÊÁáQ`Ê’Z¸š+ðpr)›(¹.jµé¸«Iük5õ <ä´ʆ±Ë®ÉÖ, kO‘‡œDTˆÊJ&^7º£‡ÄªQ�þ¤ËÏvße
  20552. &žZ�Ø’ ^4úÆ^s°ñD+`WHµ™®�bì6ÙÄ©˜ ¸®ÈL�˜W{ZZ ¦@°ämqáûv¦É·(DÁ\+Ôlåéû0*¥V¥ß‡°VmÕŠ§æhÆ�æØ/S`|³^\<-™„©Ã6ë¸2©N3�‚" ToŸóŒlräÅe ‚!õÅH2 ‹pƒA Ö›¨ ‡ÞÃÏ{›È¼þ/£òŸÑ�çœudU2*2ò"c«Ì"p…${©€y�, 饋ö&\àm¾&º`Ð|x ¦p…ˆCªÒw#ÂÉûW�9D­IiñÑ–Cˆ�›Ksï–ç‡�S¶“ã3ï ,¶‘–þM›’;j¨þBë§4š›P›2ÙÙiµîïf¶®�É¿íÁbA­]a¢idíÂðŠ­¨†"Äò×i!aQhÔCNO½±žŠï‚õYí
  20553. “xF$Äøg—9ž¥‘Z`W«°…VBâg¸± ìÚ#j\Ë‚—¨€eùGñû [³.à¾]‹ª0º~X{2›D©„? Šø"óŠ3ÄBáj,ÀK~Æ�b#„0¬É’L˜kcÍ(6 ¸ 
  20554. ±aüE7λ�/ÕŽ¯%�­ ü±œ·ï àÉÄ¡Rë^JûëÅCÏ�Z+71XÛ´ÐUO,Á„öá}#�-”�eÙ¤ 4ö3Å‚ðítÃ8§™Z7†Îià¬Ê<:iÑ?Ft‹Fk–C W'˜êf0i<âXdj—ùŒ”0ÛW#i‹‹š–eCÏ
  20555. zI7ˆÎB°s·¬˜.Kƒ  *ë�ÝV‘°�«dÿ‡ŸD�ljö@ì«ï%
  20556. ©Üˆ�å� ÎZˆÄsÝï®�sh̸%‡^ß
  20557. ýèøÍ÷@8†ò§¤øÎ?  Nº8gÔGøgr¨X°€Sƒ» üä• Ap ‘³º4‡z*ö¹4á�Ýà§,í¹Ät4GÙnÔè÷‘¼õdSå>fî”Q–CòÏWUZ{SÙ;N�xå½Ê}°ÇH&º¼* ­�9׸¯q‹šU1 Êó a `(M-aÈG}Õn¶Ì½è¢Ú0 –¼pÊÔÇmcnñŽ òð‚ɘÀ_ú\±ül¼ÞÛàþ»}Î È� Þ9÷FávžHþkƒJZüNO å´mZ�áÁQžíÒ¤ aSûëfú�
  20558. )QC+2
  20559. d’˜¡[¯ý» ÌïÁõH"t*Þ Ác*bÏÆÚ¢÷¯q°¨,µ™óã#S˜Ÿ#¢äu›'Ò¬õ:4©as¥©¾CDM�F§|ɸm©_Ã1L]öáY˜Ê\À§ý*¤XœŠ>tú–¯¸Ìg‹§ØD‰Ÿ£Šøèd@&[°)8ÃÎ;<œ{óÊ8<–È+VG\°H˜®¦^�¯a—‹a�eÝ-4”úsÚJÔA \à �hM[‚\`ð“¼#¿pD5Z97g;²÷BWâmÎä‰qTXX‘%0¹�vºžã†ù&ù·]E ¹Û4]ûFŸIJä¤ù–œ„&ÝSŽ_¦îƒ4ÈR‰0 ¯¥Dü+Ëme¹Ô¨Y ƒg÷ÐOøñ+M{”03Ïv�'Í…f…ÁÅt¯á�è :;ôØ±Ê Nô¦nà\Ç”^Ü,)1Þlãá’aBïZZÚ„[•à ¸� ûZSÒÒä¼UYhÜ߆ÏÊw€õ‹šS¸\®/¤*?zQЋÿ`�X4ïg¹ríÛ[§ŠCWæÛGû.§Y„ì0Q|ûRÔƒ‚E�[w¾¦î„yƒ)¸áï‘,шï$ËNK@c/b
  20560. -#Z¯I ¹G$Æ—¯™‹tmçÊH#êð)X£wPZAD|¢S oýf�ŠõT¤€ÝHÚë)¸ÎäÓçÇ>ªM1 b 7á°…ɆS‹uÐÃq×
  20561. ö·öjK4[sð„‡ •—×xL ›Ö¼Ç¢©ë]5 ú!M!A¾dƧN Ë><«:Ç»Z(°8�†ø�)e… „ß »¥™†/™WØÈÀ| ý°bªØéˆú<é÷œƒ®T?%à ²:@±äÔ,-àø€ecMPð8u¤m°VÐg�Œ9Héö6®Ëç‹}¾=³5�ƒ�—AbÒÄŽæýÏì°�¬Î™ÀV:’�…_ leɹß
  20562. ÏÊî–•v ý`Í0Žä!$`GÁéA"I;$ß^?ú�®Ší‰Ke O¢ Í÷³N(Õ½çö“YyÊ5Bç¡w¸ÐV¹%ˆju;)lFµoaåìË›7�óxéÿ’Ú¸Ø4-‰É%ë� †ð$ÏÖ¹/zskǘ(sh>»ÁDD©ÅƒÉt¥TÄ7örurÀœ¸0ÉÒ¢ `Ü´h5 5�Œ¦Éä¶�“Sá}¸ÑÝÈÿÒ4hrva¼éléc!ZjB]�¹Ž¦©ÎxâD¯¶ÿb–Tx�zYS‚ß6_ö)ƒÊo°Ôp>˜#�@P¢SÓ*ýbÜS\q Æ‹xñYfQ><"ó·²ã¢ Y6‘ÅòIE�r_7ñˆÒ° VÔHÃ!�³ÅIçrŒELçŽ6ž!N»�öq"'’d “aþqMvºÅ‹A‚%íõºº¾ ñv³í½Ž n<Eб‰;�Ã,Úw®ß2pO%¬r’‡X“Hö`˜uI#™/šK¹Å ò;‰56‡ßLL.œMI8ÔqÁ¤4U‘närÉ¡"s9¦(ûÜ@=¬ò}N¢¤)?S™ú‚….úr½0L3¯m7VÂýK HG°/®yQ¾Ãé2û/Ww«F)±Áãd)s•¬Fë 7|óŽÆºvQÌ´ËAÝIz`€\‰†¸¾åÜ–Ðä„›<>ð.;šëA/Ïç°ô2ʲ‰œa8D$ÿGWv…#Ì�û 9®kÅÅ'ü‰ËoØŸœo€@âýÌ (]gkí+}/ (nq‡ºìK(f¢ÍÖ ÝƟиžpüøÌ2ÔÈ3Y°ãÝéw�²pDþdG´q2$ÌÉ}‘KÓ¯A­"öE&N‚tg'NeýsÕó!Юð4qìœo}ì¿�¥Sµµë,oÕjr/s œTþMT—&öÐðQf\12¡h'&ctN¦ú'TÅx7¼�]2û ;GÍ Ê…ë¢ã|Tª++:%/ †è¦ûŠ³ÿ1T ‘ÅúÏ“ óË€Ÿ<ÔñÌ4ÂÓÔùŠÀÍ”×ÿ“Ë— É,0~áò�!¡W‹O©à'‰ áÍ:sñuÈÆÊÒ¦Ù†ù�(´^ﮎ µ¥œÂ)˜ø7èØ�fÁ€Ñml¥òÒ¹î1Å«tÜÒZƒèhÀ ÊL0 §£·–6ÒX"JÒ‚í
  20563. Œˆ4§9ØÑ �Ö©Bé}ƒÞÔ­`è`‘¥®ð„Ó’ç #¦JÞïnéäôÑ_‘F­ H|š¡$OÈKÎú=¡Å“i1÷¡¦7Œ”o-HËq¡ªûp[É«%%:ˆä€Éˆi3Û ú„G C—�LL‰4ŠSÐ:ždBòj|‰ˆpYÓöSþD�P>¶pÓv�Þ²5KLeè{t0®ò‘yÇEND$à*�;z»5šŠN’áBIóÙgnŒ€.NÉ|׶àÑnÐ�”RÈaS¤Z×ÂJcH² mÍÑXøÜÊße�k;_ 6È,yÊÂb”�0#¦Z„¸A e|w‚ÔÌG U½1l¸ËLDØ7ÄV£q’Ýt[­xuÝE”QULˆïðPB�lZSh–’.áé1Q0UìÙ±8R„i�úp;¦ñ{óôH#–GON!?ë£èt>©Q |pÊk¤�Ûó¨q!çgT,öÕjÇÐ2ÃÈsÇ�4툊t”jä·nÆ›/IÉO˜E!Ë‹nFõ›4¨†·ˆM&Ô1„’—¾…xÓ$§ew+v™SðË
  20564.  bm]e%8 ²ä�PÌÂ
  20565. !úï³�ŒsÂó_06£ò)Â�Q´2JB†êØý „[t9®–ƒ'”§³Ôœ,§¢Ìô[½f�Æג¶]˜ÂBŠBÃ@š¦îr&B„s|•Qš °§™×g¨íOCˆž1‡ÜJ Dç<ÌÏâUÿ‡²Î¼Ó(o©!³�h¦�ÜK½Hüê 0q›ˆ’§AÑVˆ¼'p´fÌy"Q
  20566. O…Û 2ÇZ»¾ŸqÂà½#d"›@bQ»,®“ w)îPÍ\b`xŠß�Oþ)Þ¢ d¼MC€$[Ho¤�WÞ¦Ñva4{äDZ`52íýº‡³5;‚…X°ÿao�K†;˜6“%ÁR(À‚ŒÓÆÑ…x9Š8 À2rãDc÷¥@ÙˆŒæ¾É¤îF×<†d(ÈAN#F�I·ž›zmEþ‰»F=©±…Æš­å•S‚€f
  20567. 4Ê8§<'´„íj�êŽô-ª˜Ú'ǘ<ÒTbñ2Ýv€EÀt¸¿q¡Ò3qODd_íÐ{`/œhhê‚öÌ`Â’9_ü1hAY|/ùë «Þ·Uê-Í•ºÐÄAÞ”Õo(ñËê"“$r؆TÌ×PR;§.¸-w>&LJøiC`A£^±—Ó#‰€ÄX8—t—öâH?€dÁ¿aÃÄ–TSTÚa¨HŸ0@ÒîŠðóU)ˆ£æï^e}Jb7%×Ü”%:›ÓÆ¿@�—¯MŽ+ñ»y”sqŽ�ª¡ëLÌÒýø¿á ÊYª00Ô÷GüD¡ >Ä©êAW ˆ¶ð2�IÛ:ÄÙF žÈÇš3ãŸ2<k½}[{ç¼*™"A�z0…Î:@ÞÀ¢1¨A:�µðçŠíܤhÖXÃî£Cûñ““£9èˆ8ÈËèµÔE„ùòÉÅUÖØeu)[?©mt-5Ër”~J’ݪÓV2li)áÕž<¸Ò³?ò(D†¦î;)’�o (­¤˜ÊXI¿I$¦–’ñ$ª)À'i(Àª*’¦_µŸE K´ª*½4C‹kàýÏ÷wkOIð˜FfQ$8γ�;(0+.½9²ÃÂ9uÝ$áÂ0öì�t ‘170‰ìfȦ Ç’ûaOµ=T,èm;°€ôn™‘�¥ø˸ÅýΧ—cí<9ð0ú<êÆð _½=g ÀQV&ÞÅB±Ü€Á%fÒ3`5ÍF�ݶ–~‰§`6dÉ.ê2`?ÎÀé]„}ìO´0^­A¿K´N\Qç(I {ÉÆ Œïp[ꜪÒ4Å$6x§P&Õ :²'�7u„ÇêáßÔ æ§´&éõŸRó®®dÀ'Ä Í´#{*Wøµàâl ·DÆQ§ÕÌŽ.*ZEîÿ šcƒÝé7µ¼|4€ ã€Õ‚or\�*öí
  20568. HX¥³Ø'È#k?WRÀ‡‘mP�x Ù$Ù“]�©¯� ׄFKÁ ~È4; [ÒŠh2 ÇAÌɉf‰� ¨<P dg¶é’ ÷)—!b#Z¥?0o´Ôá[¯¯E hXÜ$ö¶ …ÓêSþí’ؾeþˆ½NÛì$�ò–æð“Œ=Ÿ8Ш"^ ‡VÙcFDÔïx˜Á§ýÑRX³CõX“ážÎ.:Fƒ¿q,†„æ1)b¡Bº1 ò§²+¡Qž)ò_ÆOyE£�³
  20569. ôŸü‰¾º¹nTp „š}1`î�#
  20570. ×£d-½Ö¥#„Oñáâ„štïÈ:5ЋŸ/<b0°'m�oqI£ßÁBâŒFW‰ü.‘\k¯cø5ߦ-v›T[Í‚àô�°êà± ôü›-4­:dÝ—u”†[ 8:P금ª£ªBT˜ûµUÌËçÆQð ,F24‚lÀEO÷?ªDþk£œ{ å±1¸k6)Rä̘GIÉË6§Yp^UÁ­!Aâ@é{xg�#^/ ‚×E‰Tz°ÇÄ’Ê»@:FŽ'\�Q6ƒt,æÔpT!iõ
  20571. N!¦dGÁBáÄ^
  20572. ó$@yn�ˆ_uœUüºCÒàíK¨_K62˜ìB|
  20573. ^‡�¢‚T²mr½Ž¡LDgÊ¿Ëf›)!-îúú�ÓoŠ¤�ch»}Éí@oà[ràE] �ë/iÚWJ8ÁOgbêÓ�FÖe‚(/”ÂEΠçyOñ™LB�œ]IkTÚ‰aÌàbVŽÌÕ
  20574. ÏÎ
  20575. 2¼¹“™Ö�%Íb»ŠÂjúªÔg†Œ'‚Àñ‡2…-6µÿ˜Düí»¢òJZe' ·oBi2üû+]x;S¾Pσ¥{£{Ju¤m² „f^L
  20576. S0Ñ’ÍÄ~oÇÇëæü-ë÷ÐS¸Ecô*€vl��pOmó�@�öv -SãÿD;<U ÈC¯Y×à¾îûÖnA)¤pxOý@¥iåLŠ�Â7—E`K\‡J`ô9ÛU$ü pº'°Õ� Ý…ŒÓ3Áv +�“nœ˜%§lSŠ}܉AÅìNj0*±¦è׳48ØÏÎi%чŠ”Ò8ÑãP5Âc‰Œ#ÅèT$F»?$²—€L~ªIžQN_òMC
  20577. Tn‰LŠ`)e|È�‹!dšäóÚòìÜ‘[ìsû‘D”\Vo�‚gFûœŽG(1¨ ÆÌOJB™É�JÛFR%pá�Ž�3NðP CéSêóÒë@pM”�ÍÝvA�f,- +®HƒFt»,Ÿ¶‡ówfA¨€�©²‹æŽ)yÁóî^­Æ¸}ÈNÅ+s8Z‚$j‡NF³ñ×âi#ÚlÈÖâh�–´ÿP!9ge ]ði˨öhòïç€öf“v'ôƒláð!êèynÛOÛä]3ã�i†™Ñ�ÀFÍ ›€ÈPkcœ\çˆ
  20578. `çõÞ@Þ92Ä z¿µXãú;]Û©áiª%[5‹”€àp¬8Q c‹ÈådÛð\ÑLo±ä;jPÚ/Š­ønýg�¢ó[åÒqBÒQP;ö˜,V“eÙçÐ3ÜPr´'Ø·õ4Yÿ©† 8»÷[% Íö¦c“
  20579. ^ˆ`Õ÷° š‹PjL>Ê íq€÷À”:6S•—ŽÑ]KÎÏ" ¥®g[¦� åÏ‘H“˜âB¬5ÈVEqÛLJŒ•X{C¼ˆ¹§B½ÅÙÒ!¥P«Iá�q9»øLlx–®Êª7Ò>Ö¤–Û]@Õ!@9H”!ªíäÈpÀÉ™Õ$ â?ÞÕ)›«�ÜŽ¨l°/"±”ÀÌ�–¯+“@`}}:\÷•¯Ð 8•zQgS£¿+ò’¤¿Á’C„£}€R:ŸõHþUF\¡Xþ’göÀ/âë€AZ%c1ÕwlET�–wX  ZNh¥ …Äyf2DÆ €Ã¸‰&v®L“qî4Æ7•ñ§ûÊzúð\�iJyÀèJ-k¯NÄ3½ ë £-¼s‘ÑJ5‰—)ÙV0™N0ÝdÚ\Ó›d0d-©ãEÚ[mf£\£UmÁx²ÒÒC«R<(`ªÑ•æƒp4^!�hÔQè �`¢ù�!l“ ~Æ™ì:J‡É ñlüW±þ€9˸ÌZXB=ëÈl)`jžªeVJ³àU€³†G!®sØç1Ô?Ƽ3„¨ÃŠ.³}bIaÙê6àÊ• œt?èÀ€ÞSxZJ'Ãp
  20580. ië,¦.ˆ�ñ¬�ØR2T`5�˜-R
  20581. BxræWHö JP°e#Bb‰|“¯”-±þ�¡�ì‹[²„ ÆäPÂâý…¤¨Eh‹±³Â‹(5Sœ¢•fÕräÃ/]Ë°ÑIÆŠ ÌÖd”ÞE#ú¢O®Sú3—9Ó»]¸º³€e‚¿Û®Õɹ.9_Œbêe§æ¾MŒ´�9b#e�©(’¦-ˆ 0�§Ò×Ra±àÆ„9ùº–ˆ"þ‰±þýýU,áÂ%ú~¾XèÜ€ö—”ëz€Û½{'6[@„t[W%ýÑ* .d'vR {”ÒðhŠ¦!ÞAed’CªE}»x=E[|ïB$7J¡* B-á� ,=k7”[_¶ê-ÐIô– ¢«€’‡J5eÖ̶Ä´{ Èí( ´†;�WMw§`«°€Ë~pÜA °z 8‡îfæ))âŒâÂ(Þü@ ©ĪÙ……Ù<áî…ä.a%N òìné@bz­Ã‡ÈÑÀµ¿>À�ëô%…‡€T*?lgb¿döÈ<‚ĵãúÀw9Na¬Å¼8;<^*%�›yÒ:tD¥Ò•Z<@ü‰0ª¨«ä‚q4±äÐíl\ –†1†îÉŸÓ�`/ž$IJ Ò“sN)¼;:A;’)$ו
  20582. °Ww¢y%KrÞIv\b¶V™£\n­d{ÀÞôÈ6t»�v�í×/~¢�ü*OÖí
  20583. 7U>£8ûr‚AC<ºjéŠEâ¢-jçØ牷¨üxsî)��ÌD¢›–1¼ÃŒ/ÏÊq“p**̸À$Ù‘�, Ûá ƒ³BõȼpÄúk MhpˆKê7ÆUè¤Ã]ðøáh&„-ž$ˆéŽ»�¯”“Yê�£;àqËé6w•zÝ÷ÖWûîË„Ö­A¦h²ìDœ‘^RöÞÉ"­Æs5�fýüîw ˆ¿ä+çQ&’/9È‚–œ¸wNbÇëéü��­ãü°Øz{åØ•ÓþYÅ>
  20584. ]NEÚÁ±c,ßž# BFý:0ÍØ/-EȾÆÂŒÇ׃ëF\êŒôäI§{tìäA»Z‰C™ORÃuk¥ iú”ô)…ytkd�N¸&›v§A±™ˆ P{ÍÖîôËP'šó’>ÈêàxàƆ`.Üä%,;:Ô¿Ù:Ž©«­¿íaFñ§oTQ«}v#ôìš×£‘öÚQkèÆ'ÝsÄÔÓÖØ÷~…µÞÍz5hMÄQÊ’áY>C…èÊ�™�„è¾i·ÌU± ÓNF#J0uŒÎCðäð8k“!
  20585. f«éì§v ¹{Eñ/ÏëæIKIEË> ºp·yd†Ìe
  20586. ʾ”=zô†:@7ÖJà÷ijÌ|ÆÆ5g8Àîx Å3çO±Œªþ€ÄÜÜ
  20587. þ3€H1‹ó±Ø„F. y´fz´ìWIM ñÙƒÆj[�.wæ%„i?Ò†UÂè©f|}@+[8•k7Cx¤˜S�…íEOÞ¯p $ä—üáç¾Qæ»+™Ê:¸<á]�¶¸Kâ3�‹T-y²ÂÍ[NÑÖz´µ„;y³Š¤-HZþªY^¡Ô.¥M�*Ô'h8ÒíA….°Nï2r‰œLBœ 7:Or�’©}‘C‰SËšS9äJq#ì£WI}*8ËD!ˆ¸# g#Y�>8`•
  20588. ìÐ’Âñ ?a…�2H,^ñãÄ'ƒ�ï?¸ÿ�^¸ˆæ§nƒhãOÆ’­¿i<ѪæÝYa2É+™üÌ6a°F±âa<Ì!„Û0¬‰2½]�c:ïe¼K¤¬X˜X˜[UgéO¯u5iÔyPcVÙTºž5RIúŸA6òOÔ¸i ¤ýCŽ\‡ñ…—ãQZ�M„DÄƃÓÚ�ÏB!X–Ä:ôÐã\!Ç^Á…"{¡E Vax$P \$ ³DBBTÞÓFtèŸ~™Ã{O‡�¼ w�ïøž5a#ø`�«=�g�€Ð�°Yý2>‡±MG¯-G­k�èªÛ1T¾b¦ü…L
  20589. ¹`*Ù€«V¬X
  20590. ­Þ*¥xªe§֊�Z*c`ªVÁSÕb¥ºÅJUŠ’ªÐ*6 TK@¨zqPÄâ¶ÉÅh“ŠÇg†Ì*ß”U§(ªöQU4‚§9L’
  20591. ­cMÆ*�ŒT»©R!R,B£È…E°Šˆ ¾*C|TzøôpðôFèô@èô4èô*àôà÷õ±î±í…°–†Ø¬á±Xób°€L€.™�T2�y`�®ÀUpbàåÀë�
  20592. �ª�T�, �%@`äÀ è€��# �?@�t€�¤øGLˆëÅž�SÀ)öžÃ¿ z“ÿtϲFy׎� �14�Lh�ŒÐ�ဃ�f�™�°ÈeÀ(.)pK€@\âà —�X¸e@�Tb v•h˜DÀÅ&ù0-I�bD‰ d@�ZD1¤@ ‘�DàyÀ¸ó€Ñ§�CN| 9Ü4æØÓš#Nc lÂÀ°;�¸, �`c‹XâÀ³@�(„�2$0� "@- �˜$è�B@‰�<$�Ð�ÁÀø8p7C�¦ €àbè(�@¥
  20593. PA@…�F �¸0�Àõ�t‰üœÞ‹äG­éÔOR—‰éIJâIïTñyS�ÍMW52\TÆoRå¥KV•0ÈŽ¬à»‚Œ(
  20594. - $²€’š€” ¤!6¦„¢wˆêH¢©†£ùú�Gù­ O r~àe~/à]þ·àV~/àP~7 Szï Kú— Fv`;ö¯`9vÑ#
  20595. J¤Ü§BÍN‚,�ä×ÎÅÓ­²'°��`��¡'â�‚`\LTþðÙApBs�)r…!Õ
  20596. â(
  20597. Òi‚`<?xml version="1.0" standalone="no"?>
  20598. <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
  20599. <svg xmlns="http://www.w3.org/2000/svg">
  20600. <metadata></metadata>
  20601. <defs>
  20602. <font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
  20603. <font-face units-per-em="1200" ascent="960" descent="-240" />
  20604. <missing-glyph horiz-adv-x="500" />
  20605. <glyph horiz-adv-x="0" />
  20606. <glyph horiz-adv-x="400" />
  20607. <glyph unicode=" " />
  20608. <glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
  20609. <glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
  20610. <glyph unicode="&#xa0;" />
  20611. <glyph unicode="&#xa5;" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
  20612. <glyph unicode="&#x2000;" horiz-adv-x="650" />
  20613. <glyph unicode="&#x2001;" horiz-adv-x="1300" />
  20614. <glyph unicode="&#x2002;" horiz-adv-x="650" />
  20615. <glyph unicode="&#x2003;" horiz-adv-x="1300" />
  20616. <glyph unicode="&#x2004;" horiz-adv-x="433" />
  20617. <glyph unicode="&#x2005;" horiz-adv-x="325" />
  20618. <glyph unicode="&#x2006;" horiz-adv-x="216" />
  20619. <glyph unicode="&#x2007;" horiz-adv-x="216" />
  20620. <glyph unicode="&#x2008;" horiz-adv-x="162" />
  20621. <glyph unicode="&#x2009;" horiz-adv-x="260" />
  20622. <glyph unicode="&#x200a;" horiz-adv-x="72" />
  20623. <glyph unicode="&#x202f;" horiz-adv-x="260" />
  20624. <glyph unicode="&#x205f;" horiz-adv-x="325" />
  20625. <glyph unicode="&#x20ac;" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
  20626. <glyph unicode="&#x20bd;" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
  20627. <glyph unicode="&#x2212;" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
  20628. <glyph unicode="&#x231b;" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
  20629. <glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
  20630. <glyph unicode="&#x2601;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
  20631. <glyph unicode="&#x26fa;" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
  20632. <glyph unicode="&#x2709;" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
  20633. <glyph unicode="&#x270f;" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
  20634. <glyph unicode="&#xe001;" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
  20635. <glyph unicode="&#xe002;" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
  20636. <glyph unicode="&#xe003;" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
  20637. <glyph unicode="&#xe005;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
  20638. <glyph unicode="&#xe006;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
  20639. <glyph unicode="&#xe007;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
  20640. <glyph unicode="&#xe008;" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
  20641. <glyph unicode="&#xe009;" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
  20642. <glyph unicode="&#xe010;" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
  20643. <glyph unicode="&#xe011;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
  20644. <glyph unicode="&#xe012;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
  20645. <glyph unicode="&#xe013;" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
  20646. <glyph unicode="&#xe014;" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
  20647. <glyph unicode="&#xe015;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
  20648. <glyph unicode="&#xe016;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
  20649. <glyph unicode="&#xe017;" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
  20650. <glyph unicode="&#xe018;" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
  20651. <glyph unicode="&#xe019;" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
  20652. <glyph unicode="&#xe020;" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
  20653. <glyph unicode="&#xe021;" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
  20654. <glyph unicode="&#xe022;" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
  20655. <glyph unicode="&#xe023;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
  20656. <glyph unicode="&#xe024;" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
  20657. <glyph unicode="&#xe025;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
  20658. <glyph unicode="&#xe026;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
  20659. <glyph unicode="&#xe027;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
  20660. <glyph unicode="&#xe028;" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
  20661. <glyph unicode="&#xe029;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
  20662. <glyph unicode="&#xe030;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
  20663. <glyph unicode="&#xe031;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
  20664. <glyph unicode="&#xe032;" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
  20665. <glyph unicode="&#xe033;" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
  20666. <glyph unicode="&#xe034;" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
  20667. <glyph unicode="&#xe035;" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
  20668. <glyph unicode="&#xe036;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
  20669. <glyph unicode="&#xe037;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
  20670. <glyph unicode="&#xe038;" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
  20671. <glyph unicode="&#xe039;" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
  20672. <glyph unicode="&#xe040;" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
  20673. <glyph unicode="&#xe041;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
  20674. <glyph unicode="&#xe042;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
  20675. <glyph unicode="&#xe043;" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
  20676. <glyph unicode="&#xe044;" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
  20677. <glyph unicode="&#xe045;" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
  20678. <glyph unicode="&#xe046;" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
  20679. <glyph unicode="&#xe047;" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
  20680. <glyph unicode="&#xe048;" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
  20681. <glyph unicode="&#xe049;" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
  20682. <glyph unicode="&#xe050;" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
  20683. <glyph unicode="&#xe051;" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
  20684. <glyph unicode="&#xe052;" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20685. <glyph unicode="&#xe053;" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20686. <glyph unicode="&#xe054;" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
  20687. <glyph unicode="&#xe055;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20688. <glyph unicode="&#xe056;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20689. <glyph unicode="&#xe057;" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20690. <glyph unicode="&#xe058;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20691. <glyph unicode="&#xe059;" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
  20692. <glyph unicode="&#xe060;" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
  20693. <glyph unicode="&#xe062;" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
  20694. <glyph unicode="&#xe063;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
  20695. <glyph unicode="&#xe064;" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
  20696. <glyph unicode="&#xe065;" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
  20697. <glyph unicode="&#xe066;" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
  20698. <glyph unicode="&#xe067;" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
  20699. <glyph unicode="&#xe068;" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
  20700. <glyph unicode="&#xe069;" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
  20701. <glyph unicode="&#xe070;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
  20702. <glyph unicode="&#xe071;" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
  20703. <glyph unicode="&#xe072;" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
  20704. <glyph unicode="&#xe073;" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
  20705. <glyph unicode="&#xe074;" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
  20706. <glyph unicode="&#xe075;" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
  20707. <glyph unicode="&#xe076;" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
  20708. <glyph unicode="&#xe077;" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
  20709. <glyph unicode="&#xe078;" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20710. <glyph unicode="&#xe079;" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
  20711. <glyph unicode="&#xe080;" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
  20712. <glyph unicode="&#xe081;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
  20713. <glyph unicode="&#xe082;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
  20714. <glyph unicode="&#xe083;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
  20715. <glyph unicode="&#xe084;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
  20716. <glyph unicode="&#xe085;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
  20717. <glyph unicode="&#xe086;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
  20718. <glyph unicode="&#xe087;" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
  20719. <glyph unicode="&#xe088;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
  20720. <glyph unicode="&#xe089;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
  20721. <glyph unicode="&#xe090;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
  20722. <glyph unicode="&#xe091;" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
  20723. <glyph unicode="&#xe092;" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
  20724. <glyph unicode="&#xe093;" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
  20725. <glyph unicode="&#xe094;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
  20726. <glyph unicode="&#xe095;" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
  20727. <glyph unicode="&#xe096;" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
  20728. <glyph unicode="&#xe097;" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
  20729. <glyph unicode="&#xe101;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
  20730. <glyph unicode="&#xe102;" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
  20731. <glyph unicode="&#xe103;" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
  20732. <glyph unicode="&#xe104;" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
  20733. <glyph unicode="&#xe105;" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
  20734. <glyph unicode="&#xe106;" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
  20735. <glyph unicode="&#xe107;" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
  20736. <glyph unicode="&#xe108;" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
  20737. <glyph unicode="&#xe109;" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
  20738. <glyph unicode="&#xe110;" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
  20739. <glyph unicode="&#xe111;" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
  20740. <glyph unicode="&#xe112;" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
  20741. <glyph unicode="&#xe113;" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
  20742. <glyph unicode="&#xe114;" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
  20743. <glyph unicode="&#xe115;" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
  20744. <glyph unicode="&#xe116;" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
  20745. <glyph unicode="&#xe117;" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
  20746. <glyph unicode="&#xe118;" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
  20747. <glyph unicode="&#xe119;" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
  20748. <glyph unicode="&#xe120;" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
  20749. <glyph unicode="&#xe121;" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
  20750. <glyph unicode="&#xe122;" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
  20751. <glyph unicode="&#xe123;" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
  20752. <glyph unicode="&#xe124;" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
  20753. <glyph unicode="&#xe125;" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
  20754. <glyph unicode="&#xe126;" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
  20755. <glyph unicode="&#xe127;" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
  20756. <glyph unicode="&#xe128;" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
  20757. <glyph unicode="&#xe129;" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20758. <glyph unicode="&#xe130;" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
  20759. <glyph unicode="&#xe131;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
  20760. <glyph unicode="&#xe132;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
  20761. <glyph unicode="&#xe133;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
  20762. <glyph unicode="&#xe134;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
  20763. <glyph unicode="&#xe135;" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
  20764. <glyph unicode="&#xe136;" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
  20765. <glyph unicode="&#xe137;" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
  20766. <glyph unicode="&#xe138;" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
  20767. <glyph unicode="&#xe139;" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
  20768. <glyph unicode="&#xe140;" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
  20769. <glyph unicode="&#xe141;" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
  20770. <glyph unicode="&#xe142;" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
  20771. <glyph unicode="&#xe143;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
  20772. <glyph unicode="&#xe144;" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
  20773. <glyph unicode="&#xe145;" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
  20774. <glyph unicode="&#xe146;" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
  20775. <glyph unicode="&#xe148;" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
  20776. <glyph unicode="&#xe149;" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
  20777. <glyph unicode="&#xe150;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
  20778. <glyph unicode="&#xe151;" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
  20779. <glyph unicode="&#xe152;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
  20780. <glyph unicode="&#xe153;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
  20781. <glyph unicode="&#xe154;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
  20782. <glyph unicode="&#xe155;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
  20783. <glyph unicode="&#xe156;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
  20784. <glyph unicode="&#xe157;" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
  20785. <glyph unicode="&#xe158;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
  20786. <glyph unicode="&#xe159;" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
  20787. <glyph unicode="&#xe160;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
  20788. <glyph unicode="&#xe161;" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
  20789. <glyph unicode="&#xe162;" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
  20790. <glyph unicode="&#xe163;" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
  20791. <glyph unicode="&#xe164;" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
  20792. <glyph unicode="&#xe165;" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
  20793. <glyph unicode="&#xe166;" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
  20794. <glyph unicode="&#xe167;" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
  20795. <glyph unicode="&#xe168;" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
  20796. <glyph unicode="&#xe169;" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
  20797. <glyph unicode="&#xe170;" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
  20798. <glyph unicode="&#xe171;" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
  20799. <glyph unicode="&#xe172;" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
  20800. <glyph unicode="&#xe173;" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
  20801. <glyph unicode="&#xe174;" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
  20802. <glyph unicode="&#xe175;" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
  20803. <glyph unicode="&#xe176;" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
  20804. <glyph unicode="&#xe177;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
  20805. <glyph unicode="&#xe178;" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
  20806. <glyph unicode="&#xe179;" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
  20807. <glyph unicode="&#xe180;" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
  20808. <glyph unicode="&#xe181;" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
  20809. <glyph unicode="&#xe182;" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
  20810. <glyph unicode="&#xe183;" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
  20811. <glyph unicode="&#xe184;" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20812. <glyph unicode="&#xe185;" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
  20813. <glyph unicode="&#xe186;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
  20814. <glyph unicode="&#xe187;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
  20815. <glyph unicode="&#xe188;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
  20816. <glyph unicode="&#xe189;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
  20817. <glyph unicode="&#xe190;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
  20818. <glyph unicode="&#xe191;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
  20819. <glyph unicode="&#xe192;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
  20820. <glyph unicode="&#xe193;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
  20821. <glyph unicode="&#xe194;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
  20822. <glyph unicode="&#xe195;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
  20823. <glyph unicode="&#xe197;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
  20824. <glyph unicode="&#xe198;" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
  20825. <glyph unicode="&#xe199;" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
  20826. <glyph unicode="&#xe200;" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
  20827. <glyph unicode="&#xe201;" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
  20828. <glyph unicode="&#xe202;" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
  20829. <glyph unicode="&#xe203;" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
  20830. <glyph unicode="&#xe204;" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
  20831. <glyph unicode="&#xe205;" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
  20832. <glyph unicode="&#xe206;" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
  20833. <glyph unicode="&#xe209;" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
  20834. <glyph unicode="&#xe210;" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
  20835. <glyph unicode="&#xe211;" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20836. <glyph unicode="&#xe212;" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20837. <glyph unicode="&#xe213;" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20838. <glyph unicode="&#xe214;" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20839. <glyph unicode="&#xe215;" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20840. <glyph unicode="&#xe216;" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
  20841. <glyph unicode="&#xe218;" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
  20842. <glyph unicode="&#xe219;" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
  20843. <glyph unicode="&#xe221;" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
  20844. <glyph unicode="&#xe223;" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
  20845. <glyph unicode="&#xe224;" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
  20846. <glyph unicode="&#xe225;" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
  20847. <glyph unicode="&#xe226;" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
  20848. <glyph unicode="&#xe227;" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
  20849. <glyph unicode="&#xe230;" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
  20850. <glyph unicode="&#xe231;" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
  20851. <glyph unicode="&#xe232;" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
  20852. <glyph unicode="&#xe233;" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
  20853. <glyph unicode="&#xe234;" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
  20854. <glyph unicode="&#xe235;" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
  20855. <glyph unicode="&#xe236;" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
  20856. <glyph unicode="&#xe237;" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
  20857. <glyph unicode="&#xe238;" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
  20858. <glyph unicode="&#xe239;" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
  20859. <glyph unicode="&#xe240;" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
  20860. <glyph unicode="&#xe241;" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
  20861. <glyph unicode="&#xe242;" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
  20862. <glyph unicode="&#xe243;" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
  20863. <glyph unicode="&#xe244;" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
  20864. <glyph unicode="&#xe245;" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
  20865. <glyph unicode="&#xe246;" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
  20866. <glyph unicode="&#xe247;" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
  20867. <glyph unicode="&#xe248;" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
  20868. <glyph unicode="&#xe249;" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
  20869. <glyph unicode="&#xe250;" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
  20870. <glyph unicode="&#xe251;" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
  20871. <glyph unicode="&#xe252;" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
  20872. <glyph unicode="&#xe253;" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
  20873. <glyph unicode="&#xe254;" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
  20874. <glyph unicode="&#xe255;" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
  20875. <glyph unicode="&#xe256;" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
  20876. <glyph unicode="&#xe257;" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
  20877. <glyph unicode="&#xe258;" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
  20878. <glyph unicode="&#xe259;" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
  20879. <glyph unicode="&#xe260;" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
  20880. <glyph unicode="&#xf8ff;" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
  20881. <glyph unicode="&#x1f511;" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
  20882. <glyph unicode="&#x1f6aa;" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
  20883. </font>
  20884. </defs></svg> <?php
  20885. /*
  20886. * This file is part of the PHP_CodeCoverage package.
  20887. *
  20888. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  20889. *
  20890. * For the full copyright and license information, please view the LICENSE
  20891. * file that was distributed with this source code.
  20892. */
  20893. /**
  20894. * Renders a PHP_CodeCoverage_Report_Node_Directory node.
  20895. *
  20896. * @category PHP
  20897. * @package CodeCoverage
  20898. * @author Sebastian Bergmann <sebastian@phpunit.de>
  20899. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  20900. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  20901. * @link http://github.com/sebastianbergmann/php-code-coverage
  20902. * @since Class available since Release 1.1.0
  20903. */
  20904. class PHP_CodeCoverage_Report_HTML_Renderer_Directory extends PHP_CodeCoverage_Report_HTML_Renderer
  20905. {
  20906. /**
  20907. * @param PHP_CodeCoverage_Report_Node_Directory $node
  20908. * @param string $file
  20909. */
  20910. public function render(PHP_CodeCoverage_Report_Node_Directory $node, $file)
  20911. {
  20912. $template = new Text_Template($this->templatePath . 'directory.html', '{{', '}}');
  20913. $this->setCommonTemplateVariables($template, $node);
  20914. $items = $this->renderItem($node, true);
  20915. foreach ($node->getDirectories() as $item) {
  20916. $items .= $this->renderItem($item);
  20917. }
  20918. foreach ($node->getFiles() as $item) {
  20919. $items .= $this->renderItem($item);
  20920. }
  20921. $template->setVar(
  20922. array(
  20923. 'id' => $node->getId(),
  20924. 'items' => $items
  20925. )
  20926. );
  20927. $template->renderTo($file);
  20928. }
  20929. /**
  20930. * @param PHP_CodeCoverage_Report_Node $item
  20931. * @param boolean $total
  20932. * @return string
  20933. */
  20934. protected function renderItem(PHP_CodeCoverage_Report_Node $item, $total = false)
  20935. {
  20936. $data = array(
  20937. 'numClasses' => $item->getNumClassesAndTraits(),
  20938. 'numTestedClasses' => $item->getNumTestedClassesAndTraits(),
  20939. 'numMethods' => $item->getNumMethods(),
  20940. 'numTestedMethods' => $item->getNumTestedMethods(),
  20941. 'linesExecutedPercent' => $item->getLineExecutedPercent(false),
  20942. 'linesExecutedPercentAsString' => $item->getLineExecutedPercent(),
  20943. 'numExecutedLines' => $item->getNumExecutedLines(),
  20944. 'numExecutableLines' => $item->getNumExecutableLines(),
  20945. 'testedMethodsPercent' => $item->getTestedMethodsPercent(false),
  20946. 'testedMethodsPercentAsString' => $item->getTestedMethodsPercent(),
  20947. 'testedClassesPercent' => $item->getTestedClassesAndTraitsPercent(false),
  20948. 'testedClassesPercentAsString' => $item->getTestedClassesAndTraitsPercent()
  20949. );
  20950. if ($total) {
  20951. $data['name'] = 'Total';
  20952. } else {
  20953. if ($item instanceof PHP_CodeCoverage_Report_Node_Directory) {
  20954. $data['name'] = sprintf(
  20955. '<a href="%s/index.html">%s</a>',
  20956. $item->getName(),
  20957. $item->getName()
  20958. );
  20959. $data['icon'] = '<span class="glyphicon glyphicon-folder-open"></span> ';
  20960. } else {
  20961. $data['name'] = sprintf(
  20962. '<a href="%s.html">%s</a>',
  20963. $item->getName(),
  20964. $item->getName()
  20965. );
  20966. $data['icon'] = '<span class="glyphicon glyphicon-file"></span> ';
  20967. }
  20968. }
  20969. return $this->renderItemTemplate(
  20970. new Text_Template($this->templatePath . 'directory_item.html', '{{', '}}'),
  20971. $data
  20972. );
  20973. }
  20974. }
  20975. <?php
  20976. /*
  20977. * This file is part of the PHP_CodeCoverage package.
  20978. *
  20979. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  20980. *
  20981. * For the full copyright and license information, please view the LICENSE
  20982. * file that was distributed with this source code.
  20983. */
  20984. /**
  20985. * @category PHP
  20986. * @package CodeCoverage
  20987. * @author Zsolt Takács <zsolt@takacs.cc>
  20988. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  20989. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  20990. * @link http://github.com/sebastianbergmann/php-code-coverage
  20991. * @since Class available since Release 2.0.0
  20992. */
  20993. class PHP_CodeCoverage_Report_Crap4j
  20994. {
  20995. private $threshold = 30;
  20996. /**
  20997. * @param PHP_CodeCoverage $coverage
  20998. * @param string $target
  20999. * @param string $name
  21000. * @return string
  21001. */
  21002. public function process(PHP_CodeCoverage $coverage, $target = null, $name = null)
  21003. {
  21004. $document = new DOMDocument('1.0', 'UTF-8');
  21005. $document->formatOutput = true;
  21006. $root = $document->createElement('crap_result');
  21007. $document->appendChild($root);
  21008. $project = $document->createElement('project', is_string($name) ? $name : '');
  21009. $root->appendChild($project);
  21010. $root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s', (int) $_SERVER['REQUEST_TIME'])));
  21011. $stats = $document->createElement('stats');
  21012. $methodsNode = $document->createElement('methods');
  21013. $report = $coverage->getReport();
  21014. unset($coverage);
  21015. $fullMethodCount = 0;
  21016. $fullCrapMethodCount = 0;
  21017. $fullCrapLoad = 0;
  21018. $fullCrap = 0;
  21019. foreach ($report as $item) {
  21020. $namespace = 'global';
  21021. if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
  21022. continue;
  21023. }
  21024. $file = $document->createElement('file');
  21025. $file->setAttribute('name', $item->getPath());
  21026. $classes = $item->getClassesAndTraits();
  21027. foreach ($classes as $className => $class) {
  21028. foreach ($class['methods'] as $methodName => $method) {
  21029. $crapLoad = $this->getCrapLoad($method['crap'], $method['ccn'], $method['coverage']);
  21030. $fullCrap += $method['crap'];
  21031. $fullCrapLoad += $crapLoad;
  21032. $fullMethodCount++;
  21033. if ($method['crap'] >= $this->threshold) {
  21034. $fullCrapMethodCount++;
  21035. }
  21036. $methodNode = $document->createElement('method');
  21037. if (!empty($class['package']['namespace'])) {
  21038. $namespace = $class['package']['namespace'];
  21039. }
  21040. $methodNode->appendChild($document->createElement('package', $namespace));
  21041. $methodNode->appendChild($document->createElement('className', $className));
  21042. $methodNode->appendChild($document->createElement('methodName', $methodName));
  21043. $methodNode->appendChild($document->createElement('methodSignature', htmlspecialchars($method['signature'])));
  21044. $methodNode->appendChild($document->createElement('fullMethod', htmlspecialchars($method['signature'])));
  21045. $methodNode->appendChild($document->createElement('crap', $this->roundValue($method['crap'])));
  21046. $methodNode->appendChild($document->createElement('complexity', $method['ccn']));
  21047. $methodNode->appendChild($document->createElement('coverage', $this->roundValue($method['coverage'])));
  21048. $methodNode->appendChild($document->createElement('crapLoad', round($crapLoad)));
  21049. $methodsNode->appendChild($methodNode);
  21050. }
  21051. }
  21052. }
  21053. $stats->appendChild($document->createElement('name', 'Method Crap Stats'));
  21054. $stats->appendChild($document->createElement('methodCount', $fullMethodCount));
  21055. $stats->appendChild($document->createElement('crapMethodCount', $fullCrapMethodCount));
  21056. $stats->appendChild($document->createElement('crapLoad', round($fullCrapLoad)));
  21057. $stats->appendChild($document->createElement('totalCrap', $fullCrap));
  21058. $stats->appendChild($document->createElement('crapMethodPercent', $this->roundValue(100 * $fullCrapMethodCount / $fullMethodCount)));
  21059. $root->appendChild($stats);
  21060. $root->appendChild($methodsNode);
  21061. if ($target !== null) {
  21062. if (!is_dir(dirname($target))) {
  21063. mkdir(dirname($target), 0777, true);
  21064. }
  21065. return $document->save($target);
  21066. } else {
  21067. return $document->saveXML();
  21068. }
  21069. }
  21070. private function getCrapLoad($crapValue, $cyclomaticComplexity, $coveragePercent)
  21071. {
  21072. $crapLoad = 0;
  21073. if ($crapValue >= $this->threshold) {
  21074. $crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100);
  21075. $crapLoad += $cyclomaticComplexity / $this->threshold;
  21076. }
  21077. return $crapLoad;
  21078. }
  21079. private function roundValue($value)
  21080. {
  21081. return round($value, 2);
  21082. }
  21083. }
  21084. <?php
  21085. /*
  21086. * This file is part of the PHP_CodeCoverage package.
  21087. *
  21088. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21089. *
  21090. * For the full copyright and license information, please view the LICENSE
  21091. * file that was distributed with this source code.
  21092. */
  21093. /**
  21094. * @category PHP
  21095. * @package CodeCoverage
  21096. * @author Arne Blankerts <arne@blankerts.de>
  21097. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21098. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21099. * @link http://github.com/sebastianbergmann/php-code-coverage
  21100. * @since Class available since Release 2.0.0
  21101. */
  21102. class PHP_CodeCoverage_Report_XML_Tests
  21103. {
  21104. private $contextNode;
  21105. private $codeMap = array(
  21106. 0 => 'PASSED', // PHPUnit_Runner_BaseTestRunner::STATUS_PASSED
  21107. 1 => 'SKIPPED', // PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED
  21108. 2 => 'INCOMPLETE', // PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE
  21109. 3 => 'FAILURE', // PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE
  21110. 4 => 'ERROR', // PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
  21111. 5 => 'RISKY' // PHPUnit_Runner_BaseTestRunner::STATUS_RISKY
  21112. );
  21113. public function __construct(DOMElement $context)
  21114. {
  21115. $this->contextNode = $context;
  21116. }
  21117. public function addTest($test, $result)
  21118. {
  21119. $node = $this->contextNode->appendChild(
  21120. $this->contextNode->ownerDocument->createElementNS(
  21121. 'http://schema.phpunit.de/coverage/1.0',
  21122. 'test'
  21123. )
  21124. );
  21125. $node->setAttribute('name', $test);
  21126. $node->setAttribute('result', (int) $result);
  21127. $node->setAttribute('status', $this->codeMap[(int) $result]);
  21128. }
  21129. }
  21130. <?php
  21131. /*
  21132. * This file is part of the PHP_CodeCoverage package.
  21133. *
  21134. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21135. *
  21136. * For the full copyright and license information, please view the LICENSE
  21137. * file that was distributed with this source code.
  21138. */
  21139. /**
  21140. * @category PHP
  21141. * @package CodeCoverage
  21142. * @author Arne Blankerts <arne@blankerts.de>
  21143. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21144. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21145. * @link http://github.com/sebastianbergmann/php-code-coverage
  21146. * @since Class available since Release 2.0.0
  21147. */
  21148. class PHP_CodeCoverage_Report_XML_File
  21149. {
  21150. /**
  21151. * @var DOMDocument
  21152. */
  21153. protected $dom;
  21154. /**
  21155. * @var DOMElement
  21156. */
  21157. protected $contextNode;
  21158. public function __construct(DOMElement $context)
  21159. {
  21160. $this->dom = $context->ownerDocument;
  21161. $this->contextNode = $context;
  21162. }
  21163. public function getTotals()
  21164. {
  21165. $totalsContainer = $this->contextNode->firstChild;
  21166. if (!$totalsContainer) {
  21167. $totalsContainer = $this->contextNode->appendChild(
  21168. $this->dom->createElementNS(
  21169. 'http://schema.phpunit.de/coverage/1.0',
  21170. 'totals'
  21171. )
  21172. );
  21173. }
  21174. return new PHP_CodeCoverage_Report_XML_Totals($totalsContainer);
  21175. }
  21176. public function getLineCoverage($line)
  21177. {
  21178. $coverage = $this->contextNode->getElementsByTagNameNS(
  21179. 'http://schema.phpunit.de/coverage/1.0',
  21180. 'coverage'
  21181. )->item(0);
  21182. if (!$coverage) {
  21183. $coverage = $this->contextNode->appendChild(
  21184. $this->dom->createElementNS(
  21185. 'http://schema.phpunit.de/coverage/1.0',
  21186. 'coverage'
  21187. )
  21188. );
  21189. }
  21190. $lineNode = $coverage->appendChild(
  21191. $this->dom->createElementNS(
  21192. 'http://schema.phpunit.de/coverage/1.0',
  21193. 'line'
  21194. )
  21195. );
  21196. return new PHP_CodeCoverage_Report_XML_File_Coverage($lineNode, $line);
  21197. }
  21198. }
  21199. <?php
  21200. /*
  21201. * This file is part of the PHP_CodeCoverage package.
  21202. *
  21203. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21204. *
  21205. * For the full copyright and license information, please view the LICENSE
  21206. * file that was distributed with this source code.
  21207. */
  21208. /**
  21209. * @category PHP
  21210. * @package CodeCoverage
  21211. * @author Arne Blankerts <arne@blankerts.de>
  21212. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21213. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21214. * @link http://github.com/sebastianbergmann/php-code-coverage
  21215. * @since Class available since Release 2.0.0
  21216. */
  21217. class PHP_CodeCoverage_Report_XML_Node
  21218. {
  21219. /**
  21220. * @var DOMDocument
  21221. */
  21222. private $dom;
  21223. /**
  21224. * @var DOMElement
  21225. */
  21226. private $contextNode;
  21227. public function __construct(DOMElement $context)
  21228. {
  21229. $this->setContextNode($context);
  21230. }
  21231. protected function setContextNode(DOMElement $context)
  21232. {
  21233. $this->dom = $context->ownerDocument;
  21234. $this->contextNode = $context;
  21235. }
  21236. public function getDom()
  21237. {
  21238. return $this->dom;
  21239. }
  21240. protected function getContextNode()
  21241. {
  21242. return $this->contextNode;
  21243. }
  21244. public function getTotals()
  21245. {
  21246. $totalsContainer = $this->getContextNode()->firstChild;
  21247. if (!$totalsContainer) {
  21248. $totalsContainer = $this->getContextNode()->appendChild(
  21249. $this->dom->createElementNS(
  21250. 'http://schema.phpunit.de/coverage/1.0',
  21251. 'totals'
  21252. )
  21253. );
  21254. }
  21255. return new PHP_CodeCoverage_Report_XML_Totals($totalsContainer);
  21256. }
  21257. public function addDirectory($name)
  21258. {
  21259. $dirNode = $this->getDom()->createElementNS(
  21260. 'http://schema.phpunit.de/coverage/1.0',
  21261. 'directory'
  21262. );
  21263. $dirNode->setAttribute('name', $name);
  21264. $this->getContextNode()->appendChild($dirNode);
  21265. return new PHP_CodeCoverage_Report_XML_Directory($dirNode);
  21266. }
  21267. public function addFile($name, $href)
  21268. {
  21269. $fileNode = $this->getDom()->createElementNS(
  21270. 'http://schema.phpunit.de/coverage/1.0',
  21271. 'file'
  21272. );
  21273. $fileNode->setAttribute('name', $name);
  21274. $fileNode->setAttribute('href', $href);
  21275. $this->getContextNode()->appendChild($fileNode);
  21276. return new PHP_CodeCoverage_Report_XML_File($fileNode);
  21277. }
  21278. }
  21279. <?php
  21280. /*
  21281. * This file is part of the PHP_CodeCoverage package.
  21282. *
  21283. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21284. *
  21285. * For the full copyright and license information, please view the LICENSE
  21286. * file that was distributed with this source code.
  21287. */
  21288. /**
  21289. * @category PHP
  21290. * @package CodeCoverage
  21291. * @author Arne Blankerts <arne@blankerts.de>
  21292. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21293. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21294. * @link http://github.com/sebastianbergmann/php-code-coverage
  21295. * @since Class available since Release 2.0.0
  21296. */
  21297. class PHP_CodeCoverage_Report_XML_Project extends PHP_CodeCoverage_Report_XML_Node
  21298. {
  21299. public function __construct($name)
  21300. {
  21301. $this->init();
  21302. $this->setProjectName($name);
  21303. }
  21304. private function init()
  21305. {
  21306. $dom = new DOMDocument;
  21307. $dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><project/></phpunit>');
  21308. $this->setContextNode(
  21309. $dom->getElementsByTagNameNS(
  21310. 'http://schema.phpunit.de/coverage/1.0',
  21311. 'project'
  21312. )->item(0)
  21313. );
  21314. }
  21315. private function setProjectName($name)
  21316. {
  21317. $this->getContextNode()->setAttribute('name', $name);
  21318. }
  21319. public function getTests()
  21320. {
  21321. $testsNode = $this->getContextNode()->getElementsByTagNameNS(
  21322. 'http://schema.phpunit.de/coverage/1.0',
  21323. 'tests'
  21324. )->item(0);
  21325. if (!$testsNode) {
  21326. $testsNode = $this->getContextNode()->appendChild(
  21327. $this->getDom()->createElementNS(
  21328. 'http://schema.phpunit.de/coverage/1.0',
  21329. 'tests'
  21330. )
  21331. );
  21332. }
  21333. return new PHP_CodeCoverage_Report_XML_Tests($testsNode);
  21334. }
  21335. public function asDom()
  21336. {
  21337. return $this->getDom();
  21338. }
  21339. }
  21340. <?php
  21341. /*
  21342. * This file is part of the PHP_CodeCoverage package.
  21343. *
  21344. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21345. *
  21346. * For the full copyright and license information, please view the LICENSE
  21347. * file that was distributed with this source code.
  21348. */
  21349. /**
  21350. * @category PHP
  21351. * @package CodeCoverage
  21352. * @author Arne Blankerts <arne@blankerts.de>
  21353. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21354. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21355. * @link http://github.com/sebastianbergmann/php-code-coverage
  21356. * @since Class available since Release 2.0.0
  21357. */
  21358. class PHP_CodeCoverage_Report_XML_Totals
  21359. {
  21360. /**
  21361. * @var DOMNode
  21362. */
  21363. private $container;
  21364. /**
  21365. * @var DOMElement
  21366. */
  21367. private $linesNode;
  21368. /**
  21369. * @var DOMElement
  21370. */
  21371. private $methodsNode;
  21372. /**
  21373. * @var DOMElement
  21374. */
  21375. private $functionsNode;
  21376. /**
  21377. * @var DOMElement
  21378. */
  21379. private $classesNode;
  21380. /**
  21381. * @var DOMElement
  21382. */
  21383. private $traitsNode;
  21384. public function __construct(DOMElement $container)
  21385. {
  21386. $this->container = $container;
  21387. $dom = $container->ownerDocument;
  21388. $this->linesNode = $dom->createElementNS(
  21389. 'http://schema.phpunit.de/coverage/1.0',
  21390. 'lines'
  21391. );
  21392. $this->methodsNode = $dom->createElementNS(
  21393. 'http://schema.phpunit.de/coverage/1.0',
  21394. 'methods'
  21395. );
  21396. $this->functionsNode = $dom->createElementNS(
  21397. 'http://schema.phpunit.de/coverage/1.0',
  21398. 'functions'
  21399. );
  21400. $this->classesNode = $dom->createElementNS(
  21401. 'http://schema.phpunit.de/coverage/1.0',
  21402. 'classes'
  21403. );
  21404. $this->traitsNode = $dom->createElementNS(
  21405. 'http://schema.phpunit.de/coverage/1.0',
  21406. 'traits'
  21407. );
  21408. $container->appendChild($this->linesNode);
  21409. $container->appendChild($this->methodsNode);
  21410. $container->appendChild($this->functionsNode);
  21411. $container->appendChild($this->classesNode);
  21412. $container->appendChild($this->traitsNode);
  21413. }
  21414. public function getContainer()
  21415. {
  21416. return $this->container;
  21417. }
  21418. public function setNumLines($loc, $cloc, $ncloc, $executable, $executed)
  21419. {
  21420. $this->linesNode->setAttribute('total', $loc);
  21421. $this->linesNode->setAttribute('comments', $cloc);
  21422. $this->linesNode->setAttribute('code', $ncloc);
  21423. $this->linesNode->setAttribute('executable', $executable);
  21424. $this->linesNode->setAttribute('executed', $executed);
  21425. $this->linesNode->setAttribute(
  21426. 'percent',
  21427. PHP_CodeCoverage_Util::percent($executed, $executable, true)
  21428. );
  21429. }
  21430. public function setNumClasses($count, $tested)
  21431. {
  21432. $this->classesNode->setAttribute('count', $count);
  21433. $this->classesNode->setAttribute('tested', $tested);
  21434. $this->classesNode->setAttribute(
  21435. 'percent',
  21436. PHP_CodeCoverage_Util::percent($tested, $count, true)
  21437. );
  21438. }
  21439. public function setNumTraits($count, $tested)
  21440. {
  21441. $this->traitsNode->setAttribute('count', $count);
  21442. $this->traitsNode->setAttribute('tested', $tested);
  21443. $this->traitsNode->setAttribute(
  21444. 'percent',
  21445. PHP_CodeCoverage_Util::percent($tested, $count, true)
  21446. );
  21447. }
  21448. public function setNumMethods($count, $tested)
  21449. {
  21450. $this->methodsNode->setAttribute('count', $count);
  21451. $this->methodsNode->setAttribute('tested', $tested);
  21452. $this->methodsNode->setAttribute(
  21453. 'percent',
  21454. PHP_CodeCoverage_Util::percent($tested, $count, true)
  21455. );
  21456. }
  21457. public function setNumFunctions($count, $tested)
  21458. {
  21459. $this->functionsNode->setAttribute('count', $count);
  21460. $this->functionsNode->setAttribute('tested', $tested);
  21461. $this->functionsNode->setAttribute(
  21462. 'percent',
  21463. PHP_CodeCoverage_Util::percent($tested, $count, true)
  21464. );
  21465. }
  21466. }
  21467. <?php
  21468. /*
  21469. * This file is part of the PHP_CodeCoverage package.
  21470. *
  21471. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21472. *
  21473. * For the full copyright and license information, please view the LICENSE
  21474. * file that was distributed with this source code.
  21475. */
  21476. /**
  21477. * @category PHP
  21478. * @package CodeCoverage
  21479. * @author Arne Blankerts <arne@blankerts.de>
  21480. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21481. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21482. * @link http://github.com/sebastianbergmann/php-code-coverage
  21483. * @since Class available since Release 2.0.0
  21484. */
  21485. class PHP_CodeCoverage_Report_XML_Directory extends PHP_CodeCoverage_Report_XML_Node
  21486. {
  21487. }
  21488. <?php
  21489. /*
  21490. * This file is part of the PHP_CodeCoverage package.
  21491. *
  21492. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21493. *
  21494. * For the full copyright and license information, please view the LICENSE
  21495. * file that was distributed with this source code.
  21496. */
  21497. /**
  21498. * @category PHP
  21499. * @package CodeCoverage
  21500. * @author Arne Blankerts <arne@blankerts.de>
  21501. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21502. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21503. * @link http://github.com/sebastianbergmann/php-code-coverage
  21504. * @since Class available since Release 2.0.0
  21505. */
  21506. class PHP_CodeCoverage_Report_XML_File_Method
  21507. {
  21508. /**
  21509. * @var DOMElement
  21510. */
  21511. private $contextNode;
  21512. public function __construct(DOMElement $context, $name)
  21513. {
  21514. $this->contextNode = $context;
  21515. $this->setName($name);
  21516. }
  21517. private function setName($name)
  21518. {
  21519. $this->contextNode->setAttribute('name', $name);
  21520. }
  21521. public function setSignature($signature)
  21522. {
  21523. $this->contextNode->setAttribute('signature', $signature);
  21524. }
  21525. public function setLines($start, $end = null)
  21526. {
  21527. $this->contextNode->setAttribute('start', $start);
  21528. if ($end !== null) {
  21529. $this->contextNode->setAttribute('end', $end);
  21530. }
  21531. }
  21532. public function setTotals($executable, $executed, $coverage)
  21533. {
  21534. $this->contextNode->setAttribute('executable', $executable);
  21535. $this->contextNode->setAttribute('executed', $executed);
  21536. $this->contextNode->setAttribute('coverage', $coverage);
  21537. }
  21538. public function setCrap($crap)
  21539. {
  21540. $this->contextNode->setAttribute('crap', $crap);
  21541. }
  21542. }
  21543. <?php
  21544. /*
  21545. * This file is part of the PHP_CodeCoverage package.
  21546. *
  21547. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21548. *
  21549. * For the full copyright and license information, please view the LICENSE
  21550. * file that was distributed with this source code.
  21551. */
  21552. /**
  21553. * @category PHP
  21554. * @package CodeCoverage
  21555. * @author Arne Blankerts <arne@blankerts.de>
  21556. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21557. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21558. * @link http://github.com/sebastianbergmann/php-code-coverage
  21559. * @since Class available since Release 2.0.0
  21560. */
  21561. class PHP_CodeCoverage_Report_XML_File_Report extends PHP_CodeCoverage_Report_XML_File
  21562. {
  21563. public function __construct($name)
  21564. {
  21565. $this->dom = new DOMDocument;
  21566. $this->dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
  21567. $this->contextNode = $this->dom->getElementsByTagNameNS(
  21568. 'http://schema.phpunit.de/coverage/1.0',
  21569. 'file'
  21570. )->item(0);
  21571. $this->setName($name);
  21572. }
  21573. private function setName($name)
  21574. {
  21575. $this->contextNode->setAttribute('name', $name);
  21576. }
  21577. public function asDom()
  21578. {
  21579. return $this->dom;
  21580. }
  21581. public function getFunctionObject($name)
  21582. {
  21583. $node = $this->contextNode->appendChild(
  21584. $this->dom->createElementNS(
  21585. 'http://schema.phpunit.de/coverage/1.0',
  21586. 'function'
  21587. )
  21588. );
  21589. return new PHP_CodeCoverage_Report_XML_File_Method($node, $name);
  21590. }
  21591. public function getClassObject($name)
  21592. {
  21593. return $this->getUnitObject('class', $name);
  21594. }
  21595. public function getTraitObject($name)
  21596. {
  21597. return $this->getUnitObject('trait', $name);
  21598. }
  21599. private function getUnitObject($tagName, $name)
  21600. {
  21601. $node = $this->contextNode->appendChild(
  21602. $this->dom->createElementNS(
  21603. 'http://schema.phpunit.de/coverage/1.0',
  21604. $tagName
  21605. )
  21606. );
  21607. return new PHP_CodeCoverage_Report_XML_File_Unit($node, $name);
  21608. }
  21609. }
  21610. <?php
  21611. /*
  21612. * This file is part of the PHP_CodeCoverage package.
  21613. *
  21614. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21615. *
  21616. * For the full copyright and license information, please view the LICENSE
  21617. * file that was distributed with this source code.
  21618. */
  21619. /**
  21620. * @category PHP
  21621. * @package CodeCoverage
  21622. * @author Arne Blankerts <arne@blankerts.de>
  21623. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21624. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21625. * @link http://github.com/sebastianbergmann/php-code-coverage
  21626. * @since Class available since Release 2.0.0
  21627. */
  21628. class PHP_CodeCoverage_Report_XML_File_Coverage
  21629. {
  21630. /**
  21631. * @var XMLWriter
  21632. */
  21633. private $writer;
  21634. /**
  21635. * @var DOMElement
  21636. */
  21637. private $contextNode;
  21638. /**
  21639. * @var bool
  21640. */
  21641. private $finalized = false;
  21642. public function __construct(DOMElement $context, $line)
  21643. {
  21644. $this->contextNode = $context;
  21645. $this->writer = new XMLWriter();
  21646. $this->writer->openMemory();
  21647. $this->writer->startElementNs(null, $context->nodeName, 'http://schema.phpunit.de/coverage/1.0');
  21648. $this->writer->writeAttribute('nr', $line);
  21649. }
  21650. public function addTest($test)
  21651. {
  21652. if ($this->finalized) {
  21653. throw new PHP_CodeCoverage_Exception('Coverage Report already finalized');
  21654. }
  21655. $this->writer->startElement('covered');
  21656. $this->writer->writeAttribute('by', $test);
  21657. $this->writer->endElement();
  21658. }
  21659. public function finalize()
  21660. {
  21661. $this->writer->endElement();
  21662. $fragment = $this->contextNode->ownerDocument->createDocumentFragment();
  21663. $fragment->appendXML($this->writer->outputMemory());
  21664. $this->contextNode->parentNode->replaceChild(
  21665. $fragment,
  21666. $this->contextNode
  21667. );
  21668. $this->finalized = true;
  21669. }
  21670. }
  21671. <?php
  21672. /*
  21673. * This file is part of the PHP_CodeCoverage package.
  21674. *
  21675. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21676. *
  21677. * For the full copyright and license information, please view the LICENSE
  21678. * file that was distributed with this source code.
  21679. */
  21680. /**
  21681. * @category PHP
  21682. * @package CodeCoverage
  21683. * @author Arne Blankerts <arne@blankerts.de>
  21684. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21685. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21686. * @link http://github.com/sebastianbergmann/php-code-coverage
  21687. * @since Class available since Release 2.0.0
  21688. */
  21689. class PHP_CodeCoverage_Report_XML_File_Unit
  21690. {
  21691. /**
  21692. * @var DOMElement
  21693. */
  21694. private $contextNode;
  21695. public function __construct(DOMElement $context, $name)
  21696. {
  21697. $this->contextNode = $context;
  21698. $this->setName($name);
  21699. }
  21700. private function setName($name)
  21701. {
  21702. $this->contextNode->setAttribute('name', $name);
  21703. }
  21704. public function setLines($start, $executable, $executed)
  21705. {
  21706. $this->contextNode->setAttribute('start', $start);
  21707. $this->contextNode->setAttribute('executable', $executable);
  21708. $this->contextNode->setAttribute('executed', $executed);
  21709. }
  21710. public function setCrap($crap)
  21711. {
  21712. $this->contextNode->setAttribute('crap', $crap);
  21713. }
  21714. public function setPackage($full, $package, $sub, $category)
  21715. {
  21716. $node = $this->contextNode->getElementsByTagNameNS(
  21717. 'http://schema.phpunit.de/coverage/1.0',
  21718. 'package'
  21719. )->item(0);
  21720. if (!$node) {
  21721. $node = $this->contextNode->appendChild(
  21722. $this->contextNode->ownerDocument->createElementNS(
  21723. 'http://schema.phpunit.de/coverage/1.0',
  21724. 'package'
  21725. )
  21726. );
  21727. }
  21728. $node->setAttribute('full', $full);
  21729. $node->setAttribute('name', $package);
  21730. $node->setAttribute('sub', $sub);
  21731. $node->setAttribute('category', $category);
  21732. }
  21733. public function setNamespace($namespace)
  21734. {
  21735. $node = $this->contextNode->getElementsByTagNameNS(
  21736. 'http://schema.phpunit.de/coverage/1.0',
  21737. 'namespace'
  21738. )->item(0);
  21739. if (!$node) {
  21740. $node = $this->contextNode->appendChild(
  21741. $this->contextNode->ownerDocument->createElementNS(
  21742. 'http://schema.phpunit.de/coverage/1.0',
  21743. 'namespace'
  21744. )
  21745. );
  21746. }
  21747. $node->setAttribute('name', $namespace);
  21748. }
  21749. public function addMethod($name)
  21750. {
  21751. $node = $this->contextNode->appendChild(
  21752. $this->contextNode->ownerDocument->createElementNS(
  21753. 'http://schema.phpunit.de/coverage/1.0',
  21754. 'method'
  21755. )
  21756. );
  21757. return new PHP_CodeCoverage_Report_XML_File_Method($node, $name);
  21758. }
  21759. }
  21760. <?php
  21761. /*
  21762. * This file is part of the PHP_CodeCoverage package.
  21763. *
  21764. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21765. *
  21766. * For the full copyright and license information, please view the LICENSE
  21767. * file that was distributed with this source code.
  21768. */
  21769. /**
  21770. * Base class for nodes in the code coverage information tree.
  21771. *
  21772. * @category PHP
  21773. * @package CodeCoverage
  21774. * @author Sebastian Bergmann <sebastian@phpunit.de>
  21775. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  21776. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  21777. * @link http://github.com/sebastianbergmann/php-code-coverage
  21778. * @since Class available since Release 1.1.0
  21779. */
  21780. abstract class PHP_CodeCoverage_Report_Node implements Countable
  21781. {
  21782. /**
  21783. * @var string
  21784. */
  21785. protected $name;
  21786. /**
  21787. * @var string
  21788. */
  21789. protected $path;
  21790. /**
  21791. * @var array
  21792. */
  21793. protected $pathArray;
  21794. /**
  21795. * @var PHP_CodeCoverage_Report_Node
  21796. */
  21797. protected $parent;
  21798. /**
  21799. * @var string
  21800. */
  21801. protected $id;
  21802. /**
  21803. * Constructor.
  21804. *
  21805. * @param string $name
  21806. * @param PHP_CodeCoverage_Report_Node $parent
  21807. */
  21808. public function __construct($name, PHP_CodeCoverage_Report_Node $parent = null)
  21809. {
  21810. if (substr($name, -1) == '/') {
  21811. $name = substr($name, 0, -1);
  21812. }
  21813. $this->name = $name;
  21814. $this->parent = $parent;
  21815. }
  21816. /**
  21817. * @return string
  21818. */
  21819. public function getName()
  21820. {
  21821. return $this->name;
  21822. }
  21823. /**
  21824. * @return string
  21825. */
  21826. public function getId()
  21827. {
  21828. if ($this->id === null) {
  21829. $parent = $this->getParent();
  21830. if ($parent === null) {
  21831. $this->id = 'index';
  21832. } else {
  21833. $parentId = $parent->getId();
  21834. if ($parentId == 'index') {
  21835. $this->id = str_replace(':', '_', $this->name);
  21836. } else {
  21837. $this->id = $parentId . '/' . $this->name;
  21838. }
  21839. }
  21840. }
  21841. return $this->id;
  21842. }
  21843. /**
  21844. * @return string
  21845. */
  21846. public function getPath()
  21847. {
  21848. if ($this->path === null) {
  21849. if ($this->parent === null || $this->parent->getPath() === null || $this->parent->getPath() === false) {
  21850. $this->path = $this->name;
  21851. } else {
  21852. $this->path = $this->parent->getPath() . '/' . $this->name;
  21853. }
  21854. }
  21855. return $this->path;
  21856. }
  21857. /**
  21858. * @return array
  21859. */
  21860. public function getPathAsArray()
  21861. {
  21862. if ($this->pathArray === null) {
  21863. if ($this->parent === null) {
  21864. $this->pathArray = array();
  21865. } else {
  21866. $this->pathArray = $this->parent->getPathAsArray();
  21867. }
  21868. $this->pathArray[] = $this;
  21869. }
  21870. return $this->pathArray;
  21871. }
  21872. /**
  21873. * @return PHP_CodeCoverage_Report_Node
  21874. */
  21875. public function getParent()
  21876. {
  21877. return $this->parent;
  21878. }
  21879. /**
  21880. * Returns the percentage of classes that has been tested.
  21881. *
  21882. * @param boolean $asString
  21883. * @return integer
  21884. */
  21885. public function getTestedClassesPercent($asString = true)
  21886. {
  21887. return PHP_CodeCoverage_Util::percent(
  21888. $this->getNumTestedClasses(),
  21889. $this->getNumClasses(),
  21890. $asString
  21891. );
  21892. }
  21893. /**
  21894. * Returns the percentage of traits that has been tested.
  21895. *
  21896. * @param boolean $asString
  21897. * @return integer
  21898. */
  21899. public function getTestedTraitsPercent($asString = true)
  21900. {
  21901. return PHP_CodeCoverage_Util::percent(
  21902. $this->getNumTestedTraits(),
  21903. $this->getNumTraits(),
  21904. $asString
  21905. );
  21906. }
  21907. /**
  21908. * Returns the percentage of traits that has been tested.
  21909. *
  21910. * @param boolean $asString
  21911. * @return integer
  21912. * @since Method available since Release 1.2.0
  21913. */
  21914. public function getTestedClassesAndTraitsPercent($asString = true)
  21915. {
  21916. return PHP_CodeCoverage_Util::percent(
  21917. $this->getNumTestedClassesAndTraits(),
  21918. $this->getNumClassesAndTraits(),
  21919. $asString
  21920. );
  21921. }
  21922. /**
  21923. * Returns the percentage of methods that has been tested.
  21924. *
  21925. * @param boolean $asString
  21926. * @return integer
  21927. */
  21928. public function getTestedMethodsPercent($asString = true)
  21929. {
  21930. return PHP_CodeCoverage_Util::percent(
  21931. $this->getNumTestedMethods(),
  21932. $this->getNumMethods(),
  21933. $asString
  21934. );
  21935. }
  21936. /**
  21937. * Returns the percentage of executed lines.
  21938. *
  21939. * @param boolean $asString
  21940. * @return integer
  21941. */
  21942. public function getLineExecutedPercent($asString = true)
  21943. {
  21944. return PHP_CodeCoverage_Util::percent(
  21945. $this->getNumExecutedLines(),
  21946. $this->getNumExecutableLines(),
  21947. $asString
  21948. );
  21949. }
  21950. /**
  21951. * Returns the number of classes and traits.
  21952. *
  21953. * @return integer
  21954. * @since Method available since Release 1.2.0
  21955. */
  21956. public function getNumClassesAndTraits()
  21957. {
  21958. return $this->getNumClasses() + $this->getNumTraits();
  21959. }
  21960. /**
  21961. * Returns the number of tested classes and traits.
  21962. *
  21963. * @return integer
  21964. * @since Method available since Release 1.2.0
  21965. */
  21966. public function getNumTestedClassesAndTraits()
  21967. {
  21968. return $this->getNumTestedClasses() + $this->getNumTestedTraits();
  21969. }
  21970. /**
  21971. * Returns the classes and traits of this node.
  21972. *
  21973. * @return array
  21974. * @since Method available since Release 1.2.0
  21975. */
  21976. public function getClassesAndTraits()
  21977. {
  21978. return array_merge($this->getClasses(), $this->getTraits());
  21979. }
  21980. /**
  21981. * Returns the classes of this node.
  21982. *
  21983. * @return array
  21984. */
  21985. abstract public function getClasses();
  21986. /**
  21987. * Returns the traits of this node.
  21988. *
  21989. * @return array
  21990. */
  21991. abstract public function getTraits();
  21992. /**
  21993. * Returns the functions of this node.
  21994. *
  21995. * @return array
  21996. */
  21997. abstract public function getFunctions();
  21998. /**
  21999. * Returns the LOC/CLOC/NCLOC of this node.
  22000. *
  22001. * @return array
  22002. */
  22003. abstract public function getLinesOfCode();
  22004. /**
  22005. * Returns the number of executable lines.
  22006. *
  22007. * @return integer
  22008. */
  22009. abstract public function getNumExecutableLines();
  22010. /**
  22011. * Returns the number of executed lines.
  22012. *
  22013. * @return integer
  22014. */
  22015. abstract public function getNumExecutedLines();
  22016. /**
  22017. * Returns the number of classes.
  22018. *
  22019. * @return integer
  22020. */
  22021. abstract public function getNumClasses();
  22022. /**
  22023. * Returns the number of tested classes.
  22024. *
  22025. * @return integer
  22026. */
  22027. abstract public function getNumTestedClasses();
  22028. /**
  22029. * Returns the number of traits.
  22030. *
  22031. * @return integer
  22032. */
  22033. abstract public function getNumTraits();
  22034. /**
  22035. * Returns the number of tested traits.
  22036. *
  22037. * @return integer
  22038. */
  22039. abstract public function getNumTestedTraits();
  22040. /**
  22041. * Returns the number of methods.
  22042. *
  22043. * @return integer
  22044. */
  22045. abstract public function getNumMethods();
  22046. /**
  22047. * Returns the number of tested methods.
  22048. *
  22049. * @return integer
  22050. */
  22051. abstract public function getNumTestedMethods();
  22052. /**
  22053. * Returns the number of functions.
  22054. *
  22055. * @return integer
  22056. */
  22057. abstract public function getNumFunctions();
  22058. /**
  22059. * Returns the number of tested functions.
  22060. *
  22061. * @return integer
  22062. */
  22063. abstract public function getNumTestedFunctions();
  22064. }
  22065. <?php
  22066. /*
  22067. * This file is part of the PHP_CodeCoverage package.
  22068. *
  22069. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  22070. *
  22071. * For the full copyright and license information, please view the LICENSE
  22072. * file that was distributed with this source code.
  22073. */
  22074. /**
  22075. * Recursive iterator for PHP_CodeCoverage_Report_Node object graphs.
  22076. *
  22077. * @category PHP
  22078. * @package CodeCoverage
  22079. * @author Sebastian Bergmann <sebastian@phpunit.de>
  22080. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  22081. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  22082. * @link http://github.com/sebastianbergmann/php-code-coverage
  22083. * @since Class available since Release 1.1.0
  22084. */
  22085. class PHP_CodeCoverage_Report_Node_Iterator implements RecursiveIterator
  22086. {
  22087. /**
  22088. * @var integer
  22089. */
  22090. protected $position;
  22091. /**
  22092. * @var PHP_CodeCoverage_Report_Node[]
  22093. */
  22094. protected $nodes;
  22095. /**
  22096. * Constructor.
  22097. *
  22098. * @param PHP_CodeCoverage_Report_Node_Directory $node
  22099. */
  22100. public function __construct(PHP_CodeCoverage_Report_Node_Directory $node)
  22101. {
  22102. $this->nodes = $node->getChildNodes();
  22103. }
  22104. /**
  22105. * Rewinds the Iterator to the first element.
  22106. *
  22107. */
  22108. public function rewind()
  22109. {
  22110. $this->position = 0;
  22111. }
  22112. /**
  22113. * Checks if there is a current element after calls to rewind() or next().
  22114. *
  22115. * @return boolean
  22116. */
  22117. public function valid()
  22118. {
  22119. return $this->position < count($this->nodes);
  22120. }
  22121. /**
  22122. * Returns the key of the current element.
  22123. *
  22124. * @return integer
  22125. */
  22126. public function key()
  22127. {
  22128. return $this->position;
  22129. }
  22130. /**
  22131. * Returns the current element.
  22132. *
  22133. * @return PHPUnit_Framework_Test
  22134. */
  22135. public function current()
  22136. {
  22137. return $this->valid() ? $this->nodes[$this->position] : null;
  22138. }
  22139. /**
  22140. * Moves forward to next element.
  22141. *
  22142. */
  22143. public function next()
  22144. {
  22145. $this->position++;
  22146. }
  22147. /**
  22148. * Returns the sub iterator for the current element.
  22149. *
  22150. * @return PHP_CodeCoverage_Report_Node_Iterator
  22151. */
  22152. public function getChildren()
  22153. {
  22154. return new PHP_CodeCoverage_Report_Node_Iterator(
  22155. $this->nodes[$this->position]
  22156. );
  22157. }
  22158. /**
  22159. * Checks whether the current element has children.
  22160. *
  22161. * @return boolean
  22162. */
  22163. public function hasChildren()
  22164. {
  22165. return $this->nodes[$this->position] instanceof PHP_CodeCoverage_Report_Node_Directory;
  22166. }
  22167. }
  22168. <?php
  22169. /*
  22170. * This file is part of the PHP_CodeCoverage package.
  22171. *
  22172. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  22173. *
  22174. * For the full copyright and license information, please view the LICENSE
  22175. * file that was distributed with this source code.
  22176. */
  22177. /**
  22178. * Represents a file in the code coverage information tree.
  22179. *
  22180. * @category PHP
  22181. * @package CodeCoverage
  22182. * @author Sebastian Bergmann <sebastian@phpunit.de>
  22183. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  22184. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  22185. * @link http://github.com/sebastianbergmann/php-code-coverage
  22186. * @since Class available since Release 1.1.0
  22187. */
  22188. class PHP_CodeCoverage_Report_Node_File extends PHP_CodeCoverage_Report_Node
  22189. {
  22190. /**
  22191. * @var array
  22192. */
  22193. protected $coverageData;
  22194. /**
  22195. * @var array
  22196. */
  22197. protected $testData;
  22198. /**
  22199. * @var integer
  22200. */
  22201. protected $numExecutableLines = 0;
  22202. /**
  22203. * @var integer
  22204. */
  22205. protected $numExecutedLines = 0;
  22206. /**
  22207. * @var array
  22208. */
  22209. protected $classes = array();
  22210. /**
  22211. * @var array
  22212. */
  22213. protected $traits = array();
  22214. /**
  22215. * @var array
  22216. */
  22217. protected $functions = array();
  22218. /**
  22219. * @var array
  22220. */
  22221. protected $linesOfCode = array();
  22222. /**
  22223. * @var integer
  22224. */
  22225. protected $numTestedTraits = 0;
  22226. /**
  22227. * @var integer
  22228. */
  22229. protected $numTestedClasses = 0;
  22230. /**
  22231. * @var integer
  22232. */
  22233. protected $numMethods = null;
  22234. /**
  22235. * @var integer
  22236. */
  22237. protected $numTestedMethods = null;
  22238. /**
  22239. * @var integer
  22240. */
  22241. protected $numTestedFunctions = null;
  22242. /**
  22243. * @var array
  22244. */
  22245. protected $startLines = array();
  22246. /**
  22247. * @var array
  22248. */
  22249. protected $endLines = array();
  22250. /**
  22251. * @var boolean
  22252. */
  22253. protected $cacheTokens;
  22254. /**
  22255. * Constructor.
  22256. *
  22257. * @param string $name
  22258. * @param PHP_CodeCoverage_Report_Node $parent
  22259. * @param array $coverageData
  22260. * @param array $testData
  22261. * @param boolean $cacheTokens
  22262. * @throws PHP_CodeCoverage_Exception
  22263. */
  22264. public function __construct($name, PHP_CodeCoverage_Report_Node $parent, array $coverageData, array $testData, $cacheTokens)
  22265. {
  22266. if (!is_bool($cacheTokens)) {
  22267. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  22268. 1,
  22269. 'boolean'
  22270. );
  22271. }
  22272. parent::__construct($name, $parent);
  22273. $this->coverageData = $coverageData;
  22274. $this->testData = $testData;
  22275. $this->cacheTokens = $cacheTokens;
  22276. $this->calculateStatistics();
  22277. }
  22278. /**
  22279. * Returns the number of files in/under this node.
  22280. *
  22281. * @return integer
  22282. */
  22283. public function count()
  22284. {
  22285. return 1;
  22286. }
  22287. /**
  22288. * Returns the code coverage data of this node.
  22289. *
  22290. * @return array
  22291. */
  22292. public function getCoverageData()
  22293. {
  22294. return $this->coverageData;
  22295. }
  22296. /**
  22297. * Returns the test data of this node.
  22298. *
  22299. * @return array
  22300. */
  22301. public function getTestData()
  22302. {
  22303. return $this->testData;
  22304. }
  22305. /**
  22306. * Returns the classes of this node.
  22307. *
  22308. * @return array
  22309. */
  22310. public function getClasses()
  22311. {
  22312. return $this->classes;
  22313. }
  22314. /**
  22315. * Returns the traits of this node.
  22316. *
  22317. * @return array
  22318. */
  22319. public function getTraits()
  22320. {
  22321. return $this->traits;
  22322. }
  22323. /**
  22324. * Returns the functions of this node.
  22325. *
  22326. * @return array
  22327. */
  22328. public function getFunctions()
  22329. {
  22330. return $this->functions;
  22331. }
  22332. /**
  22333. * Returns the LOC/CLOC/NCLOC of this node.
  22334. *
  22335. * @return array
  22336. */
  22337. public function getLinesOfCode()
  22338. {
  22339. return $this->linesOfCode;
  22340. }
  22341. /**
  22342. * Returns the number of executable lines.
  22343. *
  22344. * @return integer
  22345. */
  22346. public function getNumExecutableLines()
  22347. {
  22348. return $this->numExecutableLines;
  22349. }
  22350. /**
  22351. * Returns the number of executed lines.
  22352. *
  22353. * @return integer
  22354. */
  22355. public function getNumExecutedLines()
  22356. {
  22357. return $this->numExecutedLines;
  22358. }
  22359. /**
  22360. * Returns the number of classes.
  22361. *
  22362. * @return integer
  22363. */
  22364. public function getNumClasses()
  22365. {
  22366. return count($this->classes);
  22367. }
  22368. /**
  22369. * Returns the number of tested classes.
  22370. *
  22371. * @return integer
  22372. */
  22373. public function getNumTestedClasses()
  22374. {
  22375. return $this->numTestedClasses;
  22376. }
  22377. /**
  22378. * Returns the number of traits.
  22379. *
  22380. * @return integer
  22381. */
  22382. public function getNumTraits()
  22383. {
  22384. return count($this->traits);
  22385. }
  22386. /**
  22387. * Returns the number of tested traits.
  22388. *
  22389. * @return integer
  22390. */
  22391. public function getNumTestedTraits()
  22392. {
  22393. return $this->numTestedTraits;
  22394. }
  22395. /**
  22396. * Returns the number of methods.
  22397. *
  22398. * @return integer
  22399. */
  22400. public function getNumMethods()
  22401. {
  22402. if ($this->numMethods === null) {
  22403. $this->numMethods = 0;
  22404. foreach ($this->classes as $class) {
  22405. foreach ($class['methods'] as $method) {
  22406. if ($method['executableLines'] > 0) {
  22407. $this->numMethods++;
  22408. }
  22409. }
  22410. }
  22411. foreach ($this->traits as $trait) {
  22412. foreach ($trait['methods'] as $method) {
  22413. if ($method['executableLines'] > 0) {
  22414. $this->numMethods++;
  22415. }
  22416. }
  22417. }
  22418. }
  22419. return $this->numMethods;
  22420. }
  22421. /**
  22422. * Returns the number of tested methods.
  22423. *
  22424. * @return integer
  22425. */
  22426. public function getNumTestedMethods()
  22427. {
  22428. if ($this->numTestedMethods === null) {
  22429. $this->numTestedMethods = 0;
  22430. foreach ($this->classes as $class) {
  22431. foreach ($class['methods'] as $method) {
  22432. if ($method['executableLines'] > 0 &&
  22433. $method['coverage'] == 100) {
  22434. $this->numTestedMethods++;
  22435. }
  22436. }
  22437. }
  22438. foreach ($this->traits as $trait) {
  22439. foreach ($trait['methods'] as $method) {
  22440. if ($method['executableLines'] > 0 &&
  22441. $method['coverage'] == 100) {
  22442. $this->numTestedMethods++;
  22443. }
  22444. }
  22445. }
  22446. }
  22447. return $this->numTestedMethods;
  22448. }
  22449. /**
  22450. * Returns the number of functions.
  22451. *
  22452. * @return integer
  22453. */
  22454. public function getNumFunctions()
  22455. {
  22456. return count($this->functions);
  22457. }
  22458. /**
  22459. * Returns the number of tested functions.
  22460. *
  22461. * @return integer
  22462. */
  22463. public function getNumTestedFunctions()
  22464. {
  22465. if ($this->numTestedFunctions === null) {
  22466. $this->numTestedFunctions = 0;
  22467. foreach ($this->functions as $function) {
  22468. if ($function['executableLines'] > 0 &&
  22469. $function['coverage'] == 100) {
  22470. $this->numTestedFunctions++;
  22471. }
  22472. }
  22473. }
  22474. return $this->numTestedFunctions;
  22475. }
  22476. /**
  22477. * Calculates coverage statistics for the file.
  22478. */
  22479. protected function calculateStatistics()
  22480. {
  22481. if ($this->cacheTokens) {
  22482. $tokens = PHP_Token_Stream_CachingFactory::get($this->getPath());
  22483. } else {
  22484. $tokens = new PHP_Token_Stream($this->getPath());
  22485. }
  22486. $this->processClasses($tokens);
  22487. $this->processTraits($tokens);
  22488. $this->processFunctions($tokens);
  22489. $this->linesOfCode = $tokens->getLinesOfCode();
  22490. unset($tokens);
  22491. for ($lineNumber = 1; $lineNumber <= $this->linesOfCode['loc']; $lineNumber++) {
  22492. if (isset($this->startLines[$lineNumber])) {
  22493. // Start line of a class.
  22494. if (isset($this->startLines[$lineNumber]['className'])) {
  22495. $currentClass = &$this->startLines[$lineNumber];
  22496. } // Start line of a trait.
  22497. elseif (isset($this->startLines[$lineNumber]['traitName'])) {
  22498. $currentTrait = &$this->startLines[$lineNumber];
  22499. } // Start line of a method.
  22500. elseif (isset($this->startLines[$lineNumber]['methodName'])) {
  22501. $currentMethod = &$this->startLines[$lineNumber];
  22502. } // Start line of a function.
  22503. elseif (isset($this->startLines[$lineNumber]['functionName'])) {
  22504. $currentFunction = &$this->startLines[$lineNumber];
  22505. }
  22506. }
  22507. if (isset($this->coverageData[$lineNumber]) &&
  22508. $this->coverageData[$lineNumber] !== null) {
  22509. if (isset($currentClass)) {
  22510. $currentClass['executableLines']++;
  22511. }
  22512. if (isset($currentTrait)) {
  22513. $currentTrait['executableLines']++;
  22514. }
  22515. if (isset($currentMethod)) {
  22516. $currentMethod['executableLines']++;
  22517. }
  22518. if (isset($currentFunction)) {
  22519. $currentFunction['executableLines']++;
  22520. }
  22521. $this->numExecutableLines++;
  22522. if (count($this->coverageData[$lineNumber]) > 0) {
  22523. if (isset($currentClass)) {
  22524. $currentClass['executedLines']++;
  22525. }
  22526. if (isset($currentTrait)) {
  22527. $currentTrait['executedLines']++;
  22528. }
  22529. if (isset($currentMethod)) {
  22530. $currentMethod['executedLines']++;
  22531. }
  22532. if (isset($currentFunction)) {
  22533. $currentFunction['executedLines']++;
  22534. }
  22535. $this->numExecutedLines++;
  22536. }
  22537. }
  22538. if (isset($this->endLines[$lineNumber])) {
  22539. // End line of a class.
  22540. if (isset($this->endLines[$lineNumber]['className'])) {
  22541. unset($currentClass);
  22542. } // End line of a trait.
  22543. elseif (isset($this->endLines[$lineNumber]['traitName'])) {
  22544. unset($currentTrait);
  22545. } // End line of a method.
  22546. elseif (isset($this->endLines[$lineNumber]['methodName'])) {
  22547. unset($currentMethod);
  22548. } // End line of a function.
  22549. elseif (isset($this->endLines[$lineNumber]['functionName'])) {
  22550. unset($currentFunction);
  22551. }
  22552. }
  22553. }
  22554. foreach ($this->traits as &$trait) {
  22555. foreach ($trait['methods'] as &$method) {
  22556. if ($method['executableLines'] > 0) {
  22557. $method['coverage'] = ($method['executedLines'] /
  22558. $method['executableLines']) * 100;
  22559. } else {
  22560. $method['coverage'] = 100;
  22561. }
  22562. $method['crap'] = $this->crap(
  22563. $method['ccn'],
  22564. $method['coverage']
  22565. );
  22566. $trait['ccn'] += $method['ccn'];
  22567. }
  22568. if ($trait['executableLines'] > 0) {
  22569. $trait['coverage'] = ($trait['executedLines'] /
  22570. $trait['executableLines']) * 100;
  22571. } else {
  22572. $trait['coverage'] = 100;
  22573. }
  22574. if ($trait['coverage'] == 100) {
  22575. $this->numTestedClasses++;
  22576. }
  22577. $trait['crap'] = $this->crap(
  22578. $trait['ccn'],
  22579. $trait['coverage']
  22580. );
  22581. }
  22582. foreach ($this->classes as &$class) {
  22583. foreach ($class['methods'] as &$method) {
  22584. if ($method['executableLines'] > 0) {
  22585. $method['coverage'] = ($method['executedLines'] /
  22586. $method['executableLines']) * 100;
  22587. } else {
  22588. $method['coverage'] = 100;
  22589. }
  22590. $method['crap'] = $this->crap(
  22591. $method['ccn'],
  22592. $method['coverage']
  22593. );
  22594. $class['ccn'] += $method['ccn'];
  22595. }
  22596. if ($class['executableLines'] > 0) {
  22597. $class['coverage'] = ($class['executedLines'] /
  22598. $class['executableLines']) * 100;
  22599. } else {
  22600. $class['coverage'] = 100;
  22601. }
  22602. if ($class['coverage'] == 100) {
  22603. $this->numTestedClasses++;
  22604. }
  22605. $class['crap'] = $this->crap(
  22606. $class['ccn'],
  22607. $class['coverage']
  22608. );
  22609. }
  22610. }
  22611. /**
  22612. * @param PHP_Token_Stream $tokens
  22613. */
  22614. protected function processClasses(PHP_Token_Stream $tokens)
  22615. {
  22616. $classes = $tokens->getClasses();
  22617. unset($tokens);
  22618. $link = $this->getId() . '.html#';
  22619. foreach ($classes as $className => $class) {
  22620. $this->classes[$className] = array(
  22621. 'className' => $className,
  22622. 'methods' => array(),
  22623. 'startLine' => $class['startLine'],
  22624. 'executableLines' => 0,
  22625. 'executedLines' => 0,
  22626. 'ccn' => 0,
  22627. 'coverage' => 0,
  22628. 'crap' => 0,
  22629. 'package' => $class['package'],
  22630. 'link' => $link . $class['startLine']
  22631. );
  22632. $this->startLines[$class['startLine']] = &$this->classes[$className];
  22633. $this->endLines[$class['endLine']] = &$this->classes[$className];
  22634. foreach ($class['methods'] as $methodName => $method) {
  22635. $this->classes[$className]['methods'][$methodName] = array(
  22636. 'methodName' => $methodName,
  22637. 'signature' => $method['signature'],
  22638. 'startLine' => $method['startLine'],
  22639. 'endLine' => $method['endLine'],
  22640. 'executableLines' => 0,
  22641. 'executedLines' => 0,
  22642. 'ccn' => $method['ccn'],
  22643. 'coverage' => 0,
  22644. 'crap' => 0,
  22645. 'link' => $link . $method['startLine']
  22646. );
  22647. $this->startLines[$method['startLine']] = &$this->classes[$className]['methods'][$methodName];
  22648. $this->endLines[$method['endLine']] = &$this->classes[$className]['methods'][$methodName];
  22649. }
  22650. }
  22651. }
  22652. /**
  22653. * @param PHP_Token_Stream $tokens
  22654. */
  22655. protected function processTraits(PHP_Token_Stream $tokens)
  22656. {
  22657. $traits = $tokens->getTraits();
  22658. unset($tokens);
  22659. $link = $this->getId() . '.html#';
  22660. foreach ($traits as $traitName => $trait) {
  22661. $this->traits[$traitName] = array(
  22662. 'traitName' => $traitName,
  22663. 'methods' => array(),
  22664. 'startLine' => $trait['startLine'],
  22665. 'executableLines' => 0,
  22666. 'executedLines' => 0,
  22667. 'ccn' => 0,
  22668. 'coverage' => 0,
  22669. 'crap' => 0,
  22670. 'package' => $trait['package'],
  22671. 'link' => $link . $trait['startLine']
  22672. );
  22673. $this->startLines[$trait['startLine']] = &$this->traits[$traitName];
  22674. $this->endLines[$trait['endLine']] = &$this->traits[$traitName];
  22675. foreach ($trait['methods'] as $methodName => $method) {
  22676. $this->traits[$traitName]['methods'][$methodName] = array(
  22677. 'methodName' => $methodName,
  22678. 'signature' => $method['signature'],
  22679. 'startLine' => $method['startLine'],
  22680. 'endLine' => $method['endLine'],
  22681. 'executableLines' => 0,
  22682. 'executedLines' => 0,
  22683. 'ccn' => $method['ccn'],
  22684. 'coverage' => 0,
  22685. 'crap' => 0,
  22686. 'link' => $link . $method['startLine']
  22687. );
  22688. $this->startLines[$method['startLine']] = &$this->traits[$traitName]['methods'][$methodName];
  22689. $this->endLines[$method['endLine']] = &$this->traits[$traitName]['methods'][$methodName];
  22690. }
  22691. }
  22692. }
  22693. /**
  22694. * @param PHP_Token_Stream $tokens
  22695. */
  22696. protected function processFunctions(PHP_Token_Stream $tokens)
  22697. {
  22698. $functions = $tokens->getFunctions();
  22699. unset($tokens);
  22700. $link = $this->getId() . '.html#';
  22701. foreach ($functions as $functionName => $function) {
  22702. $this->functions[$functionName] = array(
  22703. 'functionName' => $functionName,
  22704. 'signature' => $function['signature'],
  22705. 'startLine' => $function['startLine'],
  22706. 'executableLines' => 0,
  22707. 'executedLines' => 0,
  22708. 'ccn' => $function['ccn'],
  22709. 'coverage' => 0,
  22710. 'crap' => 0,
  22711. 'link' => $link . $function['startLine']
  22712. );
  22713. $this->startLines[$function['startLine']] = &$this->functions[$functionName];
  22714. $this->endLines[$function['endLine']] = &$this->functions[$functionName];
  22715. }
  22716. }
  22717. /**
  22718. * Calculates the Change Risk Anti-Patterns (CRAP) index for a unit of code
  22719. * based on its cyclomatic complexity and percentage of code coverage.
  22720. *
  22721. * @param integer $ccn
  22722. * @param float $coverage
  22723. * @return string
  22724. * @since Method available since Release 1.2.0
  22725. */
  22726. protected function crap($ccn, $coverage)
  22727. {
  22728. if ($coverage == 0) {
  22729. return (string) (pow($ccn, 2) + $ccn);
  22730. }
  22731. if ($coverage >= 95) {
  22732. return (string) $ccn;
  22733. }
  22734. return sprintf(
  22735. '%01.2F',
  22736. pow($ccn, 2) * pow(1 - $coverage/100, 3) + $ccn
  22737. );
  22738. }
  22739. }
  22740. <?php
  22741. /*
  22742. * This file is part of the PHP_CodeCoverage package.
  22743. *
  22744. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  22745. *
  22746. * For the full copyright and license information, please view the LICENSE
  22747. * file that was distributed with this source code.
  22748. */
  22749. /**
  22750. * Represents a directory in the code coverage information tree.
  22751. *
  22752. * @category PHP
  22753. * @package CodeCoverage
  22754. * @author Sebastian Bergmann <sebastian@phpunit.de>
  22755. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  22756. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  22757. * @link http://github.com/sebastianbergmann/php-code-coverage
  22758. * @since Class available since Release 1.1.0
  22759. */
  22760. class PHP_CodeCoverage_Report_Node_Directory extends PHP_CodeCoverage_Report_Node implements IteratorAggregate
  22761. {
  22762. /**
  22763. * @var PHP_CodeCoverage_Report_Node[]
  22764. */
  22765. protected $children = array();
  22766. /**
  22767. * @var PHP_CodeCoverage_Report_Node_Directory[]
  22768. */
  22769. protected $directories = array();
  22770. /**
  22771. * @var PHP_CodeCoverage_Report_Node_File[]
  22772. */
  22773. protected $files = array();
  22774. /**
  22775. * @var array
  22776. */
  22777. protected $classes;
  22778. /**
  22779. * @var array
  22780. */
  22781. protected $traits;
  22782. /**
  22783. * @var array
  22784. */
  22785. protected $functions;
  22786. /**
  22787. * @var array
  22788. */
  22789. protected $linesOfCode = null;
  22790. /**
  22791. * @var integer
  22792. */
  22793. protected $numFiles = -1;
  22794. /**
  22795. * @var integer
  22796. */
  22797. protected $numExecutableLines = -1;
  22798. /**
  22799. * @var integer
  22800. */
  22801. protected $numExecutedLines = -1;
  22802. /**
  22803. * @var integer
  22804. */
  22805. protected $numClasses = -1;
  22806. /**
  22807. * @var integer
  22808. */
  22809. protected $numTestedClasses = -1;
  22810. /**
  22811. * @var integer
  22812. */
  22813. protected $numTraits = -1;
  22814. /**
  22815. * @var integer
  22816. */
  22817. protected $numTestedTraits = -1;
  22818. /**
  22819. * @var integer
  22820. */
  22821. protected $numMethods = -1;
  22822. /**
  22823. * @var integer
  22824. */
  22825. protected $numTestedMethods = -1;
  22826. /**
  22827. * @var integer
  22828. */
  22829. protected $numFunctions = -1;
  22830. /**
  22831. * @var integer
  22832. */
  22833. protected $numTestedFunctions = -1;
  22834. /**
  22835. * Returns the number of files in/under this node.
  22836. *
  22837. * @return integer
  22838. */
  22839. public function count()
  22840. {
  22841. if ($this->numFiles == -1) {
  22842. $this->numFiles = 0;
  22843. foreach ($this->children as $child) {
  22844. $this->numFiles += count($child);
  22845. }
  22846. }
  22847. return $this->numFiles;
  22848. }
  22849. /**
  22850. * Returns an iterator for this node.
  22851. *
  22852. * @return RecursiveIteratorIterator
  22853. */
  22854. public function getIterator()
  22855. {
  22856. return new RecursiveIteratorIterator(
  22857. new PHP_CodeCoverage_Report_Node_Iterator($this),
  22858. RecursiveIteratorIterator::SELF_FIRST
  22859. );
  22860. }
  22861. /**
  22862. * Adds a new directory.
  22863. *
  22864. * @param string $name
  22865. * @return PHP_CodeCoverage_Report_Node_Directory
  22866. */
  22867. public function addDirectory($name)
  22868. {
  22869. $directory = new PHP_CodeCoverage_Report_Node_Directory($name, $this);
  22870. $this->children[] = $directory;
  22871. $this->directories[] = &$this->children[count($this->children) - 1];
  22872. return $directory;
  22873. }
  22874. /**
  22875. * Adds a new file.
  22876. *
  22877. * @param string $name
  22878. * @param array $coverageData
  22879. * @param array $testData
  22880. * @param boolean $cacheTokens
  22881. * @return PHP_CodeCoverage_Report_Node_File
  22882. * @throws PHP_CodeCoverage_Exception
  22883. */
  22884. public function addFile($name, array $coverageData, array $testData, $cacheTokens)
  22885. {
  22886. $file = new PHP_CodeCoverage_Report_Node_File(
  22887. $name,
  22888. $this,
  22889. $coverageData,
  22890. $testData,
  22891. $cacheTokens
  22892. );
  22893. $this->children[] = $file;
  22894. $this->files[] = &$this->children[count($this->children) - 1];
  22895. $this->numExecutableLines = -1;
  22896. $this->numExecutedLines = -1;
  22897. return $file;
  22898. }
  22899. /**
  22900. * Returns the directories in this directory.
  22901. *
  22902. * @return array
  22903. */
  22904. public function getDirectories()
  22905. {
  22906. return $this->directories;
  22907. }
  22908. /**
  22909. * Returns the files in this directory.
  22910. *
  22911. * @return array
  22912. */
  22913. public function getFiles()
  22914. {
  22915. return $this->files;
  22916. }
  22917. /**
  22918. * Returns the child nodes of this node.
  22919. *
  22920. * @return array
  22921. */
  22922. public function getChildNodes()
  22923. {
  22924. return $this->children;
  22925. }
  22926. /**
  22927. * Returns the classes of this node.
  22928. *
  22929. * @return array
  22930. */
  22931. public function getClasses()
  22932. {
  22933. if ($this->classes === null) {
  22934. $this->classes = array();
  22935. foreach ($this->children as $child) {
  22936. $this->classes = array_merge(
  22937. $this->classes,
  22938. $child->getClasses()
  22939. );
  22940. }
  22941. }
  22942. return $this->classes;
  22943. }
  22944. /**
  22945. * Returns the traits of this node.
  22946. *
  22947. * @return array
  22948. */
  22949. public function getTraits()
  22950. {
  22951. if ($this->traits === null) {
  22952. $this->traits = array();
  22953. foreach ($this->children as $child) {
  22954. $this->traits = array_merge(
  22955. $this->traits,
  22956. $child->getTraits()
  22957. );
  22958. }
  22959. }
  22960. return $this->traits;
  22961. }
  22962. /**
  22963. * Returns the functions of this node.
  22964. *
  22965. * @return array
  22966. */
  22967. public function getFunctions()
  22968. {
  22969. if ($this->functions === null) {
  22970. $this->functions = array();
  22971. foreach ($this->children as $child) {
  22972. $this->functions = array_merge(
  22973. $this->functions,
  22974. $child->getFunctions()
  22975. );
  22976. }
  22977. }
  22978. return $this->functions;
  22979. }
  22980. /**
  22981. * Returns the LOC/CLOC/NCLOC of this node.
  22982. *
  22983. * @return array
  22984. */
  22985. public function getLinesOfCode()
  22986. {
  22987. if ($this->linesOfCode === null) {
  22988. $this->linesOfCode = array('loc' => 0, 'cloc' => 0, 'ncloc' => 0);
  22989. foreach ($this->children as $child) {
  22990. $linesOfCode = $child->getLinesOfCode();
  22991. $this->linesOfCode['loc'] += $linesOfCode['loc'];
  22992. $this->linesOfCode['cloc'] += $linesOfCode['cloc'];
  22993. $this->linesOfCode['ncloc'] += $linesOfCode['ncloc'];
  22994. }
  22995. }
  22996. return $this->linesOfCode;
  22997. }
  22998. /**
  22999. * Returns the number of executable lines.
  23000. *
  23001. * @return integer
  23002. */
  23003. public function getNumExecutableLines()
  23004. {
  23005. if ($this->numExecutableLines == -1) {
  23006. $this->numExecutableLines = 0;
  23007. foreach ($this->children as $child) {
  23008. $this->numExecutableLines += $child->getNumExecutableLines();
  23009. }
  23010. }
  23011. return $this->numExecutableLines;
  23012. }
  23013. /**
  23014. * Returns the number of executed lines.
  23015. *
  23016. * @return integer
  23017. */
  23018. public function getNumExecutedLines()
  23019. {
  23020. if ($this->numExecutedLines == -1) {
  23021. $this->numExecutedLines = 0;
  23022. foreach ($this->children as $child) {
  23023. $this->numExecutedLines += $child->getNumExecutedLines();
  23024. }
  23025. }
  23026. return $this->numExecutedLines;
  23027. }
  23028. /**
  23029. * Returns the number of classes.
  23030. *
  23031. * @return integer
  23032. */
  23033. public function getNumClasses()
  23034. {
  23035. if ($this->numClasses == -1) {
  23036. $this->numClasses = 0;
  23037. foreach ($this->children as $child) {
  23038. $this->numClasses += $child->getNumClasses();
  23039. }
  23040. }
  23041. return $this->numClasses;
  23042. }
  23043. /**
  23044. * Returns the number of tested classes.
  23045. *
  23046. * @return integer
  23047. */
  23048. public function getNumTestedClasses()
  23049. {
  23050. if ($this->numTestedClasses == -1) {
  23051. $this->numTestedClasses = 0;
  23052. foreach ($this->children as $child) {
  23053. $this->numTestedClasses += $child->getNumTestedClasses();
  23054. }
  23055. }
  23056. return $this->numTestedClasses;
  23057. }
  23058. /**
  23059. * Returns the number of traits.
  23060. *
  23061. * @return integer
  23062. */
  23063. public function getNumTraits()
  23064. {
  23065. if ($this->numTraits == -1) {
  23066. $this->numTraits = 0;
  23067. foreach ($this->children as $child) {
  23068. $this->numTraits += $child->getNumTraits();
  23069. }
  23070. }
  23071. return $this->numTraits;
  23072. }
  23073. /**
  23074. * Returns the number of tested traits.
  23075. *
  23076. * @return integer
  23077. */
  23078. public function getNumTestedTraits()
  23079. {
  23080. if ($this->numTestedTraits == -1) {
  23081. $this->numTestedTraits = 0;
  23082. foreach ($this->children as $child) {
  23083. $this->numTestedTraits += $child->getNumTestedTraits();
  23084. }
  23085. }
  23086. return $this->numTestedTraits;
  23087. }
  23088. /**
  23089. * Returns the number of methods.
  23090. *
  23091. * @return integer
  23092. */
  23093. public function getNumMethods()
  23094. {
  23095. if ($this->numMethods == -1) {
  23096. $this->numMethods = 0;
  23097. foreach ($this->children as $child) {
  23098. $this->numMethods += $child->getNumMethods();
  23099. }
  23100. }
  23101. return $this->numMethods;
  23102. }
  23103. /**
  23104. * Returns the number of tested methods.
  23105. *
  23106. * @return integer
  23107. */
  23108. public function getNumTestedMethods()
  23109. {
  23110. if ($this->numTestedMethods == -1) {
  23111. $this->numTestedMethods = 0;
  23112. foreach ($this->children as $child) {
  23113. $this->numTestedMethods += $child->getNumTestedMethods();
  23114. }
  23115. }
  23116. return $this->numTestedMethods;
  23117. }
  23118. /**
  23119. * Returns the number of functions.
  23120. *
  23121. * @return integer
  23122. */
  23123. public function getNumFunctions()
  23124. {
  23125. if ($this->numFunctions == -1) {
  23126. $this->numFunctions = 0;
  23127. foreach ($this->children as $child) {
  23128. $this->numFunctions += $child->getNumFunctions();
  23129. }
  23130. }
  23131. return $this->numFunctions;
  23132. }
  23133. /**
  23134. * Returns the number of tested functions.
  23135. *
  23136. * @return integer
  23137. */
  23138. public function getNumTestedFunctions()
  23139. {
  23140. if ($this->numTestedFunctions == -1) {
  23141. $this->numTestedFunctions = 0;
  23142. foreach ($this->children as $child) {
  23143. $this->numTestedFunctions += $child->getNumTestedFunctions();
  23144. }
  23145. }
  23146. return $this->numTestedFunctions;
  23147. }
  23148. }
  23149. <?php
  23150. /*
  23151. * This file is part of the PHP_CodeCoverage package.
  23152. *
  23153. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  23154. *
  23155. * For the full copyright and license information, please view the LICENSE
  23156. * file that was distributed with this source code.
  23157. */
  23158. /**
  23159. * Generates a Clover XML logfile from an PHP_CodeCoverage object.
  23160. *
  23161. * @category PHP
  23162. * @package CodeCoverage
  23163. * @author Sebastian Bergmann <sebastian@phpunit.de>
  23164. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  23165. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  23166. * @link http://github.com/sebastianbergmann/php-code-coverage
  23167. * @since Class available since Release 1.0.0
  23168. */
  23169. class PHP_CodeCoverage_Report_Clover
  23170. {
  23171. /**
  23172. * @param PHP_CodeCoverage $coverage
  23173. * @param string $target
  23174. * @param string $name
  23175. * @return string
  23176. */
  23177. public function process(PHP_CodeCoverage $coverage, $target = null, $name = null)
  23178. {
  23179. $xmlDocument = new DOMDocument('1.0', 'UTF-8');
  23180. $xmlDocument->formatOutput = true;
  23181. $xmlCoverage = $xmlDocument->createElement('coverage');
  23182. $xmlCoverage->setAttribute('generated', (int) $_SERVER['REQUEST_TIME']);
  23183. $xmlDocument->appendChild($xmlCoverage);
  23184. $xmlProject = $xmlDocument->createElement('project');
  23185. $xmlProject->setAttribute('timestamp', (int) $_SERVER['REQUEST_TIME']);
  23186. if (is_string($name)) {
  23187. $xmlProject->setAttribute('name', $name);
  23188. }
  23189. $xmlCoverage->appendChild($xmlProject);
  23190. $packages = array();
  23191. $report = $coverage->getReport();
  23192. unset($coverage);
  23193. foreach ($report as $item) {
  23194. $namespace = 'global';
  23195. if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
  23196. continue;
  23197. }
  23198. $xmlFile = $xmlDocument->createElement('file');
  23199. $xmlFile->setAttribute('name', $item->getPath());
  23200. $classes = $item->getClassesAndTraits();
  23201. $coverage = $item->getCoverageData();
  23202. $lines = array();
  23203. foreach ($classes as $className => $class) {
  23204. $classStatements = 0;
  23205. $coveredClassStatements = 0;
  23206. $coveredMethods = 0;
  23207. $classMethods = 0;
  23208. foreach ($class['methods'] as $methodName => $method) {
  23209. if ($method['executableLines'] == 0) {
  23210. continue;
  23211. }
  23212. $classMethods++;
  23213. $classStatements += $method['executableLines'];
  23214. $coveredClassStatements += $method['executedLines'];
  23215. if ($method['coverage'] == 100) {
  23216. $coveredMethods++;
  23217. }
  23218. $methodCount = 0;
  23219. for ($i = $method['startLine'];
  23220. $i <= $method['endLine'];
  23221. $i++) {
  23222. if (isset($coverage[$i]) && ($coverage[$i] !== null)) {
  23223. $methodCount = max($methodCount, count($coverage[$i]));
  23224. }
  23225. }
  23226. $lines[$method['startLine']] = array(
  23227. 'count' => $methodCount,
  23228. 'crap' => $method['crap'],
  23229. 'type' => 'method',
  23230. 'name' => $methodName
  23231. );
  23232. }
  23233. if (!empty($class['package']['namespace'])) {
  23234. $namespace = $class['package']['namespace'];
  23235. }
  23236. $xmlClass = $xmlDocument->createElement('class');
  23237. $xmlClass->setAttribute('name', $className);
  23238. $xmlClass->setAttribute('namespace', $namespace);
  23239. if (!empty($class['package']['fullPackage'])) {
  23240. $xmlClass->setAttribute(
  23241. 'fullPackage',
  23242. $class['package']['fullPackage']
  23243. );
  23244. }
  23245. if (!empty($class['package']['category'])) {
  23246. $xmlClass->setAttribute(
  23247. 'category',
  23248. $class['package']['category']
  23249. );
  23250. }
  23251. if (!empty($class['package']['package'])) {
  23252. $xmlClass->setAttribute(
  23253. 'package',
  23254. $class['package']['package']
  23255. );
  23256. }
  23257. if (!empty($class['package']['subpackage'])) {
  23258. $xmlClass->setAttribute(
  23259. 'subpackage',
  23260. $class['package']['subpackage']
  23261. );
  23262. }
  23263. $xmlFile->appendChild($xmlClass);
  23264. $xmlMetrics = $xmlDocument->createElement('metrics');
  23265. $xmlMetrics->setAttribute('methods', $classMethods);
  23266. $xmlMetrics->setAttribute('coveredmethods', $coveredMethods);
  23267. $xmlMetrics->setAttribute('conditionals', 0);
  23268. $xmlMetrics->setAttribute('coveredconditionals', 0);
  23269. $xmlMetrics->setAttribute('statements', $classStatements);
  23270. $xmlMetrics->setAttribute(
  23271. 'coveredstatements',
  23272. $coveredClassStatements
  23273. );
  23274. $xmlMetrics->setAttribute(
  23275. 'elements',
  23276. $classMethods +
  23277. $classStatements
  23278. /* + conditionals */
  23279. );
  23280. $xmlMetrics->setAttribute(
  23281. 'coveredelements',
  23282. $coveredMethods +
  23283. $coveredClassStatements
  23284. /* + coveredconditionals */
  23285. );
  23286. $xmlClass->appendChild($xmlMetrics);
  23287. }
  23288. foreach ($coverage as $line => $data) {
  23289. if ($data === null || isset($lines[$line])) {
  23290. continue;
  23291. }
  23292. $lines[$line] = array(
  23293. 'count' => count($data), 'type' => 'stmt'
  23294. );
  23295. }
  23296. ksort($lines);
  23297. foreach ($lines as $line => $data) {
  23298. $xmlLine = $xmlDocument->createElement('line');
  23299. $xmlLine->setAttribute('num', $line);
  23300. $xmlLine->setAttribute('type', $data['type']);
  23301. if (isset($data['name'])) {
  23302. $xmlLine->setAttribute('name', $data['name']);
  23303. }
  23304. if (isset($data['crap'])) {
  23305. $xmlLine->setAttribute('crap', $data['crap']);
  23306. }
  23307. $xmlLine->setAttribute('count', $data['count']);
  23308. $xmlFile->appendChild($xmlLine);
  23309. }
  23310. $linesOfCode = $item->getLinesOfCode();
  23311. $xmlMetrics = $xmlDocument->createElement('metrics');
  23312. $xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
  23313. $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
  23314. $xmlMetrics->setAttribute('classes', $item->getNumClassesAndTraits());
  23315. $xmlMetrics->setAttribute('methods', $item->getNumMethods());
  23316. $xmlMetrics->setAttribute(
  23317. 'coveredmethods',
  23318. $item->getNumTestedMethods()
  23319. );
  23320. $xmlMetrics->setAttribute('conditionals', 0);
  23321. $xmlMetrics->setAttribute('coveredconditionals', 0);
  23322. $xmlMetrics->setAttribute(
  23323. 'statements',
  23324. $item->getNumExecutableLines()
  23325. );
  23326. $xmlMetrics->setAttribute(
  23327. 'coveredstatements',
  23328. $item->getNumExecutedLines()
  23329. );
  23330. $xmlMetrics->setAttribute(
  23331. 'elements',
  23332. $item->getNumMethods() + $item->getNumExecutableLines()
  23333. /* + conditionals */
  23334. );
  23335. $xmlMetrics->setAttribute(
  23336. 'coveredelements',
  23337. $item->getNumTestedMethods() + $item->getNumExecutedLines()
  23338. /* + coveredconditionals */
  23339. );
  23340. $xmlFile->appendChild($xmlMetrics);
  23341. if ($namespace == 'global') {
  23342. $xmlProject->appendChild($xmlFile);
  23343. } else {
  23344. if (!isset($packages[$namespace])) {
  23345. $packages[$namespace] = $xmlDocument->createElement(
  23346. 'package'
  23347. );
  23348. $packages[$namespace]->setAttribute('name', $namespace);
  23349. $xmlProject->appendChild($packages[$namespace]);
  23350. }
  23351. $packages[$namespace]->appendChild($xmlFile);
  23352. }
  23353. }
  23354. $linesOfCode = $report->getLinesOfCode();
  23355. $xmlMetrics = $xmlDocument->createElement('metrics');
  23356. $xmlMetrics->setAttribute('files', count($report));
  23357. $xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
  23358. $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
  23359. $xmlMetrics->setAttribute(
  23360. 'classes',
  23361. $report->getNumClassesAndTraits()
  23362. );
  23363. $xmlMetrics->setAttribute('methods', $report->getNumMethods());
  23364. $xmlMetrics->setAttribute(
  23365. 'coveredmethods',
  23366. $report->getNumTestedMethods()
  23367. );
  23368. $xmlMetrics->setAttribute('conditionals', 0);
  23369. $xmlMetrics->setAttribute('coveredconditionals', 0);
  23370. $xmlMetrics->setAttribute(
  23371. 'statements',
  23372. $report->getNumExecutableLines()
  23373. );
  23374. $xmlMetrics->setAttribute(
  23375. 'coveredstatements',
  23376. $report->getNumExecutedLines()
  23377. );
  23378. $xmlMetrics->setAttribute(
  23379. 'elements',
  23380. $report->getNumMethods() + $report->getNumExecutableLines()
  23381. /* + conditionals */
  23382. );
  23383. $xmlMetrics->setAttribute(
  23384. 'coveredelements',
  23385. $report->getNumTestedMethods() + $report->getNumExecutedLines()
  23386. /* + coveredconditionals */
  23387. );
  23388. $xmlProject->appendChild($xmlMetrics);
  23389. if ($target !== null) {
  23390. if (!is_dir(dirname($target))) {
  23391. mkdir(dirname($target), 0777, true);
  23392. }
  23393. return $xmlDocument->save($target);
  23394. } else {
  23395. return $xmlDocument->saveXML();
  23396. }
  23397. }
  23398. }
  23399. <?php
  23400. /*
  23401. * This file is part of the PHP_CodeCoverage package.
  23402. *
  23403. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  23404. *
  23405. * For the full copyright and license information, please view the LICENSE
  23406. * file that was distributed with this source code.
  23407. */
  23408. /**
  23409. * Generates an HTML report from an PHP_CodeCoverage object.
  23410. *
  23411. * @category PHP
  23412. * @package CodeCoverage
  23413. * @author Sebastian Bergmann <sebastian@phpunit.de>
  23414. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  23415. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  23416. * @link http://github.com/sebastianbergmann/php-code-coverage
  23417. * @since Class available since Release 1.0.0
  23418. */
  23419. class PHP_CodeCoverage_Report_HTML
  23420. {
  23421. /**
  23422. * @var string
  23423. */
  23424. private $templatePath;
  23425. /**
  23426. * @var string
  23427. */
  23428. private $generator;
  23429. /**
  23430. * @var integer
  23431. */
  23432. private $lowUpperBound;
  23433. /**
  23434. * @var integer
  23435. */
  23436. private $highLowerBound;
  23437. /**
  23438. * Constructor.
  23439. *
  23440. * @param integer $lowUpperBound
  23441. * @param integer $highLowerBound
  23442. * @param string $generator
  23443. */
  23444. public function __construct($lowUpperBound = 50, $highLowerBound = 90, $generator = '')
  23445. {
  23446. $this->generator = $generator;
  23447. $this->highLowerBound = $highLowerBound;
  23448. $this->lowUpperBound = $lowUpperBound;
  23449. $this->templatePath = sprintf(
  23450. '%s%sHTML%sRenderer%sTemplate%s',
  23451. dirname(__FILE__),
  23452. DIRECTORY_SEPARATOR,
  23453. DIRECTORY_SEPARATOR,
  23454. DIRECTORY_SEPARATOR,
  23455. DIRECTORY_SEPARATOR
  23456. );
  23457. }
  23458. /**
  23459. * @param PHP_CodeCoverage $coverage
  23460. * @param string $target
  23461. */
  23462. public function process(PHP_CodeCoverage $coverage, $target)
  23463. {
  23464. $target = $this->getDirectory($target);
  23465. $report = $coverage->getReport();
  23466. unset($coverage);
  23467. if (!isset($_SERVER['REQUEST_TIME'])) {
  23468. $_SERVER['REQUEST_TIME'] = time();
  23469. }
  23470. $date = date('D M j G:i:s T Y', $_SERVER['REQUEST_TIME']);
  23471. $dashboard = new PHP_CodeCoverage_Report_HTML_Renderer_Dashboard(
  23472. $this->templatePath,
  23473. $this->generator,
  23474. $date,
  23475. $this->lowUpperBound,
  23476. $this->highLowerBound
  23477. );
  23478. $directory = new PHP_CodeCoverage_Report_HTML_Renderer_Directory(
  23479. $this->templatePath,
  23480. $this->generator,
  23481. $date,
  23482. $this->lowUpperBound,
  23483. $this->highLowerBound
  23484. );
  23485. $file = new PHP_CodeCoverage_Report_HTML_Renderer_File(
  23486. $this->templatePath,
  23487. $this->generator,
  23488. $date,
  23489. $this->lowUpperBound,
  23490. $this->highLowerBound
  23491. );
  23492. $directory->render($report, $target . 'index.html');
  23493. $dashboard->render($report, $target . 'dashboard.html');
  23494. foreach ($report as $node) {
  23495. $id = $node->getId();
  23496. if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
  23497. if (!file_exists($target . $id)) {
  23498. mkdir($target . $id, 0777, true);
  23499. }
  23500. $directory->render($node, $target . $id . '/index.html');
  23501. $dashboard->render($node, $target . $id . '/dashboard.html');
  23502. } else {
  23503. $dir = dirname($target . $id);
  23504. if (!file_exists($dir)) {
  23505. mkdir($dir, 0777, true);
  23506. }
  23507. $file->render($node, $target . $id . '.html');
  23508. }
  23509. }
  23510. $this->copyFiles($target);
  23511. }
  23512. /**
  23513. * @param string $target
  23514. */
  23515. private function copyFiles($target)
  23516. {
  23517. $dir = $this->getDirectory($target . 'css');
  23518. copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css');
  23519. copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css');
  23520. copy($this->templatePath . 'css/style.css', $dir . 'style.css');
  23521. $dir = $this->getDirectory($target . 'fonts');
  23522. copy($this->templatePath . 'fonts/glyphicons-halflings-regular.eot', $dir . 'glyphicons-halflings-regular.eot');
  23523. copy($this->templatePath . 'fonts/glyphicons-halflings-regular.svg', $dir . 'glyphicons-halflings-regular.svg');
  23524. copy($this->templatePath . 'fonts/glyphicons-halflings-regular.ttf', $dir . 'glyphicons-halflings-regular.ttf');
  23525. copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff', $dir . 'glyphicons-halflings-regular.woff');
  23526. copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff2', $dir . 'glyphicons-halflings-regular.woff2');
  23527. $dir = $this->getDirectory($target . 'js');
  23528. copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js');
  23529. copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js');
  23530. copy($this->templatePath . 'js/holder.min.js', $dir . 'holder.min.js');
  23531. copy($this->templatePath . 'js/html5shiv.min.js', $dir . 'html5shiv.min.js');
  23532. copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js');
  23533. copy($this->templatePath . 'js/nv.d3.min.js', $dir . 'nv.d3.min.js');
  23534. copy($this->templatePath . 'js/respond.min.js', $dir . 'respond.min.js');
  23535. }
  23536. /**
  23537. * @param string $directory
  23538. * @return string
  23539. * @throws PHP_CodeCoverage_Exception
  23540. * @since Method available since Release 1.2.0
  23541. */
  23542. private function getDirectory($directory)
  23543. {
  23544. if (substr($directory, -1, 1) != DIRECTORY_SEPARATOR) {
  23545. $directory .= DIRECTORY_SEPARATOR;
  23546. }
  23547. if (is_dir($directory)) {
  23548. return $directory;
  23549. }
  23550. if (@mkdir($directory, 0777, true)) {
  23551. return $directory;
  23552. }
  23553. throw new PHP_CodeCoverage_Exception(
  23554. sprintf(
  23555. 'Directory "%s" does not exist.',
  23556. $directory
  23557. )
  23558. );
  23559. }
  23560. }
  23561. <?php
  23562. /*
  23563. * This file is part of the PHP_CodeCoverage package.
  23564. *
  23565. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  23566. *
  23567. * For the full copyright and license information, please view the LICENSE
  23568. * file that was distributed with this source code.
  23569. */
  23570. /**
  23571. * Factory for PHP_CodeCoverage_Report_Node_* object graphs.
  23572. *
  23573. * @category PHP
  23574. * @package CodeCoverage
  23575. * @author Sebastian Bergmann <sebastian@phpunit.de>
  23576. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  23577. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  23578. * @link http://github.com/sebastianbergmann/php-code-coverage
  23579. * @since Class available since Release 1.1.0
  23580. */
  23581. class PHP_CodeCoverage_Report_Factory
  23582. {
  23583. /**
  23584. * @param PHP_CodeCoverage $coverage
  23585. * @return PHP_CodeCoverage_Report_Node_Directory
  23586. */
  23587. public function create(PHP_CodeCoverage $coverage)
  23588. {
  23589. $files = $coverage->getData();
  23590. $commonPath = $this->reducePaths($files);
  23591. $root = new PHP_CodeCoverage_Report_Node_Directory(
  23592. $commonPath,
  23593. null
  23594. );
  23595. $this->addItems(
  23596. $root,
  23597. $this->buildDirectoryStructure($files),
  23598. $coverage->getTests(),
  23599. $coverage->getCacheTokens()
  23600. );
  23601. return $root;
  23602. }
  23603. /**
  23604. * @param PHP_CodeCoverage_Report_Node_Directory $root
  23605. * @param array $items
  23606. * @param array $tests
  23607. * @param boolean $cacheTokens
  23608. */
  23609. private function addItems(PHP_CodeCoverage_Report_Node_Directory $root, array $items, array $tests, $cacheTokens)
  23610. {
  23611. foreach ($items as $key => $value) {
  23612. if (substr($key, -2) == '/f') {
  23613. $key = substr($key, 0, -2);
  23614. if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) {
  23615. $root->addFile($key, $value, $tests, $cacheTokens);
  23616. }
  23617. } else {
  23618. $child = $root->addDirectory($key);
  23619. $this->addItems($child, $value, $tests, $cacheTokens);
  23620. }
  23621. }
  23622. }
  23623. /**
  23624. * Builds an array representation of the directory structure.
  23625. *
  23626. * For instance,
  23627. *
  23628. * <code>
  23629. * Array
  23630. * (
  23631. * [Money.php] => Array
  23632. * (
  23633. * ...
  23634. * )
  23635. *
  23636. * [MoneyBag.php] => Array
  23637. * (
  23638. * ...
  23639. * )
  23640. * )
  23641. * </code>
  23642. *
  23643. * is transformed into
  23644. *
  23645. * <code>
  23646. * Array
  23647. * (
  23648. * [.] => Array
  23649. * (
  23650. * [Money.php] => Array
  23651. * (
  23652. * ...
  23653. * )
  23654. *
  23655. * [MoneyBag.php] => Array
  23656. * (
  23657. * ...
  23658. * )
  23659. * )
  23660. * )
  23661. * </code>
  23662. *
  23663. * @param array $files
  23664. * @return array
  23665. */
  23666. private function buildDirectoryStructure($files)
  23667. {
  23668. $result = array();
  23669. foreach ($files as $path => $file) {
  23670. $path = explode('/', $path);
  23671. $pointer = &$result;
  23672. $max = count($path);
  23673. for ($i = 0; $i < $max; $i++) {
  23674. if ($i == ($max - 1)) {
  23675. $type = '/f';
  23676. } else {
  23677. $type = '';
  23678. }
  23679. $pointer = &$pointer[$path[$i] . $type];
  23680. }
  23681. $pointer = $file;
  23682. }
  23683. return $result;
  23684. }
  23685. /**
  23686. * Reduces the paths by cutting the longest common start path.
  23687. *
  23688. * For instance,
  23689. *
  23690. * <code>
  23691. * Array
  23692. * (
  23693. * [/home/sb/Money/Money.php] => Array
  23694. * (
  23695. * ...
  23696. * )
  23697. *
  23698. * [/home/sb/Money/MoneyBag.php] => Array
  23699. * (
  23700. * ...
  23701. * )
  23702. * )
  23703. * </code>
  23704. *
  23705. * is reduced to
  23706. *
  23707. * <code>
  23708. * Array
  23709. * (
  23710. * [Money.php] => Array
  23711. * (
  23712. * ...
  23713. * )
  23714. *
  23715. * [MoneyBag.php] => Array
  23716. * (
  23717. * ...
  23718. * )
  23719. * )
  23720. * </code>
  23721. *
  23722. * @param array $files
  23723. * @return string
  23724. */
  23725. private function reducePaths(&$files)
  23726. {
  23727. if (empty($files)) {
  23728. return '.';
  23729. }
  23730. $commonPath = '';
  23731. $paths = array_keys($files);
  23732. if (count($files) == 1) {
  23733. $commonPath = dirname($paths[0]) . '/';
  23734. $files[basename($paths[0])] = $files[$paths[0]];
  23735. unset($files[$paths[0]]);
  23736. return $commonPath;
  23737. }
  23738. $max = count($paths);
  23739. for ($i = 0; $i < $max; $i++) {
  23740. // strip phar:// prefixes
  23741. if (strpos($paths[$i], 'phar://') === 0) {
  23742. $paths[$i] = substr($paths[$i], 7);
  23743. $paths[$i] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
  23744. }
  23745. $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
  23746. if (empty($paths[$i][0])) {
  23747. $paths[$i][0] = DIRECTORY_SEPARATOR;
  23748. }
  23749. }
  23750. $done = false;
  23751. $max = count($paths);
  23752. while (!$done) {
  23753. for ($i = 0; $i < $max - 1; $i++) {
  23754. if (!isset($paths[$i][0]) ||
  23755. !isset($paths[$i+1][0]) ||
  23756. $paths[$i][0] != $paths[$i+1][0]) {
  23757. $done = true;
  23758. break;
  23759. }
  23760. }
  23761. if (!$done) {
  23762. $commonPath .= $paths[0][0];
  23763. if ($paths[0][0] != DIRECTORY_SEPARATOR) {
  23764. $commonPath .= DIRECTORY_SEPARATOR;
  23765. }
  23766. for ($i = 0; $i < $max; $i++) {
  23767. array_shift($paths[$i]);
  23768. }
  23769. }
  23770. }
  23771. $original = array_keys($files);
  23772. $max = count($original);
  23773. for ($i = 0; $i < $max; $i++) {
  23774. $files[join('/', $paths[$i])] = $files[$original[$i]];
  23775. unset($files[$original[$i]]);
  23776. }
  23777. ksort($files);
  23778. return substr($commonPath, 0, -1);
  23779. }
  23780. }
  23781. <?php
  23782. /*
  23783. * This file is part of the PHP_CodeCoverage package.
  23784. *
  23785. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  23786. *
  23787. * For the full copyright and license information, please view the LICENSE
  23788. * file that was distributed with this source code.
  23789. */
  23790. /**
  23791. * @category PHP
  23792. * @package CodeCoverage
  23793. * @author Arne Blankerts <arne@blankerts.de>
  23794. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  23795. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  23796. * @link http://github.com/sebastianbergmann/php-code-coverage
  23797. * @since Class available since Release 2.0.0
  23798. */
  23799. class PHP_CodeCoverage_Report_XML
  23800. {
  23801. /**
  23802. * @var string
  23803. */
  23804. private $target;
  23805. /**
  23806. * @var PHP_CodeCoverage_Report_XML_Project
  23807. */
  23808. private $project;
  23809. public function process(PHP_CodeCoverage $coverage, $target)
  23810. {
  23811. if (substr($target, -1, 1) != DIRECTORY_SEPARATOR) {
  23812. $target .= DIRECTORY_SEPARATOR;
  23813. }
  23814. $this->target = $target;
  23815. $this->initTargetDirectory($target);
  23816. $report = $coverage->getReport();
  23817. $this->project = new PHP_CodeCoverage_Report_XML_Project(
  23818. $coverage->getReport()->getName()
  23819. );
  23820. $this->processTests($coverage->getTests());
  23821. $this->processDirectory($report, $this->project);
  23822. $index = $this->project->asDom();
  23823. $index->formatOutput = true;
  23824. $index->preserveWhiteSpace = false;
  23825. $index->save($target . '/index.xml');
  23826. }
  23827. private function initTargetDirectory($dir)
  23828. {
  23829. if (file_exists($dir)) {
  23830. if (!is_dir($dir)) {
  23831. throw new PHP_CodeCoverage_Exception(
  23832. "'$dir' exists but is not a directory."
  23833. );
  23834. }
  23835. if (!is_writable($dir)) {
  23836. throw new PHP_CodeCoverage_Exception(
  23837. "'$dir' exists but is not writable."
  23838. );
  23839. }
  23840. } elseif (!@mkdir($dir, 0777, true)) {
  23841. throw new PHP_CodeCoverage_Exception(
  23842. "'$dir' could not be created."
  23843. );
  23844. }
  23845. }
  23846. private function processDirectory(PHP_CodeCoverage_Report_Node_Directory $directory, PHP_CodeCoverage_Report_XML_Node $context)
  23847. {
  23848. $dirObject = $context->addDirectory($directory->getName());
  23849. $this->setTotals($directory, $dirObject->getTotals());
  23850. foreach ($directory as $node) {
  23851. if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
  23852. $this->processDirectory($node, $dirObject);
  23853. continue;
  23854. }
  23855. if ($node instanceof PHP_CodeCoverage_Report_Node_File) {
  23856. $this->processFile($node, $dirObject);
  23857. continue;
  23858. }
  23859. throw new PHP_CodeCoverage_Exception(
  23860. 'Unknown node type for XML report'
  23861. );
  23862. }
  23863. }
  23864. private function processFile(PHP_CodeCoverage_Report_Node_File $file, PHP_CodeCoverage_Report_XML_Directory $context)
  23865. {
  23866. $fileObject = $context->addFile(
  23867. $file->getName(),
  23868. $file->getId() . '.xml'
  23869. );
  23870. $this->setTotals($file, $fileObject->getTotals());
  23871. $fileReport = new PHP_CodeCoverage_Report_XML_File_Report(
  23872. $file->getName()
  23873. );
  23874. $this->setTotals($file, $fileReport->getTotals());
  23875. foreach ($file->getClassesAndTraits() as $unit) {
  23876. $this->processUnit($unit, $fileReport);
  23877. }
  23878. foreach ($file->getFunctions() as $function) {
  23879. $this->processFunction($function, $fileReport);
  23880. }
  23881. foreach ($file->getCoverageData() as $line => $tests) {
  23882. if (!is_array($tests) || count($tests) == 0) {
  23883. continue;
  23884. }
  23885. $coverage = $fileReport->getLineCoverage($line);
  23886. foreach ($tests as $test) {
  23887. $coverage->addTest($test);
  23888. }
  23889. $coverage->finalize();
  23890. }
  23891. $this->initTargetDirectory(
  23892. $this->target . dirname($file->getId()) . '/'
  23893. );
  23894. $fileDom = $fileReport->asDom();
  23895. $fileDom->formatOutput = true;
  23896. $fileDom->preserveWhiteSpace = false;
  23897. $fileDom->save($this->target . $file->getId() . '.xml');
  23898. }
  23899. private function processUnit($unit, PHP_CodeCoverage_Report_XML_File_Report $report)
  23900. {
  23901. if (isset($unit['className'])) {
  23902. $unitObject = $report->getClassObject($unit['className']);
  23903. } else {
  23904. $unitObject = $report->getTraitObject($unit['traitName']);
  23905. }
  23906. $unitObject->setLines(
  23907. $unit['startLine'],
  23908. $unit['executableLines'],
  23909. $unit['executedLines']
  23910. );
  23911. $unitObject->setCrap($unit['crap']);
  23912. $unitObject->setPackage(
  23913. $unit['package']['fullPackage'],
  23914. $unit['package']['package'],
  23915. $unit['package']['subpackage'],
  23916. $unit['package']['category']
  23917. );
  23918. $unitObject->setNamespace($unit['package']['namespace']);
  23919. foreach ($unit['methods'] as $method) {
  23920. $methodObject = $unitObject->addMethod($method['methodName']);
  23921. $methodObject->setSignature($method['signature']);
  23922. $methodObject->setLines($method['startLine'], $method['endLine']);
  23923. $methodObject->setCrap($method['crap']);
  23924. $methodObject->setTotals(
  23925. $method['executableLines'],
  23926. $method['executedLines'],
  23927. $method['coverage']
  23928. );
  23929. }
  23930. }
  23931. private function processFunction($function, PHP_CodeCoverage_Report_XML_File_Report $report)
  23932. {
  23933. $functionObject = $report->getFunctionObject($function['functionName']);
  23934. $functionObject->setSignature($function['signature']);
  23935. $functionObject->setLines($function['startLine']);
  23936. $functionObject->setCrap($function['crap']);
  23937. $functionObject->setTotals($function['executableLines'], $function['executedLines'], $function['coverage']);
  23938. }
  23939. private function processTests(array $tests)
  23940. {
  23941. $testsObject = $this->project->getTests();
  23942. foreach ($tests as $test => $result) {
  23943. if ($test == 'UNCOVERED_FILES_FROM_WHITELIST') {
  23944. continue;
  23945. }
  23946. $testsObject->addTest($test, $result);
  23947. }
  23948. }
  23949. private function setTotals(PHP_CodeCoverage_Report_Node $node, PHP_CodeCoverage_Report_XML_Totals $totals)
  23950. {
  23951. $loc = $node->getLinesOfCode();
  23952. $totals->setNumLines(
  23953. $loc['loc'],
  23954. $loc['cloc'],
  23955. $loc['ncloc'],
  23956. $node->getNumExecutableLines(),
  23957. $node->getNumExecutedLines()
  23958. );
  23959. $totals->setNumClasses(
  23960. $node->getNumClasses(),
  23961. $node->getNumTestedClasses()
  23962. );
  23963. $totals->setNumTraits(
  23964. $node->getNumTraits(),
  23965. $node->getNumTestedTraits()
  23966. );
  23967. $totals->setNumMethods(
  23968. $node->getNumMethods(),
  23969. $node->getNumTestedMethods()
  23970. );
  23971. $totals->setNumFunctions(
  23972. $node->getNumFunctions(),
  23973. $node->getNumTestedFunctions()
  23974. );
  23975. }
  23976. }
  23977. <?php
  23978. /*
  23979. * This file is part of the PHP_CodeCoverage package.
  23980. *
  23981. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  23982. *
  23983. * For the full copyright and license information, please view the LICENSE
  23984. * file that was distributed with this source code.
  23985. */
  23986. /**
  23987. * Uses var_export() to write a PHP_CodeCoverage object to a file.
  23988. *
  23989. * @category PHP
  23990. * @package CodeCoverage
  23991. * @author Sebastian Bergmann <sebastian@phpunit.de>
  23992. * @author uyga <iamuyga@gmail.com>
  23993. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  23994. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  23995. * @link http://github.com/sebastianbergmann/php-code-coverage
  23996. * @since Class available since Release 1.1.0
  23997. */
  23998. class PHP_CodeCoverage_Report_PHP
  23999. {
  24000. /**
  24001. * @param PHP_CodeCoverage $coverage
  24002. * @param string $target
  24003. * @return string
  24004. */
  24005. public function process(PHP_CodeCoverage $coverage, $target = null)
  24006. {
  24007. $filter = $coverage->filter();
  24008. $output = sprintf(
  24009. '<?php
  24010. $coverage = new PHP_CodeCoverage;
  24011. $coverage->setData(%s);
  24012. $coverage->setTests(%s);
  24013. $filter = $coverage->filter();
  24014. $filter->setBlacklistedFiles(%s);
  24015. $filter->setWhitelistedFiles(%s);
  24016. return $coverage;',
  24017. var_export($coverage->getData(true), 1),
  24018. var_export($coverage->getTests(), 1),
  24019. var_export($filter->getBlacklistedFiles(), 1),
  24020. var_export($filter->getWhitelistedFiles(), 1)
  24021. );
  24022. if ($target !== null) {
  24023. return file_put_contents($target, $output);
  24024. } else {
  24025. return $output;
  24026. }
  24027. }
  24028. }
  24029. <?php
  24030. /*
  24031. * This file is part of the PHP_CodeCoverage package.
  24032. *
  24033. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24034. *
  24035. * For the full copyright and license information, please view the LICENSE
  24036. * file that was distributed with this source code.
  24037. */
  24038. /**
  24039. * Generates human readable output from an PHP_CodeCoverage object.
  24040. *
  24041. * The output gets put into a text file our written to the CLI.
  24042. *
  24043. * @category PHP
  24044. * @package CodeCoverage
  24045. * @author Sebastian Bergmann <sebastian@phpunit.de>
  24046. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  24047. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  24048. * @link http://github.com/sebastianbergmann/php-code-coverage
  24049. * @since Class available since Release 1.1.0
  24050. */
  24051. class PHP_CodeCoverage_Report_Text
  24052. {
  24053. protected $lowUpperBound;
  24054. protected $highLowerBound;
  24055. protected $showUncoveredFiles;
  24056. protected $showOnlySummary;
  24057. protected $colors = array(
  24058. 'green' => "\x1b[30;42m",
  24059. 'yellow' => "\x1b[30;43m",
  24060. 'red' => "\x1b[37;41m",
  24061. 'header' => "\x1b[1;37;40m",
  24062. 'reset' => "\x1b[0m",
  24063. 'eol' => "\x1b[2K",
  24064. );
  24065. public function __construct($lowUpperBound, $highLowerBound, $showUncoveredFiles, $showOnlySummary)
  24066. {
  24067. $this->lowUpperBound = $lowUpperBound;
  24068. $this->highLowerBound = $highLowerBound;
  24069. $this->showUncoveredFiles = $showUncoveredFiles;
  24070. $this->showOnlySummary = $showOnlySummary;
  24071. }
  24072. /**
  24073. * @param PHP_CodeCoverage $coverage
  24074. * @param bool $showColors
  24075. * @return string
  24076. */
  24077. public function process(PHP_CodeCoverage $coverage, $showColors = false)
  24078. {
  24079. $output = PHP_EOL . PHP_EOL;
  24080. $report = $coverage->getReport();
  24081. unset($coverage);
  24082. $colors = array(
  24083. 'header' => '',
  24084. 'classes' => '',
  24085. 'methods' => '',
  24086. 'lines' => '',
  24087. 'reset' => '',
  24088. 'eol' => ''
  24089. );
  24090. if ($showColors) {
  24091. $colors['classes'] = $this->getCoverageColor(
  24092. $report->getNumTestedClassesAndTraits(),
  24093. $report->getNumClassesAndTraits()
  24094. );
  24095. $colors['methods'] = $this->getCoverageColor(
  24096. $report->getNumTestedMethods(),
  24097. $report->getNumMethods()
  24098. );
  24099. $colors['lines'] = $this->getCoverageColor(
  24100. $report->getNumExecutedLines(),
  24101. $report->getNumExecutableLines()
  24102. );
  24103. $colors['reset'] = $this->colors['reset'];
  24104. $colors['header'] = $this->colors['header'];
  24105. $colors['eol'] = $this->colors['eol'];
  24106. }
  24107. $classes = sprintf(
  24108. ' Classes: %6s (%d/%d)',
  24109. PHP_CodeCoverage_Util::percent(
  24110. $report->getNumTestedClassesAndTraits(),
  24111. $report->getNumClassesAndTraits(),
  24112. true
  24113. ),
  24114. $report->getNumTestedClassesAndTraits(),
  24115. $report->getNumClassesAndTraits()
  24116. );
  24117. $methods = sprintf(
  24118. ' Methods: %6s (%d/%d)',
  24119. PHP_CodeCoverage_Util::percent(
  24120. $report->getNumTestedMethods(),
  24121. $report->getNumMethods(),
  24122. true
  24123. ),
  24124. $report->getNumTestedMethods(),
  24125. $report->getNumMethods()
  24126. );
  24127. $lines = sprintf(
  24128. ' Lines: %6s (%d/%d)',
  24129. PHP_CodeCoverage_Util::percent(
  24130. $report->getNumExecutedLines(),
  24131. $report->getNumExecutableLines(),
  24132. true
  24133. ),
  24134. $report->getNumExecutedLines(),
  24135. $report->getNumExecutableLines()
  24136. );
  24137. $padding = max(array_map('strlen', array($classes, $methods, $lines)));
  24138. if ($this->showOnlySummary) {
  24139. $title = 'Code Coverage Report Summary:';
  24140. $padding = max($padding, strlen($title));
  24141. $output .= $this->format($colors['header'], $padding, $title);
  24142. } else {
  24143. $date = date(' Y-m-d H:i:s', $_SERVER['REQUEST_TIME']);
  24144. $title = 'Code Coverage Report:';
  24145. $output .= $this->format($colors['header'], $padding, $title);
  24146. $output .= $this->format($colors['header'], $padding, $date);
  24147. $output .= $this->format($colors['header'], $padding, '');
  24148. $output .= $this->format($colors['header'], $padding, ' Summary:');
  24149. }
  24150. $output .= $this->format($colors['classes'], $padding, $classes);
  24151. $output .= $this->format($colors['methods'], $padding, $methods);
  24152. $output .= $this->format($colors['lines'], $padding, $lines);
  24153. if ($this->showOnlySummary) {
  24154. return $output . PHP_EOL;
  24155. }
  24156. $classCoverage = array();
  24157. foreach ($report as $item) {
  24158. if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
  24159. continue;
  24160. }
  24161. $classes = $item->getClassesAndTraits();
  24162. foreach ($classes as $className => $class) {
  24163. $classStatements = 0;
  24164. $coveredClassStatements = 0;
  24165. $coveredMethods = 0;
  24166. $classMethods = 0;
  24167. foreach ($class['methods'] as $method) {
  24168. if ($method['executableLines'] == 0) {
  24169. continue;
  24170. }
  24171. $classMethods++;
  24172. $classStatements += $method['executableLines'];
  24173. $coveredClassStatements += $method['executedLines'];
  24174. if ($method['coverage'] == 100) {
  24175. $coveredMethods++;
  24176. }
  24177. }
  24178. if (!empty($class['package']['namespace'])) {
  24179. $namespace = '\\' . $class['package']['namespace'] . '::';
  24180. } elseif (!empty($class['package']['fullPackage'])) {
  24181. $namespace = '@' . $class['package']['fullPackage'] . '::';
  24182. } else {
  24183. $namespace = '';
  24184. }
  24185. $classCoverage[$namespace . $className] = array(
  24186. 'namespace' => $namespace,
  24187. 'className ' => $className,
  24188. 'methodsCovered' => $coveredMethods,
  24189. 'methodCount' => $classMethods,
  24190. 'statementsCovered' => $coveredClassStatements,
  24191. 'statementCount' => $classStatements,
  24192. );
  24193. }
  24194. }
  24195. ksort($classCoverage);
  24196. $methodColor = '';
  24197. $linesColor = '';
  24198. $resetColor = '';
  24199. foreach ($classCoverage as $fullQualifiedPath => $classInfo) {
  24200. if ($classInfo['statementsCovered'] != 0 ||
  24201. $this->showUncoveredFiles) {
  24202. if ($showColors) {
  24203. $methodColor = $this->getCoverageColor($classInfo['methodsCovered'], $classInfo['methodCount']);
  24204. $linesColor = $this->getCoverageColor($classInfo['statementsCovered'], $classInfo['statementCount']);
  24205. $resetColor = $colors['reset'];
  24206. }
  24207. $output .= PHP_EOL . $fullQualifiedPath . PHP_EOL
  24208. . ' ' . $methodColor . 'Methods: ' . $this->printCoverageCounts($classInfo['methodsCovered'], $classInfo['methodCount'], 2) . $resetColor . ' '
  24209. . ' ' . $linesColor . 'Lines: ' . $this->printCoverageCounts($classInfo['statementsCovered'], $classInfo['statementCount'], 3) . $resetColor
  24210. ;
  24211. }
  24212. }
  24213. return $output . PHP_EOL;
  24214. }
  24215. protected function getCoverageColor($numberOfCoveredElements, $totalNumberOfElements)
  24216. {
  24217. $coverage = PHP_CodeCoverage_Util::percent(
  24218. $numberOfCoveredElements,
  24219. $totalNumberOfElements
  24220. );
  24221. if ($coverage >= $this->highLowerBound) {
  24222. return $this->colors['green'];
  24223. } elseif ($coverage > $this->lowUpperBound) {
  24224. return $this->colors['yellow'];
  24225. }
  24226. return $this->colors['red'];
  24227. }
  24228. protected function printCoverageCounts($numberOfCoveredElements, $totalNumberOfElements, $presicion)
  24229. {
  24230. $format = '%' . $presicion . 's';
  24231. return PHP_CodeCoverage_Util::percent(
  24232. $numberOfCoveredElements,
  24233. $totalNumberOfElements,
  24234. true,
  24235. true
  24236. ) .
  24237. ' (' . sprintf($format, $numberOfCoveredElements) . '/' .
  24238. sprintf($format, $totalNumberOfElements) . ')';
  24239. }
  24240. private function format($color, $padding, $string)
  24241. {
  24242. $reset = $color ? $this->colors['reset'] : '';
  24243. return $color . str_pad($string, $padding) . $reset . PHP_EOL;
  24244. }
  24245. }
  24246. <?php
  24247. /*
  24248. * This file is part of the PHP_CodeCoverage package.
  24249. *
  24250. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24251. *
  24252. * For the full copyright and license information, please view the LICENSE
  24253. * file that was distributed with this source code.
  24254. */
  24255. /**
  24256. * Exception that is raised when code is unintentionally covered.
  24257. *
  24258. * @category PHP
  24259. * @package CodeCoverage
  24260. * @author Sebastian Bergmann <sebastian@phpunit.de>
  24261. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  24262. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  24263. * @link http://github.com/sebastianbergmann/php-code-coverage
  24264. * @since Class available since Release 2.0.0
  24265. */
  24266. class PHP_CodeCoverage_Exception_UnintentionallyCoveredCode extends PHP_CodeCoverage_Exception
  24267. {
  24268. }
  24269. <?php
  24270. /*
  24271. * This file is part of the PHP_CodeCoverage package.
  24272. *
  24273. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24274. *
  24275. * For the full copyright and license information, please view the LICENSE
  24276. * file that was distributed with this source code.
  24277. */
  24278. /**
  24279. * Interface for code coverage drivers.
  24280. *
  24281. * @category PHP
  24282. * @package CodeCoverage
  24283. * @author Sebastian Bergmann <sebastian@phpunit.de>
  24284. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  24285. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  24286. * @link http://github.com/sebastianbergmann/php-code-coverage
  24287. * @since Class available since Release 1.0.0
  24288. */
  24289. interface PHP_CodeCoverage_Driver
  24290. {
  24291. /**
  24292. * Start collection of code coverage information.
  24293. */
  24294. public function start();
  24295. /**
  24296. * Stop collection of code coverage information.
  24297. *
  24298. * @return array
  24299. */
  24300. public function stop();
  24301. }
  24302. <?php
  24303. /*
  24304. * This file is part of the PHP_CodeCoverage package.
  24305. *
  24306. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24307. *
  24308. * For the full copyright and license information, please view the LICENSE
  24309. * file that was distributed with this source code.
  24310. */
  24311. /**
  24312. * Filter for blacklisting and whitelisting of code coverage information.
  24313. *
  24314. * @category PHP
  24315. * @package CodeCoverage
  24316. * @author Sebastian Bergmann <sebastian@phpunit.de>
  24317. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  24318. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  24319. * @link http://github.com/sebastianbergmann/php-code-coverage
  24320. * @since Class available since Release 1.0.0
  24321. */
  24322. class PHP_CodeCoverage_Filter
  24323. {
  24324. /**
  24325. * Source files that are blacklisted.
  24326. *
  24327. * @var array
  24328. */
  24329. private $blacklistedFiles = array();
  24330. /**
  24331. * Source files that are whitelisted.
  24332. *
  24333. * @var array
  24334. */
  24335. private $whitelistedFiles = array();
  24336. /**
  24337. * Adds a directory to the blacklist (recursively).
  24338. *
  24339. * @param string $directory
  24340. * @param string $suffix
  24341. * @param string $prefix
  24342. */
  24343. public function addDirectoryToBlacklist($directory, $suffix = '.php', $prefix = '')
  24344. {
  24345. $facade = new File_Iterator_Facade;
  24346. $files = $facade->getFilesAsArray($directory, $suffix, $prefix);
  24347. foreach ($files as $file) {
  24348. $this->addFileToBlacklist($file);
  24349. }
  24350. }
  24351. /**
  24352. * Adds a file to the blacklist.
  24353. *
  24354. * @param string $filename
  24355. */
  24356. public function addFileToBlacklist($filename)
  24357. {
  24358. $this->blacklistedFiles[realpath($filename)] = true;
  24359. }
  24360. /**
  24361. * Adds files to the blacklist.
  24362. *
  24363. * @param array $files
  24364. */
  24365. public function addFilesToBlacklist(array $files)
  24366. {
  24367. foreach ($files as $file) {
  24368. $this->addFileToBlacklist($file);
  24369. }
  24370. }
  24371. /**
  24372. * Removes a directory from the blacklist (recursively).
  24373. *
  24374. * @param string $directory
  24375. * @param string $suffix
  24376. * @param string $prefix
  24377. */
  24378. public function removeDirectoryFromBlacklist($directory, $suffix = '.php', $prefix = '')
  24379. {
  24380. $facade = new File_Iterator_Facade;
  24381. $files = $facade->getFilesAsArray($directory, $suffix, $prefix);
  24382. foreach ($files as $file) {
  24383. $this->removeFileFromBlacklist($file);
  24384. }
  24385. }
  24386. /**
  24387. * Removes a file from the blacklist.
  24388. *
  24389. * @param string $filename
  24390. */
  24391. public function removeFileFromBlacklist($filename)
  24392. {
  24393. $filename = realpath($filename);
  24394. if (isset($this->blacklistedFiles[$filename])) {
  24395. unset($this->blacklistedFiles[$filename]);
  24396. }
  24397. }
  24398. /**
  24399. * Adds a directory to the whitelist (recursively).
  24400. *
  24401. * @param string $directory
  24402. * @param string $suffix
  24403. * @param string $prefix
  24404. */
  24405. public function addDirectoryToWhitelist($directory, $suffix = '.php', $prefix = '')
  24406. {
  24407. $facade = new File_Iterator_Facade;
  24408. $files = $facade->getFilesAsArray($directory, $suffix, $prefix);
  24409. foreach ($files as $file) {
  24410. $this->addFileToWhitelist($file);
  24411. }
  24412. }
  24413. /**
  24414. * Adds a file to the whitelist.
  24415. *
  24416. * @param string $filename
  24417. */
  24418. public function addFileToWhitelist($filename)
  24419. {
  24420. $this->whitelistedFiles[realpath($filename)] = true;
  24421. }
  24422. /**
  24423. * Adds files to the whitelist.
  24424. *
  24425. * @param array $files
  24426. */
  24427. public function addFilesToWhitelist(array $files)
  24428. {
  24429. foreach ($files as $file) {
  24430. $this->addFileToWhitelist($file);
  24431. }
  24432. }
  24433. /**
  24434. * Removes a directory from the whitelist (recursively).
  24435. *
  24436. * @param string $directory
  24437. * @param string $suffix
  24438. * @param string $prefix
  24439. */
  24440. public function removeDirectoryFromWhitelist($directory, $suffix = '.php', $prefix = '')
  24441. {
  24442. $facade = new File_Iterator_Facade;
  24443. $files = $facade->getFilesAsArray($directory, $suffix, $prefix);
  24444. foreach ($files as $file) {
  24445. $this->removeFileFromWhitelist($file);
  24446. }
  24447. }
  24448. /**
  24449. * Removes a file from the whitelist.
  24450. *
  24451. * @param string $filename
  24452. */
  24453. public function removeFileFromWhitelist($filename)
  24454. {
  24455. $filename = realpath($filename);
  24456. if (isset($this->whitelistedFiles[$filename])) {
  24457. unset($this->whitelistedFiles[$filename]);
  24458. }
  24459. }
  24460. /**
  24461. * Checks whether a filename is a real filename.
  24462. *
  24463. * @param string $filename
  24464. */
  24465. public function isFile($filename)
  24466. {
  24467. if ($filename == '-' ||
  24468. strpos($filename, 'vfs://') === 0 ||
  24469. strpos($filename, 'xdebug://debug-eval') !== false ||
  24470. strpos($filename, 'eval()\'d code') !== false ||
  24471. strpos($filename, 'runtime-created function') !== false ||
  24472. strpos($filename, 'runkit created function') !== false ||
  24473. strpos($filename, 'assert code') !== false ||
  24474. strpos($filename, 'regexp code') !== false) {
  24475. return false;
  24476. }
  24477. return file_exists($filename);
  24478. }
  24479. /**
  24480. * Checks whether or not a file is filtered.
  24481. *
  24482. * When the whitelist is empty (default), blacklisting is used.
  24483. * When the whitelist is not empty, whitelisting is used.
  24484. *
  24485. * @param string $filename
  24486. * @return boolean
  24487. * @throws PHP_CodeCoverage_Exception
  24488. */
  24489. public function isFiltered($filename)
  24490. {
  24491. if (!$this->isFile($filename)) {
  24492. return true;
  24493. }
  24494. $filename = realpath($filename);
  24495. if (!empty($this->whitelistedFiles)) {
  24496. return !isset($this->whitelistedFiles[$filename]);
  24497. }
  24498. return isset($this->blacklistedFiles[$filename]);
  24499. }
  24500. /**
  24501. * Returns the list of blacklisted files.
  24502. *
  24503. * @return array
  24504. */
  24505. public function getBlacklist()
  24506. {
  24507. return array_keys($this->blacklistedFiles);
  24508. }
  24509. /**
  24510. * Returns the list of whitelisted files.
  24511. *
  24512. * @return array
  24513. */
  24514. public function getWhitelist()
  24515. {
  24516. return array_keys($this->whitelistedFiles);
  24517. }
  24518. /**
  24519. * Returns whether this filter has a whitelist.
  24520. *
  24521. * @return boolean
  24522. * @since Method available since Release 1.1.0
  24523. */
  24524. public function hasWhitelist()
  24525. {
  24526. return !empty($this->whitelistedFiles);
  24527. }
  24528. /**
  24529. * Returns the blacklisted files.
  24530. *
  24531. * @return array
  24532. * @since Method available since Release 2.0.0
  24533. */
  24534. public function getBlacklistedFiles()
  24535. {
  24536. return $this->blacklistedFiles;
  24537. }
  24538. /**
  24539. * Sets the blacklisted files.
  24540. *
  24541. * @param array $blacklistedFiles
  24542. * @since Method available since Release 2.0.0
  24543. */
  24544. public function setBlacklistedFiles($blacklistedFiles)
  24545. {
  24546. $this->blacklistedFiles = $blacklistedFiles;
  24547. }
  24548. /**
  24549. * Returns the whitelisted files.
  24550. *
  24551. * @return array
  24552. * @since Method available since Release 2.0.0
  24553. */
  24554. public function getWhitelistedFiles()
  24555. {
  24556. return $this->whitelistedFiles;
  24557. }
  24558. /**
  24559. * Sets the whitelisted files.
  24560. *
  24561. * @param array $whitelistedFiles
  24562. * @since Method available since Release 2.0.0
  24563. */
  24564. public function setWhitelistedFiles($whitelistedFiles)
  24565. {
  24566. $this->whitelistedFiles = $whitelistedFiles;
  24567. }
  24568. }
  24569. <?php
  24570. /*
  24571. * This file is part of the PHP_CodeCoverage package.
  24572. *
  24573. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24574. *
  24575. * For the full copyright and license information, please view the LICENSE
  24576. * file that was distributed with this source code.
  24577. */
  24578. /**
  24579. * Factory for PHP_CodeCoverage_Exception objects that are used to describe
  24580. * invalid arguments passed to a function or method.
  24581. *
  24582. * @category PHP
  24583. * @package CodeCoverage
  24584. * @author Sebastian Bergmann <sebastian@phpunit.de>
  24585. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  24586. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  24587. * @link http://github.com/sebastianbergmann/php-code-coverage
  24588. * @since Class available since Release 1.2.0
  24589. */
  24590. class PHP_CodeCoverage_Util_InvalidArgumentHelper
  24591. {
  24592. /**
  24593. * @param integer $argument
  24594. * @param string $type
  24595. * @param mixed $value
  24596. */
  24597. public static function factory($argument, $type, $value = null)
  24598. {
  24599. $stack = debug_backtrace(false);
  24600. return new PHP_CodeCoverage_Exception(
  24601. sprintf(
  24602. 'Argument #%d%sof %s::%s() must be a %s',
  24603. $argument,
  24604. $value !== null ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ',
  24605. $stack[1]['class'],
  24606. $stack[1]['function'],
  24607. $type
  24608. )
  24609. );
  24610. }
  24611. }
  24612. <?php
  24613. /*
  24614. * This file is part of the PHP_CodeCoverage package.
  24615. *
  24616. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24617. *
  24618. * For the full copyright and license information, please view the LICENSE
  24619. * file that was distributed with this source code.
  24620. */
  24621. /**
  24622. * Driver for HHVM's code coverage functionality.
  24623. *
  24624. * @category PHP
  24625. * @package CodeCoverage
  24626. * @author Sebastian Bergmann <sebastian@phpunit.de>
  24627. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  24628. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  24629. * @link http://github.com/sebastianbergmann/php-code-coverage
  24630. * @since Class available since Release 1.3.0
  24631. * @codeCoverageIgnore
  24632. */
  24633. class PHP_CodeCoverage_Driver_HHVM implements PHP_CodeCoverage_Driver
  24634. {
  24635. /**
  24636. * Constructor.
  24637. */
  24638. public function __construct()
  24639. {
  24640. if (!defined('HHVM_VERSION')) {
  24641. throw new PHP_CodeCoverage_Exception('This driver requires HHVM');
  24642. }
  24643. }
  24644. /**
  24645. * Start collection of code coverage information.
  24646. */
  24647. public function start()
  24648. {
  24649. fb_enable_code_coverage();
  24650. }
  24651. /**
  24652. * Stop collection of code coverage information.
  24653. *
  24654. * @return array
  24655. */
  24656. public function stop()
  24657. {
  24658. $codeCoverage = fb_get_code_coverage(true);
  24659. fb_disable_code_coverage();
  24660. return $codeCoverage;
  24661. }
  24662. }
  24663. <?php
  24664. /*
  24665. * This file is part of the PHP_CodeCoverage package.
  24666. *
  24667. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24668. *
  24669. * For the full copyright and license information, please view the LICENSE
  24670. * file that was distributed with this source code.
  24671. */
  24672. /**
  24673. * Driver for Xdebug's code coverage functionality.
  24674. *
  24675. * @category PHP
  24676. * @package CodeCoverage
  24677. * @author Sebastian Bergmann <sebastian@phpunit.de>
  24678. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  24679. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  24680. * @link http://github.com/sebastianbergmann/php-code-coverage
  24681. * @since Class available since Release 1.0.0
  24682. * @codeCoverageIgnore
  24683. */
  24684. class PHP_CodeCoverage_Driver_Xdebug implements PHP_CodeCoverage_Driver
  24685. {
  24686. /**
  24687. * Constructor.
  24688. */
  24689. public function __construct()
  24690. {
  24691. if (!extension_loaded('xdebug')) {
  24692. throw new PHP_CodeCoverage_Exception('This driver requires Xdebug');
  24693. }
  24694. if (version_compare(phpversion('xdebug'), '2.2.0-dev', '>=') &&
  24695. !ini_get('xdebug.coverage_enable')) {
  24696. throw new PHP_CodeCoverage_Exception(
  24697. 'xdebug.coverage_enable=On has to be set in php.ini'
  24698. );
  24699. }
  24700. }
  24701. /**
  24702. * Start collection of code coverage information.
  24703. */
  24704. public function start()
  24705. {
  24706. xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
  24707. }
  24708. /**
  24709. * Stop collection of code coverage information.
  24710. *
  24711. * @return array
  24712. */
  24713. public function stop()
  24714. {
  24715. $data = xdebug_get_code_coverage();
  24716. xdebug_stop_code_coverage();
  24717. return $this->cleanup($data);
  24718. }
  24719. /**
  24720. * @param array $data
  24721. * @return array
  24722. * @since Method available since Release 2.0.0
  24723. */
  24724. private function cleanup(array $data)
  24725. {
  24726. foreach (array_keys($data) as $file) {
  24727. if (isset($data[$file][0])) {
  24728. unset($data[$file][0]);
  24729. }
  24730. if ($file != "xdebug://debug-eval" && file_exists($file)) {
  24731. $numLines = $this->getNumberOfLinesInFile($file);
  24732. foreach (array_keys($data[$file]) as $line) {
  24733. if (isset($data[$file][$line]) && $line > $numLines) {
  24734. unset($data[$file][$line]);
  24735. }
  24736. }
  24737. }
  24738. }
  24739. return $data;
  24740. }
  24741. /**
  24742. * @param string $file
  24743. * @return integer
  24744. * @since Method available since Release 2.0.0
  24745. */
  24746. private function getNumberOfLinesInFile($file)
  24747. {
  24748. $buffer = file_get_contents($file);
  24749. $lines = substr_count($buffer, "\n");
  24750. if (substr($buffer, -1) !== "\n") {
  24751. $lines++;
  24752. }
  24753. return $lines;
  24754. }
  24755. }
  24756. PHP_CodeCoverage
  24757. Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  24758. All rights reserved.
  24759. Redistribution and use in source and binary forms, with or without
  24760. modification, are permitted provided that the following conditions
  24761. are met:
  24762. * Redistributions of source code must retain the above copyright
  24763. notice, this list of conditions and the following disclaimer.
  24764. * Redistributions in binary form must reproduce the above copyright
  24765. notice, this list of conditions and the following disclaimer in
  24766. the documentation and/or other materials provided with the
  24767. distribution.
  24768. * Neither the name of Sebastian Bergmann nor the names of his
  24769. contributors may be used to endorse or promote products derived
  24770. from this software without specific prior written permission.
  24771. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  24772. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24773. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24774. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24775. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24776. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24777. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24778. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24779. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24780. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  24781. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  24782. POSSIBILITY OF SUCH DAMAGE.
  24783. <?php
  24784. /*
  24785. * This file is part of the PHP_CodeCoverage package.
  24786. *
  24787. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24788. *
  24789. * For the full copyright and license information, please view the LICENSE
  24790. * file that was distributed with this source code.
  24791. */
  24792. use SebastianBergmann\Environment\Runtime;
  24793. /**
  24794. * Provides collection functionality for PHP code coverage information.
  24795. *
  24796. * @category PHP
  24797. * @package CodeCoverage
  24798. * @author Sebastian Bergmann <sebastian@phpunit.de>
  24799. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  24800. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  24801. * @link http://github.com/sebastianbergmann/php-code-coverage
  24802. * @since Class available since Release 1.0.0
  24803. */
  24804. class PHP_CodeCoverage
  24805. {
  24806. /**
  24807. * @var PHP_CodeCoverage_Driver
  24808. */
  24809. private $driver;
  24810. /**
  24811. * @var PHP_CodeCoverage_Filter
  24812. */
  24813. private $filter;
  24814. /**
  24815. * @var boolean
  24816. */
  24817. private $cacheTokens = false;
  24818. /**
  24819. * @var boolean
  24820. */
  24821. private $checkForUnintentionallyCoveredCode = false;
  24822. /**
  24823. * @var boolean
  24824. */
  24825. private $forceCoversAnnotation = false;
  24826. /**
  24827. * @var boolean
  24828. */
  24829. private $mapTestClassNameToCoveredClassName = false;
  24830. /**
  24831. * @var boolean
  24832. */
  24833. private $addUncoveredFilesFromWhitelist = true;
  24834. /**
  24835. * @var boolean
  24836. */
  24837. private $processUncoveredFilesFromWhitelist = false;
  24838. /**
  24839. * @var mixed
  24840. */
  24841. private $currentId;
  24842. /**
  24843. * Code coverage data.
  24844. *
  24845. * @var array
  24846. */
  24847. private $data = array();
  24848. /**
  24849. * @var array
  24850. */
  24851. private $ignoredLines = array();
  24852. /**
  24853. * Test data.
  24854. *
  24855. * @var array
  24856. */
  24857. private $tests = array();
  24858. /**
  24859. * Constructor.
  24860. *
  24861. * @param PHP_CodeCoverage_Driver $driver
  24862. * @param PHP_CodeCoverage_Filter $filter
  24863. * @throws PHP_CodeCoverage_Exception
  24864. */
  24865. public function __construct(PHP_CodeCoverage_Driver $driver = null, PHP_CodeCoverage_Filter $filter = null)
  24866. {
  24867. if ($driver === null) {
  24868. $runtime = new Runtime;
  24869. if ($runtime->isHHVM()) {
  24870. $driver = new PHP_CodeCoverage_Driver_HHVM;
  24871. } elseif ($runtime->hasXdebug()) {
  24872. $driver = new PHP_CodeCoverage_Driver_Xdebug;
  24873. } else {
  24874. throw new PHP_CodeCoverage_Exception('No code coverage driver available');
  24875. }
  24876. }
  24877. if ($filter === null) {
  24878. $filter = new PHP_CodeCoverage_Filter;
  24879. }
  24880. $this->driver = $driver;
  24881. $this->filter = $filter;
  24882. }
  24883. /**
  24884. * Returns the PHP_CodeCoverage_Report_Node_* object graph
  24885. * for this PHP_CodeCoverage object.
  24886. *
  24887. * @return PHP_CodeCoverage_Report_Node_Directory
  24888. * @since Method available since Release 1.1.0
  24889. */
  24890. public function getReport()
  24891. {
  24892. $factory = new PHP_CodeCoverage_Report_Factory;
  24893. return $factory->create($this);
  24894. }
  24895. /**
  24896. * Clears collected code coverage data.
  24897. */
  24898. public function clear()
  24899. {
  24900. $this->currentId = null;
  24901. $this->data = array();
  24902. $this->tests = array();
  24903. }
  24904. /**
  24905. * Returns the PHP_CodeCoverage_Filter used.
  24906. *
  24907. * @return PHP_CodeCoverage_Filter
  24908. */
  24909. public function filter()
  24910. {
  24911. return $this->filter;
  24912. }
  24913. /**
  24914. * Returns the collected code coverage data.
  24915. * Set $raw = true to bypass all filters.
  24916. *
  24917. * @param bool $raw
  24918. * @return array
  24919. * @since Method available since Release 1.1.0
  24920. */
  24921. public function getData($raw = false)
  24922. {
  24923. if (!$raw && $this->addUncoveredFilesFromWhitelist) {
  24924. $this->addUncoveredFilesFromWhitelist();
  24925. }
  24926. // We need to apply the blacklist filter a second time
  24927. // when no whitelist is used.
  24928. if (!$raw && !$this->filter->hasWhitelist()) {
  24929. $this->applyListsFilter($this->data);
  24930. }
  24931. return $this->data;
  24932. }
  24933. /**
  24934. * Sets the coverage data.
  24935. *
  24936. * @param array $data
  24937. * @since Method available since Release 2.0.0
  24938. */
  24939. public function setData(array $data)
  24940. {
  24941. $this->data = $data;
  24942. }
  24943. /**
  24944. * Returns the test data.
  24945. *
  24946. * @return array
  24947. * @since Method available since Release 1.1.0
  24948. */
  24949. public function getTests()
  24950. {
  24951. return $this->tests;
  24952. }
  24953. /**
  24954. * Sets the test data.
  24955. *
  24956. * @param array $tests
  24957. * @since Method available since Release 2.0.0
  24958. */
  24959. public function setTests(array $tests)
  24960. {
  24961. $this->tests = $tests;
  24962. }
  24963. /**
  24964. * Start collection of code coverage information.
  24965. *
  24966. * @param mixed $id
  24967. * @param boolean $clear
  24968. * @throws PHP_CodeCoverage_Exception
  24969. */
  24970. public function start($id, $clear = false)
  24971. {
  24972. if (!is_bool($clear)) {
  24973. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24974. 1,
  24975. 'boolean'
  24976. );
  24977. }
  24978. if ($clear) {
  24979. $this->clear();
  24980. }
  24981. $this->currentId = $id;
  24982. $this->driver->start();
  24983. }
  24984. /**
  24985. * Stop collection of code coverage information.
  24986. *
  24987. * @param boolean $append
  24988. * @param mixed $linesToBeCovered
  24989. * @param array $linesToBeUsed
  24990. * @return array
  24991. * @throws PHP_CodeCoverage_Exception
  24992. */
  24993. public function stop($append = true, $linesToBeCovered = array(), array $linesToBeUsed = array())
  24994. {
  24995. if (!is_bool($append)) {
  24996. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24997. 1,
  24998. 'boolean'
  24999. );
  25000. }
  25001. if (!is_array($linesToBeCovered) && $linesToBeCovered !== false) {
  25002. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  25003. 2,
  25004. 'array or false'
  25005. );
  25006. }
  25007. $data = $this->driver->stop();
  25008. $this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed);
  25009. $this->currentId = null;
  25010. return $data;
  25011. }
  25012. /**
  25013. * Appends code coverage data.
  25014. *
  25015. * @param array $data
  25016. * @param mixed $id
  25017. * @param boolean $append
  25018. * @param mixed $linesToBeCovered
  25019. * @param array $linesToBeUsed
  25020. * @throws PHP_CodeCoverage_Exception
  25021. */
  25022. public function append(array $data, $id = null, $append = true, $linesToBeCovered = array(), array $linesToBeUsed = array())
  25023. {
  25024. if ($id === null) {
  25025. $id = $this->currentId;
  25026. }
  25027. if ($id === null) {
  25028. throw new PHP_CodeCoverage_Exception;
  25029. }
  25030. $this->applyListsFilter($data);
  25031. $this->applyIgnoredLinesFilter($data);
  25032. $this->initializeFilesThatAreSeenTheFirstTime($data);
  25033. if (!$append) {
  25034. return;
  25035. }
  25036. if ($id != 'UNCOVERED_FILES_FROM_WHITELIST') {
  25037. $this->applyCoversAnnotationFilter(
  25038. $data,
  25039. $linesToBeCovered,
  25040. $linesToBeUsed
  25041. );
  25042. }
  25043. if (empty($data)) {
  25044. return;
  25045. }
  25046. $size = 'unknown';
  25047. $status = null;
  25048. if ($id instanceof PHPUnit_Framework_TestCase) {
  25049. $_size = $id->getSize();
  25050. if ($_size == PHPUnit_Util_Test::SMALL) {
  25051. $size = 'small';
  25052. } elseif ($_size == PHPUnit_Util_Test::MEDIUM) {
  25053. $size = 'medium';
  25054. } elseif ($_size == PHPUnit_Util_Test::LARGE) {
  25055. $size = 'large';
  25056. }
  25057. $status = $id->getStatus();
  25058. $id = get_class($id) . '::' . $id->getName();
  25059. } elseif ($id instanceof PHPUnit_Extensions_PhptTestCase) {
  25060. $size = 'large';
  25061. $id = $id->getName();
  25062. }
  25063. $this->tests[$id] = array('size' => $size, 'status' => $status);
  25064. foreach ($data as $file => $lines) {
  25065. if (!$this->filter->isFile($file)) {
  25066. continue;
  25067. }
  25068. foreach ($lines as $k => $v) {
  25069. if ($v == 1) {
  25070. if (empty($this->data[$file][$k]) || !in_array($id, $this->data[$file][$k])) {
  25071. $this->data[$file][$k][] = $id;
  25072. }
  25073. }
  25074. }
  25075. }
  25076. }
  25077. /**
  25078. * Merges the data from another instance of PHP_CodeCoverage.
  25079. *
  25080. * @param PHP_CodeCoverage $that
  25081. */
  25082. public function merge(PHP_CodeCoverage $that)
  25083. {
  25084. foreach ($that->data as $file => $lines) {
  25085. if (!isset($this->data[$file])) {
  25086. if (!$this->filter->isFiltered($file)) {
  25087. $this->data[$file] = $lines;
  25088. }
  25089. continue;
  25090. }
  25091. foreach ($lines as $line => $data) {
  25092. if ($data !== null) {
  25093. if (!isset($this->data[$file][$line])) {
  25094. $this->data[$file][$line] = $data;
  25095. } else {
  25096. $this->data[$file][$line] = array_unique(
  25097. array_merge($this->data[$file][$line], $data)
  25098. );
  25099. }
  25100. }
  25101. }
  25102. }
  25103. $this->tests = array_merge($this->tests, $that->getTests());
  25104. $this->filter->setBlacklistedFiles(
  25105. array_merge($this->filter->getBlacklistedFiles(), $that->filter()->getBlacklistedFiles())
  25106. );
  25107. $this->filter->setWhitelistedFiles(
  25108. array_merge($this->filter->getWhitelistedFiles(), $that->filter()->getWhitelistedFiles())
  25109. );
  25110. }
  25111. /**
  25112. * @param boolean $flag
  25113. * @throws PHP_CodeCoverage_Exception
  25114. * @since Method available since Release 1.1.0
  25115. */
  25116. public function setCacheTokens($flag)
  25117. {
  25118. if (!is_bool($flag)) {
  25119. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  25120. 1,
  25121. 'boolean'
  25122. );
  25123. }
  25124. $this->cacheTokens = $flag;
  25125. }
  25126. /**
  25127. * @since Method available since Release 1.1.0
  25128. */
  25129. public function getCacheTokens()
  25130. {
  25131. return $this->cacheTokens;
  25132. }
  25133. /**
  25134. * @param boolean $flag
  25135. * @throws PHP_CodeCoverage_Exception
  25136. * @since Method available since Release 2.0.0
  25137. */
  25138. public function setCheckForUnintentionallyCoveredCode($flag)
  25139. {
  25140. if (!is_bool($flag)) {
  25141. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  25142. 1,
  25143. 'boolean'
  25144. );
  25145. }
  25146. $this->checkForUnintentionallyCoveredCode = $flag;
  25147. }
  25148. /**
  25149. * @param boolean $flag
  25150. * @throws PHP_CodeCoverage_Exception
  25151. */
  25152. public function setForceCoversAnnotation($flag)
  25153. {
  25154. if (!is_bool($flag)) {
  25155. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  25156. 1,
  25157. 'boolean'
  25158. );
  25159. }
  25160. $this->forceCoversAnnotation = $flag;
  25161. }
  25162. /**
  25163. * @param boolean $flag
  25164. * @throws PHP_CodeCoverage_Exception
  25165. */
  25166. public function setMapTestClassNameToCoveredClassName($flag)
  25167. {
  25168. if (!is_bool($flag)) {
  25169. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  25170. 1,
  25171. 'boolean'
  25172. );
  25173. }
  25174. $this->mapTestClassNameToCoveredClassName = $flag;
  25175. }
  25176. /**
  25177. * @param boolean $flag
  25178. * @throws PHP_CodeCoverage_Exception
  25179. */
  25180. public function setAddUncoveredFilesFromWhitelist($flag)
  25181. {
  25182. if (!is_bool($flag)) {
  25183. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  25184. 1,
  25185. 'boolean'
  25186. );
  25187. }
  25188. $this->addUncoveredFilesFromWhitelist = $flag;
  25189. }
  25190. /**
  25191. * @param boolean $flag
  25192. * @throws PHP_CodeCoverage_Exception
  25193. */
  25194. public function setProcessUncoveredFilesFromWhitelist($flag)
  25195. {
  25196. if (!is_bool($flag)) {
  25197. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  25198. 1,
  25199. 'boolean'
  25200. );
  25201. }
  25202. $this->processUncoveredFilesFromWhitelist = $flag;
  25203. }
  25204. /**
  25205. * Applies the @covers annotation filtering.
  25206. *
  25207. * @param array $data
  25208. * @param mixed $linesToBeCovered
  25209. * @param array $linesToBeUsed
  25210. * @throws PHP_CodeCoverage_Exception_UnintentionallyCoveredCode
  25211. */
  25212. private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed)
  25213. {
  25214. if ($linesToBeCovered === false ||
  25215. ($this->forceCoversAnnotation && empty($linesToBeCovered))) {
  25216. $data = array();
  25217. return;
  25218. }
  25219. if (empty($linesToBeCovered)) {
  25220. return;
  25221. }
  25222. if ($this->checkForUnintentionallyCoveredCode) {
  25223. $this->performUnintentionallyCoveredCodeCheck(
  25224. $data,
  25225. $linesToBeCovered,
  25226. $linesToBeUsed
  25227. );
  25228. }
  25229. $data = array_intersect_key($data, $linesToBeCovered);
  25230. foreach (array_keys($data) as $filename) {
  25231. $_linesToBeCovered = array_flip($linesToBeCovered[$filename]);
  25232. $data[$filename] = array_intersect_key(
  25233. $data[$filename],
  25234. $_linesToBeCovered
  25235. );
  25236. }
  25237. }
  25238. /**
  25239. * Applies the blacklist/whitelist filtering.
  25240. *
  25241. * @param array $data
  25242. */
  25243. private function applyListsFilter(array &$data)
  25244. {
  25245. foreach (array_keys($data) as $filename) {
  25246. if ($this->filter->isFiltered($filename)) {
  25247. unset($data[$filename]);
  25248. }
  25249. }
  25250. }
  25251. /**
  25252. * Applies the "ignored lines" filtering.
  25253. *
  25254. * @param array $data
  25255. */
  25256. private function applyIgnoredLinesFilter(array &$data)
  25257. {
  25258. foreach (array_keys($data) as $filename) {
  25259. if (!$this->filter->isFile($filename)) {
  25260. continue;
  25261. }
  25262. foreach ($this->getLinesToBeIgnored($filename) as $line) {
  25263. unset($data[$filename][$line]);
  25264. }
  25265. }
  25266. }
  25267. /**
  25268. * @param array $data
  25269. * @since Method available since Release 1.1.0
  25270. */
  25271. private function initializeFilesThatAreSeenTheFirstTime(array $data)
  25272. {
  25273. foreach ($data as $file => $lines) {
  25274. if ($this->filter->isFile($file) && !isset($this->data[$file])) {
  25275. $this->data[$file] = array();
  25276. foreach ($lines as $k => $v) {
  25277. $this->data[$file][$k] = $v == -2 ? null : array();
  25278. }
  25279. }
  25280. }
  25281. }
  25282. /**
  25283. * Processes whitelisted files that are not covered.
  25284. */
  25285. private function addUncoveredFilesFromWhitelist()
  25286. {
  25287. $data = array();
  25288. $uncoveredFiles = array_diff(
  25289. $this->filter->getWhitelist(),
  25290. array_keys($this->data)
  25291. );
  25292. foreach ($uncoveredFiles as $uncoveredFile) {
  25293. if (!file_exists($uncoveredFile)) {
  25294. continue;
  25295. }
  25296. if ($this->processUncoveredFilesFromWhitelist) {
  25297. $this->processUncoveredFileFromWhitelist(
  25298. $uncoveredFile,
  25299. $data,
  25300. $uncoveredFiles
  25301. );
  25302. } else {
  25303. $data[$uncoveredFile] = array();
  25304. $lines = count(file($uncoveredFile));
  25305. for ($i = 1; $i <= $lines; $i++) {
  25306. $data[$uncoveredFile][$i] = -1;
  25307. }
  25308. }
  25309. }
  25310. $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST');
  25311. }
  25312. /**
  25313. * @param string $uncoveredFile
  25314. * @param array $data
  25315. * @param array $uncoveredFiles
  25316. */
  25317. private function processUncoveredFileFromWhitelist($uncoveredFile, array &$data, array $uncoveredFiles)
  25318. {
  25319. $this->driver->start();
  25320. include_once $uncoveredFile;
  25321. $coverage = $this->driver->stop();
  25322. foreach ($coverage as $file => $fileCoverage) {
  25323. if (!isset($data[$file]) &&
  25324. in_array($file, $uncoveredFiles)) {
  25325. foreach (array_keys($fileCoverage) as $key) {
  25326. if ($fileCoverage[$key] == 1) {
  25327. $fileCoverage[$key] = -1;
  25328. }
  25329. }
  25330. $data[$file] = $fileCoverage;
  25331. }
  25332. }
  25333. }
  25334. /**
  25335. * Returns the lines of a source file that should be ignored.
  25336. *
  25337. * @param string $filename
  25338. * @return array
  25339. * @throws PHP_CodeCoverage_Exception
  25340. * @since Method available since Release 2.0.0
  25341. */
  25342. private function getLinesToBeIgnored($filename)
  25343. {
  25344. if (!is_string($filename)) {
  25345. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  25346. 1,
  25347. 'string'
  25348. );
  25349. }
  25350. if (!isset($this->ignoredLines[$filename])) {
  25351. $this->ignoredLines[$filename] = array();
  25352. $ignore = false;
  25353. $stop = false;
  25354. $lines = file($filename);
  25355. $numLines = count($lines);
  25356. foreach ($lines as $index => $line) {
  25357. if (!trim($line)) {
  25358. $this->ignoredLines[$filename][] = $index + 1;
  25359. }
  25360. }
  25361. if ($this->cacheTokens) {
  25362. $tokens = PHP_Token_Stream_CachingFactory::get($filename);
  25363. } else {
  25364. $tokens = new PHP_Token_Stream($filename);
  25365. }
  25366. $classes = array_merge($tokens->getClasses(), $tokens->getTraits());
  25367. $tokens = $tokens->tokens();
  25368. foreach ($tokens as $token) {
  25369. switch (get_class($token)) {
  25370. case 'PHP_Token_COMMENT':
  25371. case 'PHP_Token_DOC_COMMENT':
  25372. $_token = trim($token);
  25373. $_line = trim($lines[$token->getLine() - 1]);
  25374. if ($_token == '// @codeCoverageIgnore' ||
  25375. $_token == '//@codeCoverageIgnore') {
  25376. $ignore = true;
  25377. $stop = true;
  25378. } elseif ($_token == '// @codeCoverageIgnoreStart' ||
  25379. $_token == '//@codeCoverageIgnoreStart') {
  25380. $ignore = true;
  25381. } elseif ($_token == '// @codeCoverageIgnoreEnd' ||
  25382. $_token == '//@codeCoverageIgnoreEnd') {
  25383. $stop = true;
  25384. }
  25385. if (!$ignore) {
  25386. $start = $token->getLine();
  25387. $end = $start + substr_count($token, "\n");
  25388. // Do not ignore the first line when there is a token
  25389. // before the comment
  25390. if (0 !== strpos($_token, $_line)) {
  25391. $start++;
  25392. }
  25393. for ($i = $start; $i < $end; $i++) {
  25394. $this->ignoredLines[$filename][] = $i;
  25395. }
  25396. // A DOC_COMMENT token or a COMMENT token starting with "/*"
  25397. // does not contain the final \n character in its text
  25398. if (isset($lines[$i-1]) && 0 === strpos($_token, '/*') && '*/' === substr(trim($lines[$i-1]), -2)) {
  25399. $this->ignoredLines[$filename][] = $i;
  25400. }
  25401. }
  25402. break;
  25403. case 'PHP_Token_INTERFACE':
  25404. case 'PHP_Token_TRAIT':
  25405. case 'PHP_Token_CLASS':
  25406. case 'PHP_Token_FUNCTION':
  25407. $docblock = $token->getDocblock();
  25408. $this->ignoredLines[$filename][] = $token->getLine();
  25409. if (strpos($docblock, '@codeCoverageIgnore')) {
  25410. $endLine = $token->getEndLine();
  25411. for ($i = $token->getLine(); $i <= $endLine; $i++) {
  25412. $this->ignoredLines[$filename][] = $i;
  25413. }
  25414. } elseif ($token instanceof PHP_Token_INTERFACE ||
  25415. $token instanceof PHP_Token_TRAIT ||
  25416. $token instanceof PHP_Token_CLASS) {
  25417. if (empty($classes[$token->getName()]['methods'])) {
  25418. for ($i = $token->getLine();
  25419. $i <= $token->getEndLine();
  25420. $i++) {
  25421. $this->ignoredLines[$filename][] = $i;
  25422. }
  25423. } else {
  25424. $firstMethod = array_shift(
  25425. $classes[$token->getName()]['methods']
  25426. );
  25427. do {
  25428. $lastMethod = array_pop(
  25429. $classes[$token->getName()]['methods']
  25430. );
  25431. } while ($lastMethod !== null &&
  25432. substr($lastMethod['signature'], 0, 18) == 'anonymous function');
  25433. if ($lastMethod === null) {
  25434. $lastMethod = $firstMethod;
  25435. }
  25436. for ($i = $token->getLine();
  25437. $i < $firstMethod['startLine'];
  25438. $i++) {
  25439. $this->ignoredLines[$filename][] = $i;
  25440. }
  25441. for ($i = $token->getEndLine();
  25442. $i > $lastMethod['endLine'];
  25443. $i--) {
  25444. $this->ignoredLines[$filename][] = $i;
  25445. }
  25446. }
  25447. }
  25448. break;
  25449. case 'PHP_Token_NAMESPACE':
  25450. $this->ignoredLines[$filename][] = $token->getEndLine();
  25451. // Intentional fallthrough
  25452. case 'PHP_Token_OPEN_TAG':
  25453. case 'PHP_Token_CLOSE_TAG':
  25454. case 'PHP_Token_USE':
  25455. $this->ignoredLines[$filename][] = $token->getLine();
  25456. break;
  25457. }
  25458. if ($ignore) {
  25459. $this->ignoredLines[$filename][] = $token->getLine();
  25460. if ($stop) {
  25461. $ignore = false;
  25462. $stop = false;
  25463. }
  25464. }
  25465. }
  25466. $this->ignoredLines[$filename][] = $numLines + 1;
  25467. $this->ignoredLines[$filename] = array_unique(
  25468. $this->ignoredLines[$filename]
  25469. );
  25470. sort($this->ignoredLines[$filename]);
  25471. }
  25472. return $this->ignoredLines[$filename];
  25473. }
  25474. /**
  25475. * @param array $data
  25476. * @param array $linesToBeCovered
  25477. * @param array $linesToBeUsed
  25478. * @throws PHP_CodeCoverage_Exception_UnintentionallyCoveredCode
  25479. * @since Method available since Release 2.0.0
  25480. */
  25481. private function performUnintentionallyCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed)
  25482. {
  25483. $allowedLines = $this->getAllowedLines(
  25484. $linesToBeCovered,
  25485. $linesToBeUsed
  25486. );
  25487. $message = '';
  25488. foreach ($data as $file => $_data) {
  25489. foreach ($_data as $line => $flag) {
  25490. if ($flag == 1 &&
  25491. (!isset($allowedLines[$file]) ||
  25492. !isset($allowedLines[$file][$line]))) {
  25493. $message .= sprintf(
  25494. '- %s:%d' . PHP_EOL,
  25495. $file,
  25496. $line
  25497. );
  25498. }
  25499. }
  25500. }
  25501. if (!empty($message)) {
  25502. throw new PHP_CodeCoverage_Exception_UnintentionallyCoveredCode(
  25503. $message
  25504. );
  25505. }
  25506. }
  25507. /**
  25508. * @param array $linesToBeCovered
  25509. * @param array $linesToBeUsed
  25510. * @return array
  25511. * @since Method available since Release 2.0.0
  25512. */
  25513. private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed)
  25514. {
  25515. $allowedLines = array();
  25516. foreach (array_keys($linesToBeCovered) as $file) {
  25517. if (!isset($allowedLines[$file])) {
  25518. $allowedLines[$file] = array();
  25519. }
  25520. $allowedLines[$file] = array_merge(
  25521. $allowedLines[$file],
  25522. $linesToBeCovered[$file]
  25523. );
  25524. }
  25525. foreach (array_keys($linesToBeUsed) as $file) {
  25526. if (!isset($allowedLines[$file])) {
  25527. $allowedLines[$file] = array();
  25528. }
  25529. $allowedLines[$file] = array_merge(
  25530. $allowedLines[$file],
  25531. $linesToBeUsed[$file]
  25532. );
  25533. }
  25534. foreach (array_keys($allowedLines) as $file) {
  25535. $allowedLines[$file] = array_flip(
  25536. array_unique($allowedLines[$file])
  25537. );
  25538. }
  25539. return $allowedLines;
  25540. }
  25541. }
  25542. Copyright (c) 2004-2015 Fabien Potencier
  25543. Permission is hereby granted, free of charge, to any person obtaining a copy
  25544. of this software and associated documentation files (the "Software"), to deal
  25545. in the Software without restriction, including without limitation the rights
  25546. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  25547. copies of the Software, and to permit persons to whom the Software is furnished
  25548. to do so, subject to the following conditions:
  25549. The above copyright notice and this permission notice shall be included in all
  25550. copies or substantial portions of the Software.
  25551. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25552. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25553. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  25554. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25555. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25556. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25557. THE SOFTWARE.
  25558. <?php
  25559. /*
  25560. * This file is part of the Symfony package.
  25561. *
  25562. * (c) Fabien Potencier <fabien@symfony.com>
  25563. *
  25564. * For the full copyright and license information, please view the LICENSE
  25565. * file that was distributed with this source code.
  25566. */
  25567. namespace Symfony\Component\Yaml;
  25568. use Symfony\Component\Yaml\Exception\ParseException;
  25569. use Symfony\Component\Yaml\Exception\DumpException;
  25570. /**
  25571. * Inline implements a YAML parser/dumper for the YAML inline syntax.
  25572. *
  25573. * @author Fabien Potencier <fabien@symfony.com>
  25574. */
  25575. class Inline
  25576. {
  25577. const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
  25578. private static $exceptionOnInvalidType = false;
  25579. private static $objectSupport = false;
  25580. private static $objectForMap = false;
  25581. /**
  25582. * Converts a YAML string to a PHP array.
  25583. *
  25584. * @param string $value A YAML string
  25585. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  25586. * @param bool $objectSupport true if object support is enabled, false otherwise
  25587. * @param bool $objectForMap true if maps should return a stdClass instead of array()
  25588. * @param array $references Mapping of variable names to values
  25589. *
  25590. * @return array A PHP array representing the YAML string
  25591. *
  25592. * @throws ParseException
  25593. */
  25594. public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array())
  25595. {
  25596. self::$exceptionOnInvalidType = $exceptionOnInvalidType;
  25597. self::$objectSupport = $objectSupport;
  25598. self::$objectForMap = $objectForMap;
  25599. $value = trim($value);
  25600. if (0 == strlen($value)) {
  25601. return '';
  25602. }
  25603. if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
  25604. $mbEncoding = mb_internal_encoding();
  25605. mb_internal_encoding('ASCII');
  25606. }
  25607. $i = 0;
  25608. switch ($value[0]) {
  25609. case '[':
  25610. $result = self::parseSequence($value, $i, $references);
  25611. ++$i;
  25612. break;
  25613. case '{':
  25614. $result = self::parseMapping($value, $i, $references);
  25615. ++$i;
  25616. break;
  25617. default:
  25618. $result = self::parseScalar($value, null, array('"', "'"), $i, true, $references);
  25619. }
  25620. // some comments are allowed at the end
  25621. if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
  25622. throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)));
  25623. }
  25624. if (isset($mbEncoding)) {
  25625. mb_internal_encoding($mbEncoding);
  25626. }
  25627. return $result;
  25628. }
  25629. /**
  25630. * Dumps a given PHP variable to a YAML string.
  25631. *
  25632. * @param mixed $value The PHP variable to convert
  25633. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  25634. * @param bool $objectSupport true if object support is enabled, false otherwise
  25635. *
  25636. * @return string The YAML string representing the PHP array
  25637. *
  25638. * @throws DumpException When trying to dump PHP resource
  25639. */
  25640. public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false)
  25641. {
  25642. switch (true) {
  25643. case is_resource($value):
  25644. if ($exceptionOnInvalidType) {
  25645. throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
  25646. }
  25647. return 'null';
  25648. case is_object($value):
  25649. if ($objectSupport) {
  25650. return '!!php/object:'.serialize($value);
  25651. }
  25652. if ($exceptionOnInvalidType) {
  25653. throw new DumpException('Object support when dumping a YAML file has been disabled.');
  25654. }
  25655. return 'null';
  25656. case is_array($value):
  25657. return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport);
  25658. case null === $value:
  25659. return 'null';
  25660. case true === $value:
  25661. return 'true';
  25662. case false === $value:
  25663. return 'false';
  25664. case ctype_digit($value):
  25665. return is_string($value) ? "'$value'" : (int) $value;
  25666. case is_numeric($value):
  25667. $locale = setlocale(LC_NUMERIC, 0);
  25668. if (false !== $locale) {
  25669. setlocale(LC_NUMERIC, 'C');
  25670. }
  25671. if (is_float($value)) {
  25672. $repr = (string) $value;
  25673. if (is_infinite($value)) {
  25674. $repr = str_ireplace('INF', '.Inf', $repr);
  25675. } elseif (floor($value) == $value && $repr == $value) {
  25676. // Preserve float data type since storing a whole number will result in integer value.
  25677. $repr = '!!float '.$repr;
  25678. }
  25679. } else {
  25680. $repr = is_string($value) ? "'$value'" : (string) $value;
  25681. }
  25682. if (false !== $locale) {
  25683. setlocale(LC_NUMERIC, $locale);
  25684. }
  25685. return $repr;
  25686. case '' == $value:
  25687. return "''";
  25688. case Escaper::requiresDoubleQuoting($value):
  25689. return Escaper::escapeWithDoubleQuotes($value);
  25690. case Escaper::requiresSingleQuoting($value):
  25691. case preg_match(self::getHexRegex(), $value):
  25692. case preg_match(self::getTimestampRegex(), $value):
  25693. return Escaper::escapeWithSingleQuotes($value);
  25694. default:
  25695. return $value;
  25696. }
  25697. }
  25698. /**
  25699. * Dumps a PHP array to a YAML string.
  25700. *
  25701. * @param array $value The PHP array to dump
  25702. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  25703. * @param bool $objectSupport true if object support is enabled, false otherwise
  25704. *
  25705. * @return string The YAML string representing the PHP array
  25706. */
  25707. private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport)
  25708. {
  25709. // array
  25710. $keys = array_keys($value);
  25711. $keysCount = count($keys);
  25712. if ((1 === $keysCount && '0' == $keys[0])
  25713. || ($keysCount > 1 && array_reduce($keys, function ($v, $w) { return (int) $v + $w; }, 0) === $keysCount * ($keysCount - 1) / 2)
  25714. ) {
  25715. $output = array();
  25716. foreach ($value as $val) {
  25717. $output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport);
  25718. }
  25719. return sprintf('[%s]', implode(', ', $output));
  25720. }
  25721. // mapping
  25722. $output = array();
  25723. foreach ($value as $key => $val) {
  25724. $output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport));
  25725. }
  25726. return sprintf('{ %s }', implode(', ', $output));
  25727. }
  25728. /**
  25729. * Parses a scalar to a YAML string.
  25730. *
  25731. * @param string $scalar
  25732. * @param string $delimiters
  25733. * @param array $stringDelimiters
  25734. * @param int &$i
  25735. * @param bool $evaluate
  25736. * @param array $references
  25737. *
  25738. * @return string A YAML string
  25739. *
  25740. * @throws ParseException When malformed inline YAML string is parsed
  25741. */
  25742. public static function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array())
  25743. {
  25744. if (in_array($scalar[$i], $stringDelimiters)) {
  25745. // quoted scalar
  25746. $output = self::parseQuotedScalar($scalar, $i);
  25747. if (null !== $delimiters) {
  25748. $tmp = ltrim(substr($scalar, $i), ' ');
  25749. if (!in_array($tmp[0], $delimiters)) {
  25750. throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)));
  25751. }
  25752. }
  25753. } else {
  25754. // "normal" string
  25755. if (!$delimiters) {
  25756. $output = substr($scalar, $i);
  25757. $i += strlen($output);
  25758. // remove comments
  25759. if (false !== $strpos = strpos($output, ' #')) {
  25760. $output = rtrim(substr($output, 0, $strpos));
  25761. }
  25762. } elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
  25763. $output = $match[1];
  25764. $i += strlen($output);
  25765. } else {
  25766. throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
  25767. }
  25768. if ($evaluate) {
  25769. $output = self::evaluateScalar($output, $references);
  25770. }
  25771. }
  25772. return $output;
  25773. }
  25774. /**
  25775. * Parses a quoted scalar to YAML.
  25776. *
  25777. * @param string $scalar
  25778. * @param int &$i
  25779. *
  25780. * @return string A YAML string
  25781. *
  25782. * @throws ParseException When malformed inline YAML string is parsed
  25783. */
  25784. private static function parseQuotedScalar($scalar, &$i)
  25785. {
  25786. if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
  25787. throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
  25788. }
  25789. $output = substr($match[0], 1, strlen($match[0]) - 2);
  25790. $unescaper = new Unescaper();
  25791. if ('"' == $scalar[$i]) {
  25792. $output = $unescaper->unescapeDoubleQuotedString($output);
  25793. } else {
  25794. $output = $unescaper->unescapeSingleQuotedString($output);
  25795. }
  25796. $i += strlen($match[0]);
  25797. return $output;
  25798. }
  25799. /**
  25800. * Parses a sequence to a YAML string.
  25801. *
  25802. * @param string $sequence
  25803. * @param int &$i
  25804. * @param array $references
  25805. *
  25806. * @return string A YAML string
  25807. *
  25808. * @throws ParseException When malformed inline YAML string is parsed
  25809. */
  25810. private static function parseSequence($sequence, &$i = 0, $references = array())
  25811. {
  25812. $output = array();
  25813. $len = strlen($sequence);
  25814. ++$i;
  25815. // [foo, bar, ...]
  25816. while ($i < $len) {
  25817. switch ($sequence[$i]) {
  25818. case '[':
  25819. // nested sequence
  25820. $output[] = self::parseSequence($sequence, $i, $references);
  25821. break;
  25822. case '{':
  25823. // nested mapping
  25824. $output[] = self::parseMapping($sequence, $i, $references);
  25825. break;
  25826. case ']':
  25827. return $output;
  25828. case ',':
  25829. case ' ':
  25830. break;
  25831. default:
  25832. $isQuoted = in_array($sequence[$i], array('"', "'"));
  25833. $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i, true, $references);
  25834. // the value can be an array if a reference has been resolved to an array var
  25835. if (!is_array($value) && !$isQuoted && false !== strpos($value, ': ')) {
  25836. // embedded mapping?
  25837. try {
  25838. $pos = 0;
  25839. $value = self::parseMapping('{'.$value.'}', $pos, $references);
  25840. } catch (\InvalidArgumentException $e) {
  25841. // no, it's not
  25842. }
  25843. }
  25844. $output[] = $value;
  25845. --$i;
  25846. }
  25847. ++$i;
  25848. }
  25849. throw new ParseException(sprintf('Malformed inline YAML string %s', $sequence));
  25850. }
  25851. /**
  25852. * Parses a mapping to a YAML string.
  25853. *
  25854. * @param string $mapping
  25855. * @param int &$i
  25856. * @param array $references
  25857. *
  25858. * @return string A YAML string
  25859. *
  25860. * @throws ParseException When malformed inline YAML string is parsed
  25861. */
  25862. private static function parseMapping($mapping, &$i = 0, $references = array())
  25863. {
  25864. $output = array();
  25865. $len = strlen($mapping);
  25866. ++$i;
  25867. // {foo: bar, bar:foo, ...}
  25868. while ($i < $len) {
  25869. switch ($mapping[$i]) {
  25870. case ' ':
  25871. case ',':
  25872. ++$i;
  25873. continue 2;
  25874. case '}':
  25875. if (self::$objectForMap) {
  25876. return (object) $output;
  25877. }
  25878. return $output;
  25879. }
  25880. // key
  25881. $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
  25882. // value
  25883. $done = false;
  25884. while ($i < $len) {
  25885. switch ($mapping[$i]) {
  25886. case '[':
  25887. // nested sequence
  25888. $value = self::parseSequence($mapping, $i, $references);
  25889. // Spec: Keys MUST be unique; first one wins.
  25890. // Parser cannot abort this mapping earlier, since lines
  25891. // are processed sequentially.
  25892. if (!isset($output[$key])) {
  25893. $output[$key] = $value;
  25894. }
  25895. $done = true;
  25896. break;
  25897. case '{':
  25898. // nested mapping
  25899. $value = self::parseMapping($mapping, $i, $references);
  25900. // Spec: Keys MUST be unique; first one wins.
  25901. // Parser cannot abort this mapping earlier, since lines
  25902. // are processed sequentially.
  25903. if (!isset($output[$key])) {
  25904. $output[$key] = $value;
  25905. }
  25906. $done = true;
  25907. break;
  25908. case ':':
  25909. case ' ':
  25910. break;
  25911. default:
  25912. $value = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i, true, $references);
  25913. // Spec: Keys MUST be unique; first one wins.
  25914. // Parser cannot abort this mapping earlier, since lines
  25915. // are processed sequentially.
  25916. if (!isset($output[$key])) {
  25917. $output[$key] = $value;
  25918. }
  25919. $done = true;
  25920. --$i;
  25921. }
  25922. ++$i;
  25923. if ($done) {
  25924. continue 2;
  25925. }
  25926. }
  25927. }
  25928. throw new ParseException(sprintf('Malformed inline YAML string %s', $mapping));
  25929. }
  25930. /**
  25931. * Evaluates scalars and replaces magic values.
  25932. *
  25933. * @param string $scalar
  25934. * @param array $references
  25935. *
  25936. * @return string A YAML string
  25937. *
  25938. * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved
  25939. */
  25940. private static function evaluateScalar($scalar, $references = array())
  25941. {
  25942. $scalar = trim($scalar);
  25943. $scalarLower = strtolower($scalar);
  25944. if (0 === strpos($scalar, '*')) {
  25945. if (false !== $pos = strpos($scalar, '#')) {
  25946. $value = substr($scalar, 1, $pos - 2);
  25947. } else {
  25948. $value = substr($scalar, 1);
  25949. }
  25950. // an unquoted *
  25951. if (false === $value || '' === $value) {
  25952. throw new ParseException('A reference must contain at least one character.');
  25953. }
  25954. if (!array_key_exists($value, $references)) {
  25955. throw new ParseException(sprintf('Reference "%s" does not exist.', $value));
  25956. }
  25957. return $references[$value];
  25958. }
  25959. switch (true) {
  25960. case 'null' === $scalarLower:
  25961. case '' === $scalar:
  25962. case '~' === $scalar:
  25963. return;
  25964. case 'true' === $scalarLower:
  25965. return true;
  25966. case 'false' === $scalarLower:
  25967. return false;
  25968. // Optimise for returning strings.
  25969. case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]):
  25970. switch (true) {
  25971. case 0 === strpos($scalar, '!str'):
  25972. return (string) substr($scalar, 5);
  25973. case 0 === strpos($scalar, '! '):
  25974. return (int) self::parseScalar(substr($scalar, 2));
  25975. case 0 === strpos($scalar, '!!php/object:'):
  25976. if (self::$objectSupport) {
  25977. return unserialize(substr($scalar, 13));
  25978. }
  25979. if (self::$exceptionOnInvalidType) {
  25980. throw new ParseException('Object support when parsing a YAML file has been disabled.');
  25981. }
  25982. return;
  25983. case 0 === strpos($scalar, '!!float '):
  25984. return (float) substr($scalar, 8);
  25985. case ctype_digit($scalar):
  25986. $raw = $scalar;
  25987. $cast = (int) $scalar;
  25988. return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
  25989. case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
  25990. $raw = $scalar;
  25991. $cast = (int) $scalar;
  25992. return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
  25993. case is_numeric($scalar):
  25994. case preg_match(self::getHexRegex(), $scalar):
  25995. return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar;
  25996. case '.inf' === $scalarLower:
  25997. case '.nan' === $scalarLower:
  25998. return -log(0);
  25999. case '-.inf' === $scalarLower:
  26000. return log(0);
  26001. case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
  26002. return (float) str_replace(',', '', $scalar);
  26003. case preg_match(self::getTimestampRegex(), $scalar):
  26004. return strtotime($scalar);
  26005. }
  26006. default:
  26007. return (string) $scalar;
  26008. }
  26009. }
  26010. /**
  26011. * Gets a regex that matches a YAML date.
  26012. *
  26013. * @return string The regular expression
  26014. *
  26015. * @see http://www.yaml.org/spec/1.2/spec.html#id2761573
  26016. */
  26017. private static function getTimestampRegex()
  26018. {
  26019. return <<<EOF
  26020. ~^
  26021. (?P<year>[0-9][0-9][0-9][0-9])
  26022. -(?P<month>[0-9][0-9]?)
  26023. -(?P<day>[0-9][0-9]?)
  26024. (?:(?:[Tt]|[ \t]+)
  26025. (?P<hour>[0-9][0-9]?)
  26026. :(?P<minute>[0-9][0-9])
  26027. :(?P<second>[0-9][0-9])
  26028. (?:\.(?P<fraction>[0-9]*))?
  26029. (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
  26030. (?::(?P<tz_minute>[0-9][0-9]))?))?)?
  26031. $~x
  26032. EOF;
  26033. }
  26034. /**
  26035. * Gets a regex that matches a YAML number in hexadecimal notation.
  26036. *
  26037. * @return string
  26038. */
  26039. private static function getHexRegex()
  26040. {
  26041. return '~^0x[0-9a-f]++$~i';
  26042. }
  26043. }
  26044. <?php
  26045. /*
  26046. * This file is part of the Symfony package.
  26047. *
  26048. * (c) Fabien Potencier <fabien@symfony.com>
  26049. *
  26050. * For the full copyright and license information, please view the LICENSE
  26051. * file that was distributed with this source code.
  26052. */
  26053. namespace Symfony\Component\Yaml;
  26054. /**
  26055. * Unescaper encapsulates unescaping rules for single and double-quoted
  26056. * YAML strings.
  26057. *
  26058. * @author Matthew Lewinski <matthew@lewinski.org>
  26059. */
  26060. class Unescaper
  26061. {
  26062. /**
  26063. * Parser and Inline assume UTF-8 encoding, so escaped Unicode characters
  26064. * must be converted to that encoding.
  26065. *
  26066. * @deprecated since version 2.5, to be removed in 3.0
  26067. * @internal
  26068. */
  26069. const ENCODING = 'UTF-8';
  26070. /**
  26071. * Regex fragment that matches an escaped character in a double quoted string.
  26072. */
  26073. const REGEX_ESCAPED_CHARACTER = "\\\\([0abt\tnvfre \\\"\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})";
  26074. /**
  26075. * Unescapes a single quoted string.
  26076. *
  26077. * @param string $value A single quoted string.
  26078. *
  26079. * @return string The unescaped string.
  26080. */
  26081. public function unescapeSingleQuotedString($value)
  26082. {
  26083. return str_replace('\'\'', '\'', $value);
  26084. }
  26085. /**
  26086. * Unescapes a double quoted string.
  26087. *
  26088. * @param string $value A double quoted string.
  26089. *
  26090. * @return string The unescaped string.
  26091. */
  26092. public function unescapeDoubleQuotedString($value)
  26093. {
  26094. $self = $this;
  26095. $callback = function ($match) use ($self) {
  26096. return $self->unescapeCharacter($match[0]);
  26097. };
  26098. // evaluate the string
  26099. return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
  26100. }
  26101. /**
  26102. * Unescapes a character that was found in a double-quoted string.
  26103. *
  26104. * @param string $value An escaped character
  26105. *
  26106. * @return string The unescaped character
  26107. */
  26108. public function unescapeCharacter($value)
  26109. {
  26110. switch ($value{1}) {
  26111. case '0':
  26112. return "\x0";
  26113. case 'a':
  26114. return "\x7";
  26115. case 'b':
  26116. return "\x8";
  26117. case 't':
  26118. return "\t";
  26119. case "\t":
  26120. return "\t";
  26121. case 'n':
  26122. return "\n";
  26123. case 'v':
  26124. return "\xB";
  26125. case 'f':
  26126. return "\xC";
  26127. case 'r':
  26128. return "\r";
  26129. case 'e':
  26130. return "\x1B";
  26131. case ' ':
  26132. return ' ';
  26133. case '"':
  26134. return '"';
  26135. case '/':
  26136. return '/';
  26137. case '\\':
  26138. return '\\';
  26139. case 'N':
  26140. // U+0085 NEXT LINE
  26141. return "\xC2\x85";
  26142. case '_':
  26143. // U+00A0 NO-BREAK SPACE
  26144. return "\xC2\xA0";
  26145. case 'L':
  26146. // U+2028 LINE SEPARATOR
  26147. return "\xE2\x80\xA8";
  26148. case 'P':
  26149. // U+2029 PARAGRAPH SEPARATOR
  26150. return "\xE2\x80\xA9";
  26151. case 'x':
  26152. return self::utf8chr(hexdec(substr($value, 2, 2)));
  26153. case 'u':
  26154. return self::utf8chr(hexdec(substr($value, 2, 4)));
  26155. case 'U':
  26156. return self::utf8chr(hexdec(substr($value, 2, 8)));
  26157. }
  26158. }
  26159. /**
  26160. * Get the UTF-8 character for the given code point.
  26161. *
  26162. * @param int $c The unicode code point
  26163. *
  26164. * @return string The corresponding UTF-8 character
  26165. */
  26166. private static function utf8chr($c)
  26167. {
  26168. if (0x80 > $c %= 0x200000) {
  26169. return chr($c);
  26170. }
  26171. if (0x800 > $c) {
  26172. return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
  26173. }
  26174. if (0x10000 > $c) {
  26175. return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
  26176. }
  26177. return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
  26178. }
  26179. }
  26180. <?php
  26181. /*
  26182. * This file is part of the Symfony package.
  26183. *
  26184. * (c) Fabien Potencier <fabien@symfony.com>
  26185. *
  26186. * For the full copyright and license information, please view the LICENSE
  26187. * file that was distributed with this source code.
  26188. */
  26189. namespace Symfony\Component\Yaml;
  26190. use Symfony\Component\Yaml\Exception\ParseException;
  26191. /**
  26192. * Yaml offers convenience methods to load and dump YAML.
  26193. *
  26194. * @author Fabien Potencier <fabien@symfony.com>
  26195. *
  26196. * @api
  26197. */
  26198. class Yaml
  26199. {
  26200. /**
  26201. * Parses YAML into a PHP array.
  26202. *
  26203. * The parse method, when supplied with a YAML stream (string or file),
  26204. * will do its best to convert YAML in a file into a PHP array.
  26205. *
  26206. * Usage:
  26207. * <code>
  26208. * $array = Yaml::parse(file_get_contents('config.yml'));
  26209. * print_r($array);
  26210. * </code>
  26211. *
  26212. * As this method accepts both plain strings and file names as an input,
  26213. * you must validate the input before calling this method. Passing a file
  26214. * as an input is a deprecated feature and will be removed in 3.0.
  26215. *
  26216. * @param string $input Path to a YAML file or a string containing YAML
  26217. * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
  26218. * @param bool $objectSupport True if object support is enabled, false otherwise
  26219. * @param bool $objectForMap True if maps should return a stdClass instead of array()
  26220. *
  26221. * @return array The YAML converted to a PHP array
  26222. *
  26223. * @throws ParseException If the YAML is not valid
  26224. *
  26225. * @deprecated The ability to pass file names to the Yaml::parse method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.
  26226. *
  26227. * @api
  26228. */
  26229. public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
  26230. {
  26231. // if input is a file, process it
  26232. $file = '';
  26233. if (strpos($input, "\n") === false && is_file($input)) {
  26234. trigger_error('The ability to pass file names to the '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.', E_USER_DEPRECATED);
  26235. if (false === is_readable($input)) {
  26236. throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input));
  26237. }
  26238. $file = $input;
  26239. $input = file_get_contents($file);
  26240. }
  26241. $yaml = new Parser();
  26242. try {
  26243. return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26244. } catch (ParseException $e) {
  26245. if ($file) {
  26246. $e->setParsedFile($file);
  26247. }
  26248. throw $e;
  26249. }
  26250. }
  26251. /**
  26252. * Dumps a PHP array to a YAML string.
  26253. *
  26254. * The dump method, when supplied with an array, will do its best
  26255. * to convert the array into friendly YAML.
  26256. *
  26257. * @param array $array PHP array
  26258. * @param int $inline The level where you switch to inline YAML
  26259. * @param int $indent The amount of spaces to use for indentation of nested nodes.
  26260. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  26261. * @param bool $objectSupport true if object support is enabled, false otherwise
  26262. *
  26263. * @return string A YAML string representing the original PHP array
  26264. *
  26265. * @api
  26266. */
  26267. public static function dump($array, $inline = 2, $indent = 4, $exceptionOnInvalidType = false, $objectSupport = false)
  26268. {
  26269. $yaml = new Dumper();
  26270. $yaml->setIndentation($indent);
  26271. return $yaml->dump($array, $inline, 0, $exceptionOnInvalidType, $objectSupport);
  26272. }
  26273. }
  26274. <?php
  26275. /*
  26276. * This file is part of the Symfony package.
  26277. *
  26278. * (c) Fabien Potencier <fabien@symfony.com>
  26279. *
  26280. * For the full copyright and license information, please view the LICENSE
  26281. * file that was distributed with this source code.
  26282. */
  26283. namespace Symfony\Component\Yaml\Exception;
  26284. /**
  26285. * Exception class thrown when an error occurs during parsing.
  26286. *
  26287. * @author Fabien Potencier <fabien@symfony.com>
  26288. *
  26289. * @api
  26290. */
  26291. class ParseException extends RuntimeException
  26292. {
  26293. private $parsedFile;
  26294. private $parsedLine;
  26295. private $snippet;
  26296. private $rawMessage;
  26297. /**
  26298. * Constructor.
  26299. *
  26300. * @param string $message The error message
  26301. * @param int $parsedLine The line where the error occurred
  26302. * @param int $snippet The snippet of code near the problem
  26303. * @param string $parsedFile The file name where the error occurred
  26304. * @param \Exception $previous The previous exception
  26305. */
  26306. public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null)
  26307. {
  26308. $this->parsedFile = $parsedFile;
  26309. $this->parsedLine = $parsedLine;
  26310. $this->snippet = $snippet;
  26311. $this->rawMessage = $message;
  26312. $this->updateRepr();
  26313. parent::__construct($this->message, 0, $previous);
  26314. }
  26315. /**
  26316. * Gets the snippet of code near the error.
  26317. *
  26318. * @return string The snippet of code
  26319. */
  26320. public function getSnippet()
  26321. {
  26322. return $this->snippet;
  26323. }
  26324. /**
  26325. * Sets the snippet of code near the error.
  26326. *
  26327. * @param string $snippet The code snippet
  26328. */
  26329. public function setSnippet($snippet)
  26330. {
  26331. $this->snippet = $snippet;
  26332. $this->updateRepr();
  26333. }
  26334. /**
  26335. * Gets the filename where the error occurred.
  26336. *
  26337. * This method returns null if a string is parsed.
  26338. *
  26339. * @return string The filename
  26340. */
  26341. public function getParsedFile()
  26342. {
  26343. return $this->parsedFile;
  26344. }
  26345. /**
  26346. * Sets the filename where the error occurred.
  26347. *
  26348. * @param string $parsedFile The filename
  26349. */
  26350. public function setParsedFile($parsedFile)
  26351. {
  26352. $this->parsedFile = $parsedFile;
  26353. $this->updateRepr();
  26354. }
  26355. /**
  26356. * Gets the line where the error occurred.
  26357. *
  26358. * @return int The file line
  26359. */
  26360. public function getParsedLine()
  26361. {
  26362. return $this->parsedLine;
  26363. }
  26364. /**
  26365. * Sets the line where the error occurred.
  26366. *
  26367. * @param int $parsedLine The file line
  26368. */
  26369. public function setParsedLine($parsedLine)
  26370. {
  26371. $this->parsedLine = $parsedLine;
  26372. $this->updateRepr();
  26373. }
  26374. private function updateRepr()
  26375. {
  26376. $this->message = $this->rawMessage;
  26377. $dot = false;
  26378. if ('.' === substr($this->message, -1)) {
  26379. $this->message = substr($this->message, 0, -1);
  26380. $dot = true;
  26381. }
  26382. if (null !== $this->parsedFile) {
  26383. if (PHP_VERSION_ID >= 50400) {
  26384. $jsonOptions = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
  26385. } else {
  26386. $jsonOptions = 0;
  26387. }
  26388. $this->message .= sprintf(' in %s', json_encode($this->parsedFile, $jsonOptions));
  26389. }
  26390. if ($this->parsedLine >= 0) {
  26391. $this->message .= sprintf(' at line %d', $this->parsedLine);
  26392. }
  26393. if ($this->snippet) {
  26394. $this->message .= sprintf(' (near "%s")', $this->snippet);
  26395. }
  26396. if ($dot) {
  26397. $this->message .= '.';
  26398. }
  26399. }
  26400. }
  26401. <?php
  26402. /*
  26403. * This file is part of the Symfony package.
  26404. *
  26405. * (c) Fabien Potencier <fabien@symfony.com>
  26406. *
  26407. * For the full copyright and license information, please view the LICENSE
  26408. * file that was distributed with this source code.
  26409. */
  26410. namespace Symfony\Component\Yaml\Exception;
  26411. /**
  26412. * Exception class thrown when an error occurs during dumping.
  26413. *
  26414. * @author Fabien Potencier <fabien@symfony.com>
  26415. *
  26416. * @api
  26417. */
  26418. class DumpException extends RuntimeException
  26419. {
  26420. }
  26421. <?php
  26422. /*
  26423. * This file is part of the Symfony package.
  26424. *
  26425. * (c) Fabien Potencier <fabien@symfony.com>
  26426. *
  26427. * For the full copyright and license information, please view the LICENSE
  26428. * file that was distributed with this source code.
  26429. */
  26430. namespace Symfony\Component\Yaml\Exception;
  26431. /**
  26432. * Exception class thrown when an error occurs during parsing.
  26433. *
  26434. * @author Romain Neutron <imprec@gmail.com>
  26435. *
  26436. * @api
  26437. */
  26438. class RuntimeException extends \RuntimeException implements ExceptionInterface
  26439. {
  26440. }
  26441. <?php
  26442. /*
  26443. * This file is part of the Symfony package.
  26444. *
  26445. * (c) Fabien Potencier <fabien@symfony.com>
  26446. *
  26447. * For the full copyright and license information, please view the LICENSE
  26448. * file that was distributed with this source code.
  26449. */
  26450. namespace Symfony\Component\Yaml\Exception;
  26451. /**
  26452. * Exception interface for all exceptions thrown by the component.
  26453. *
  26454. * @author Fabien Potencier <fabien@symfony.com>
  26455. *
  26456. * @api
  26457. */
  26458. interface ExceptionInterface
  26459. {
  26460. }
  26461. <?php
  26462. /*
  26463. * This file is part of the Symfony package.
  26464. *
  26465. * (c) Fabien Potencier <fabien@symfony.com>
  26466. *
  26467. * For the full copyright and license information, please view the LICENSE
  26468. * file that was distributed with this source code.
  26469. */
  26470. namespace Symfony\Component\Yaml;
  26471. use Symfony\Component\Yaml\Exception\ParseException;
  26472. /**
  26473. * Parser parses YAML strings to convert them to PHP arrays.
  26474. *
  26475. * @author Fabien Potencier <fabien@symfony.com>
  26476. */
  26477. class Parser
  26478. {
  26479. const FOLDED_SCALAR_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
  26480. private $offset = 0;
  26481. private $lines = array();
  26482. private $currentLineNb = -1;
  26483. private $currentLine = '';
  26484. private $refs = array();
  26485. /**
  26486. * Constructor.
  26487. *
  26488. * @param int $offset The offset of YAML document (used for line numbers in error messages)
  26489. */
  26490. public function __construct($offset = 0)
  26491. {
  26492. $this->offset = $offset;
  26493. }
  26494. /**
  26495. * Parses a YAML string to a PHP value.
  26496. *
  26497. * @param string $value A YAML string
  26498. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  26499. * @param bool $objectSupport true if object support is enabled, false otherwise
  26500. * @param bool $objectForMap true if maps should return a stdClass instead of array()
  26501. *
  26502. * @return mixed A PHP value
  26503. *
  26504. * @throws ParseException If the YAML is not valid
  26505. */
  26506. public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
  26507. {
  26508. if (!preg_match('//u', $value)) {
  26509. throw new ParseException('The YAML value does not appear to be valid UTF-8.');
  26510. }
  26511. $this->currentLineNb = -1;
  26512. $this->currentLine = '';
  26513. $value = $this->cleanup($value);
  26514. $this->lines = explode("\n", $value);
  26515. if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
  26516. $mbEncoding = mb_internal_encoding();
  26517. mb_internal_encoding('UTF-8');
  26518. }
  26519. $data = array();
  26520. $context = null;
  26521. $allowOverwrite = false;
  26522. while ($this->moveToNextLine()) {
  26523. if ($this->isCurrentLineEmpty()) {
  26524. continue;
  26525. }
  26526. // tab?
  26527. if ("\t" === $this->currentLine[0]) {
  26528. throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26529. }
  26530. $isRef = $mergeNode = false;
  26531. if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
  26532. if ($context && 'mapping' == $context) {
  26533. throw new ParseException('You cannot define a sequence item when in a mapping');
  26534. }
  26535. $context = 'sequence';
  26536. if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
  26537. $isRef = $matches['ref'];
  26538. $values['value'] = $matches['value'];
  26539. }
  26540. // array
  26541. if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
  26542. $c = $this->getRealCurrentLineNb() + 1;
  26543. $parser = new self($c);
  26544. $parser->refs = &$this->refs;
  26545. $data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26546. } else {
  26547. if (isset($values['leadspaces'])
  26548. && preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
  26549. ) {
  26550. // this is a compact notation element, add to next block and parse
  26551. $c = $this->getRealCurrentLineNb();
  26552. $parser = new self($c);
  26553. $parser->refs = &$this->refs;
  26554. $block = $values['value'];
  26555. if ($this->isNextLineIndented()) {
  26556. $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + strlen($values['leadspaces']) + 1);
  26557. }
  26558. $data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26559. } else {
  26560. $data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26561. }
  26562. }
  26563. } elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) {
  26564. if ($context && 'sequence' == $context) {
  26565. throw new ParseException('You cannot define a mapping item when in a sequence');
  26566. }
  26567. $context = 'mapping';
  26568. // force correct settings
  26569. Inline::parse(null, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
  26570. try {
  26571. $key = Inline::parseScalar($values['key']);
  26572. } catch (ParseException $e) {
  26573. $e->setParsedLine($this->getRealCurrentLineNb() + 1);
  26574. $e->setSnippet($this->currentLine);
  26575. throw $e;
  26576. }
  26577. if ('<<' === $key) {
  26578. $mergeNode = true;
  26579. $allowOverwrite = true;
  26580. if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
  26581. $refName = substr($values['value'], 1);
  26582. if (!array_key_exists($refName, $this->refs)) {
  26583. throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26584. }
  26585. $refValue = $this->refs[$refName];
  26586. if (!is_array($refValue)) {
  26587. throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26588. }
  26589. foreach ($refValue as $key => $value) {
  26590. if (!isset($data[$key])) {
  26591. $data[$key] = $value;
  26592. }
  26593. }
  26594. } else {
  26595. if (isset($values['value']) && $values['value'] !== '') {
  26596. $value = $values['value'];
  26597. } else {
  26598. $value = $this->getNextEmbedBlock();
  26599. }
  26600. $c = $this->getRealCurrentLineNb() + 1;
  26601. $parser = new self($c);
  26602. $parser->refs = &$this->refs;
  26603. $parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26604. if (!is_array($parsed)) {
  26605. throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26606. }
  26607. if (isset($parsed[0])) {
  26608. // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes
  26609. // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
  26610. // in the sequence override keys specified in later mapping nodes.
  26611. foreach ($parsed as $parsedItem) {
  26612. if (!is_array($parsedItem)) {
  26613. throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
  26614. }
  26615. foreach ($parsedItem as $key => $value) {
  26616. if (!isset($data[$key])) {
  26617. $data[$key] = $value;
  26618. }
  26619. }
  26620. }
  26621. } else {
  26622. // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the
  26623. // current mapping, unless the key already exists in it.
  26624. foreach ($parsed as $key => $value) {
  26625. if (!isset($data[$key])) {
  26626. $data[$key] = $value;
  26627. }
  26628. }
  26629. }
  26630. }
  26631. } elseif (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
  26632. $isRef = $matches['ref'];
  26633. $values['value'] = $matches['value'];
  26634. }
  26635. if ($mergeNode) {
  26636. // Merge keys
  26637. } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
  26638. // hash
  26639. // if next line is less indented or equal, then it means that the current value is null
  26640. if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
  26641. // Spec: Keys MUST be unique; first one wins.
  26642. // But overwriting is allowed when a merge node is used in current block.
  26643. if ($allowOverwrite || !isset($data[$key])) {
  26644. $data[$key] = null;
  26645. }
  26646. } else {
  26647. $c = $this->getRealCurrentLineNb() + 1;
  26648. $parser = new self($c);
  26649. $parser->refs = &$this->refs;
  26650. $value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26651. // Spec: Keys MUST be unique; first one wins.
  26652. // But overwriting is allowed when a merge node is used in current block.
  26653. if ($allowOverwrite || !isset($data[$key])) {
  26654. $data[$key] = $value;
  26655. }
  26656. }
  26657. } else {
  26658. $value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26659. // Spec: Keys MUST be unique; first one wins.
  26660. // But overwriting is allowed when a merge node is used in current block.
  26661. if ($allowOverwrite || !isset($data[$key])) {
  26662. $data[$key] = $value;
  26663. }
  26664. }
  26665. } else {
  26666. // multiple documents are not supported
  26667. if ('---' === $this->currentLine) {
  26668. throw new ParseException('Multiple documents are not supported.');
  26669. }
  26670. // 1-liner optionally followed by newline(s)
  26671. if ($this->lines[0] === trim($value)) {
  26672. try {
  26673. $value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
  26674. } catch (ParseException $e) {
  26675. $e->setParsedLine($this->getRealCurrentLineNb() + 1);
  26676. $e->setSnippet($this->currentLine);
  26677. throw $e;
  26678. }
  26679. if (is_array($value)) {
  26680. $first = reset($value);
  26681. if (is_string($first) && 0 === strpos($first, '*')) {
  26682. $data = array();
  26683. foreach ($value as $alias) {
  26684. $data[] = $this->refs[substr($alias, 1)];
  26685. }
  26686. $value = $data;
  26687. }
  26688. }
  26689. if (isset($mbEncoding)) {
  26690. mb_internal_encoding($mbEncoding);
  26691. }
  26692. return $value;
  26693. }
  26694. switch (preg_last_error()) {
  26695. case PREG_INTERNAL_ERROR:
  26696. $error = 'Internal PCRE error.';
  26697. break;
  26698. case PREG_BACKTRACK_LIMIT_ERROR:
  26699. $error = 'pcre.backtrack_limit reached.';
  26700. break;
  26701. case PREG_RECURSION_LIMIT_ERROR:
  26702. $error = 'pcre.recursion_limit reached.';
  26703. break;
  26704. case PREG_BAD_UTF8_ERROR:
  26705. $error = 'Malformed UTF-8 data.';
  26706. break;
  26707. case PREG_BAD_UTF8_OFFSET_ERROR:
  26708. $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
  26709. break;
  26710. default:
  26711. $error = 'Unable to parse.';
  26712. }
  26713. throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26714. }
  26715. if ($isRef) {
  26716. $this->refs[$isRef] = end($data);
  26717. }
  26718. }
  26719. if (isset($mbEncoding)) {
  26720. mb_internal_encoding($mbEncoding);
  26721. }
  26722. return empty($data) ? null : $data;
  26723. }
  26724. /**
  26725. * Returns the current line number (takes the offset into account).
  26726. *
  26727. * @return int The current line number
  26728. */
  26729. private function getRealCurrentLineNb()
  26730. {
  26731. return $this->currentLineNb + $this->offset;
  26732. }
  26733. /**
  26734. * Returns the current line indentation.
  26735. *
  26736. * @return int The current line indentation
  26737. */
  26738. private function getCurrentLineIndentation()
  26739. {
  26740. return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
  26741. }
  26742. /**
  26743. * Returns the next embed block of YAML.
  26744. *
  26745. * @param int $indentation The indent level at which the block is to be read, or null for default
  26746. * @param bool $inSequence True if the enclosing data structure is a sequence
  26747. *
  26748. * @return string A YAML string
  26749. *
  26750. * @throws ParseException When indentation problem are detected
  26751. */
  26752. private function getNextEmbedBlock($indentation = null, $inSequence = false)
  26753. {
  26754. $oldLineIndentation = $this->getCurrentLineIndentation();
  26755. if (!$this->moveToNextLine()) {
  26756. return;
  26757. }
  26758. if (null === $indentation) {
  26759. $newIndent = $this->getCurrentLineIndentation();
  26760. $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem($this->currentLine);
  26761. if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
  26762. throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26763. }
  26764. } else {
  26765. $newIndent = $indentation;
  26766. }
  26767. $data = array();
  26768. if ($this->getCurrentLineIndentation() >= $newIndent) {
  26769. $data[] = substr($this->currentLine, $newIndent);
  26770. } else {
  26771. $this->moveToPreviousLine();
  26772. return;
  26773. }
  26774. if ($inSequence && $oldLineIndentation === $newIndent && '-' === $data[0][0]) {
  26775. // the previous line contained a dash but no item content, this line is a sequence item with the same indentation
  26776. // and therefore no nested list or mapping
  26777. $this->moveToPreviousLine();
  26778. return;
  26779. }
  26780. $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem($this->currentLine);
  26781. // Comments must not be removed inside a string block (ie. after a line ending with "|")
  26782. $removeCommentsPattern = '~'.self::FOLDED_SCALAR_PATTERN.'$~';
  26783. $removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
  26784. while ($this->moveToNextLine()) {
  26785. $indent = $this->getCurrentLineIndentation();
  26786. if ($indent === $newIndent) {
  26787. $removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
  26788. }
  26789. if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem($this->currentLine) && $newIndent === $indent) {
  26790. $this->moveToPreviousLine();
  26791. break;
  26792. }
  26793. if ($this->isCurrentLineBlank()) {
  26794. $data[] = substr($this->currentLine, $newIndent);
  26795. continue;
  26796. }
  26797. if ($removeComments && $this->isCurrentLineComment()) {
  26798. continue;
  26799. }
  26800. if ($indent >= $newIndent) {
  26801. $data[] = substr($this->currentLine, $newIndent);
  26802. } elseif (0 == $indent) {
  26803. $this->moveToPreviousLine();
  26804. break;
  26805. } else {
  26806. throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26807. }
  26808. }
  26809. return implode("\n", $data);
  26810. }
  26811. /**
  26812. * Moves the parser to the next line.
  26813. *
  26814. * @return bool
  26815. */
  26816. private function moveToNextLine()
  26817. {
  26818. if ($this->currentLineNb >= count($this->lines) - 1) {
  26819. return false;
  26820. }
  26821. $this->currentLine = $this->lines[++$this->currentLineNb];
  26822. return true;
  26823. }
  26824. /**
  26825. * Moves the parser to the previous line.
  26826. */
  26827. private function moveToPreviousLine()
  26828. {
  26829. $this->currentLine = $this->lines[--$this->currentLineNb];
  26830. }
  26831. /**
  26832. * Parses a YAML value.
  26833. *
  26834. * @param string $value A YAML value
  26835. * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
  26836. * @param bool $objectSupport True if object support is enabled, false otherwise
  26837. * @param bool $objectForMap true if maps should return a stdClass instead of array()
  26838. *
  26839. * @return mixed A PHP value
  26840. *
  26841. * @throws ParseException When reference does not exist
  26842. */
  26843. private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap)
  26844. {
  26845. if (0 === strpos($value, '*')) {
  26846. if (false !== $pos = strpos($value, '#')) {
  26847. $value = substr($value, 1, $pos - 2);
  26848. } else {
  26849. $value = substr($value, 1);
  26850. }
  26851. if (!array_key_exists($value, $this->refs)) {
  26852. throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine);
  26853. }
  26854. return $this->refs[$value];
  26855. }
  26856. if (preg_match('/^'.self::FOLDED_SCALAR_PATTERN.'$/', $value, $matches)) {
  26857. $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
  26858. return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
  26859. }
  26860. try {
  26861. return Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
  26862. } catch (ParseException $e) {
  26863. $e->setParsedLine($this->getRealCurrentLineNb() + 1);
  26864. $e->setSnippet($this->currentLine);
  26865. throw $e;
  26866. }
  26867. }
  26868. /**
  26869. * Parses a folded scalar.
  26870. *
  26871. * @param string $separator The separator that was used to begin this folded scalar (| or >)
  26872. * @param string $indicator The indicator that was used to begin this folded scalar (+ or -)
  26873. * @param int $indentation The indentation that was used to begin this folded scalar
  26874. *
  26875. * @return string The text value
  26876. */
  26877. private function parseFoldedScalar($separator, $indicator = '', $indentation = 0)
  26878. {
  26879. $notEOF = $this->moveToNextLine();
  26880. if (!$notEOF) {
  26881. return '';
  26882. }
  26883. $isCurrentLineBlank = $this->isCurrentLineBlank();
  26884. $text = '';
  26885. // leading blank lines are consumed before determining indentation
  26886. while ($notEOF && $isCurrentLineBlank) {
  26887. // newline only if not EOF
  26888. if ($notEOF = $this->moveToNextLine()) {
  26889. $text .= "\n";
  26890. $isCurrentLineBlank = $this->isCurrentLineBlank();
  26891. }
  26892. }
  26893. // determine indentation if not specified
  26894. if (0 === $indentation) {
  26895. if (preg_match('/^ +/', $this->currentLine, $matches)) {
  26896. $indentation = strlen($matches[0]);
  26897. }
  26898. }
  26899. if ($indentation > 0) {
  26900. $pattern = sprintf('/^ {%d}(.*)$/', $indentation);
  26901. while (
  26902. $notEOF && (
  26903. $isCurrentLineBlank ||
  26904. preg_match($pattern, $this->currentLine, $matches)
  26905. )
  26906. ) {
  26907. if ($isCurrentLineBlank) {
  26908. $text .= substr($this->currentLine, $indentation);
  26909. } else {
  26910. $text .= $matches[1];
  26911. }
  26912. // newline only if not EOF
  26913. if ($notEOF = $this->moveToNextLine()) {
  26914. $text .= "\n";
  26915. $isCurrentLineBlank = $this->isCurrentLineBlank();
  26916. }
  26917. }
  26918. } elseif ($notEOF) {
  26919. $text .= "\n";
  26920. }
  26921. if ($notEOF) {
  26922. $this->moveToPreviousLine();
  26923. }
  26924. // replace all non-trailing single newlines with spaces in folded blocks
  26925. if ('>' === $separator) {
  26926. preg_match('/(\n*)$/', $text, $matches);
  26927. $text = preg_replace('/(?<!\n)\n(?!\n)/', ' ', rtrim($text, "\n"));
  26928. $text .= $matches[1];
  26929. }
  26930. // deal with trailing newlines as indicated
  26931. if ('' === $indicator) {
  26932. $text = preg_replace('/\n+$/s', "\n", $text);
  26933. } elseif ('-' === $indicator) {
  26934. $text = preg_replace('/\n+$/s', '', $text);
  26935. }
  26936. return $text;
  26937. }
  26938. /**
  26939. * Returns true if the next line is indented.
  26940. *
  26941. * @return bool Returns true if the next line is indented, false otherwise
  26942. */
  26943. private function isNextLineIndented()
  26944. {
  26945. $currentIndentation = $this->getCurrentLineIndentation();
  26946. $EOF = !$this->moveToNextLine();
  26947. while (!$EOF && $this->isCurrentLineEmpty()) {
  26948. $EOF = !$this->moveToNextLine();
  26949. }
  26950. if ($EOF) {
  26951. return false;
  26952. }
  26953. $ret = false;
  26954. if ($this->getCurrentLineIndentation() > $currentIndentation) {
  26955. $ret = true;
  26956. }
  26957. $this->moveToPreviousLine();
  26958. return $ret;
  26959. }
  26960. /**
  26961. * Returns true if the current line is blank or if it is a comment line.
  26962. *
  26963. * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise
  26964. */
  26965. private function isCurrentLineEmpty()
  26966. {
  26967. return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
  26968. }
  26969. /**
  26970. * Returns true if the current line is blank.
  26971. *
  26972. * @return bool Returns true if the current line is blank, false otherwise
  26973. */
  26974. private function isCurrentLineBlank()
  26975. {
  26976. return '' == trim($this->currentLine, ' ');
  26977. }
  26978. /**
  26979. * Returns true if the current line is a comment line.
  26980. *
  26981. * @return bool Returns true if the current line is a comment line, false otherwise
  26982. */
  26983. private function isCurrentLineComment()
  26984. {
  26985. //checking explicitly the first char of the trim is faster than loops or strpos
  26986. $ltrimmedLine = ltrim($this->currentLine, ' ');
  26987. return $ltrimmedLine[0] === '#';
  26988. }
  26989. /**
  26990. * Cleanups a YAML string to be parsed.
  26991. *
  26992. * @param string $value The input YAML string
  26993. *
  26994. * @return string A cleaned up YAML string
  26995. */
  26996. private function cleanup($value)
  26997. {
  26998. $value = str_replace(array("\r\n", "\r"), "\n", $value);
  26999. // strip YAML header
  27000. $count = 0;
  27001. $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count);
  27002. $this->offset += $count;
  27003. // remove leading comments
  27004. $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
  27005. if ($count == 1) {
  27006. // items have been removed, update the offset
  27007. $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
  27008. $value = $trimmedValue;
  27009. }
  27010. // remove start of the document marker (---)
  27011. $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
  27012. if ($count == 1) {
  27013. // items have been removed, update the offset
  27014. $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
  27015. $value = $trimmedValue;
  27016. // remove end of the document marker (...)
  27017. $value = preg_replace('#\.\.\.\s*$#s', '', $value);
  27018. }
  27019. return $value;
  27020. }
  27021. /**
  27022. * Returns true if the next line starts unindented collection.
  27023. *
  27024. * @return bool Returns true if the next line starts unindented collection, false otherwise
  27025. */
  27026. private function isNextLineUnIndentedCollection()
  27027. {
  27028. $currentIndentation = $this->getCurrentLineIndentation();
  27029. $notEOF = $this->moveToNextLine();
  27030. while ($notEOF && $this->isCurrentLineEmpty()) {
  27031. $notEOF = $this->moveToNextLine();
  27032. }
  27033. if (false === $notEOF) {
  27034. return false;
  27035. }
  27036. $ret = false;
  27037. if (
  27038. $this->getCurrentLineIndentation() == $currentIndentation
  27039. &&
  27040. $this->isStringUnIndentedCollectionItem($this->currentLine)
  27041. ) {
  27042. $ret = true;
  27043. }
  27044. $this->moveToPreviousLine();
  27045. return $ret;
  27046. }
  27047. /**
  27048. * Returns true if the string is un-indented collection item.
  27049. *
  27050. * @return bool Returns true if the string is un-indented collection item, false otherwise
  27051. */
  27052. private function isStringUnIndentedCollectionItem()
  27053. {
  27054. return (0 === strpos($this->currentLine, '- '));
  27055. }
  27056. }
  27057. <?php
  27058. /*
  27059. * This file is part of the Symfony package.
  27060. *
  27061. * (c) Fabien Potencier <fabien@symfony.com>
  27062. *
  27063. * For the full copyright and license information, please view the LICENSE
  27064. * file that was distributed with this source code.
  27065. */
  27066. namespace Symfony\Component\Yaml;
  27067. /**
  27068. * Dumper dumps PHP variables to YAML strings.
  27069. *
  27070. * @author Fabien Potencier <fabien@symfony.com>
  27071. */
  27072. class Dumper
  27073. {
  27074. /**
  27075. * The amount of spaces to use for indentation of nested nodes.
  27076. *
  27077. * @var int
  27078. */
  27079. protected $indentation = 4;
  27080. /**
  27081. * Sets the indentation.
  27082. *
  27083. * @param int $num The amount of spaces to use for indentation of nested nodes.
  27084. */
  27085. public function setIndentation($num)
  27086. {
  27087. $this->indentation = (int) $num;
  27088. }
  27089. /**
  27090. * Dumps a PHP value to YAML.
  27091. *
  27092. * @param mixed $input The PHP value
  27093. * @param int $inline The level where you switch to inline YAML
  27094. * @param int $indent The level of indentation (used internally)
  27095. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  27096. * @param bool $objectSupport true if object support is enabled, false otherwise
  27097. *
  27098. * @return string The YAML representation of the PHP value
  27099. */
  27100. public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType = false, $objectSupport = false)
  27101. {
  27102. $output = '';
  27103. $prefix = $indent ? str_repeat(' ', $indent) : '';
  27104. if ($inline <= 0 || !is_array($input) || empty($input)) {
  27105. $output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport);
  27106. } else {
  27107. $isAHash = array_keys($input) !== range(0, count($input) - 1);
  27108. foreach ($input as $key => $value) {
  27109. $willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);
  27110. $output .= sprintf('%s%s%s%s',
  27111. $prefix,
  27112. $isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-',
  27113. $willBeInlined ? ' ' : "\n",
  27114. $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport)
  27115. ).($willBeInlined ? "\n" : '');
  27116. }
  27117. }
  27118. return $output;
  27119. }
  27120. }
  27121. <?php
  27122. /*
  27123. * This file is part of the Symfony package.
  27124. *
  27125. * (c) Fabien Potencier <fabien@symfony.com>
  27126. *
  27127. * For the full copyright and license information, please view the LICENSE
  27128. * file that was distributed with this source code.
  27129. */
  27130. namespace Symfony\Component\Yaml;
  27131. /**
  27132. * Escaper encapsulates escaping rules for single and double-quoted
  27133. * YAML strings.
  27134. *
  27135. * @author Matthew Lewinski <matthew@lewinski.org>
  27136. */
  27137. class Escaper
  27138. {
  27139. // Characters that would cause a dumped string to require double quoting.
  27140. const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
  27141. // Mapping arrays for escaping a double quoted string. The backslash is
  27142. // first to ensure proper escaping because str_replace operates iteratively
  27143. // on the input arrays. This ordering of the characters avoids the use of strtr,
  27144. // which performs more slowly.
  27145. private static $escapees = array('\\', '\\\\', '\\"', '"',
  27146. "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
  27147. "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
  27148. "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
  27149. "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
  27150. "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9",);
  27151. private static $escaped = array('\\\\', '\\"', '\\\\', '\\"',
  27152. '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a',
  27153. '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f',
  27154. '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17',
  27155. '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f',
  27156. '\\N', '\\_', '\\L', '\\P',);
  27157. /**
  27158. * Determines if a PHP value would require double quoting in YAML.
  27159. *
  27160. * @param string $value A PHP value
  27161. *
  27162. * @return bool True if the value would require double quotes.
  27163. */
  27164. public static function requiresDoubleQuoting($value)
  27165. {
  27166. return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
  27167. }
  27168. /**
  27169. * Escapes and surrounds a PHP value with double quotes.
  27170. *
  27171. * @param string $value A PHP value
  27172. *
  27173. * @return string The quoted, escaped string
  27174. */
  27175. public static function escapeWithDoubleQuotes($value)
  27176. {
  27177. return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
  27178. }
  27179. /**
  27180. * Determines if a PHP value would require single quoting in YAML.
  27181. *
  27182. * @param string $value A PHP value
  27183. *
  27184. * @return bool True if the value would require single quotes.
  27185. */
  27186. public static function requiresSingleQuoting($value)
  27187. {
  27188. // Determines if a PHP value is entirely composed of a value that would
  27189. // require single quoting in YAML.
  27190. if (in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'))) {
  27191. return true;
  27192. }
  27193. // Determines if the PHP value contains any single characters that would
  27194. // cause it to require single quoting in YAML.
  27195. return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
  27196. }
  27197. /**
  27198. * Escapes and surrounds a PHP value with single quotes.
  27199. *
  27200. * @param string $value A PHP value
  27201. *
  27202. * @return string The quoted, escaped string
  27203. */
  27204. public static function escapeWithSingleQuotes($value)
  27205. {
  27206. return sprintf("'%s'", str_replace('\'', '\'\'', $value));
  27207. }
  27208. }
  27209. -----BEGIN CERTIFICATE-----
  27210. MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
  27211. MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
  27212. IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
  27213. MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
  27214. FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
  27215. bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
  27216. dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
  27217. H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
  27218. uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
  27219. mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
  27220. a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
  27221. E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
  27222. WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
  27223. VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
  27224. Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
  27225. cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
  27226. IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
  27227. AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
  27228. YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
  27229. 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
  27230. Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
  27231. c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
  27232. mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
  27233. -----END CERTIFICATE-----
  27234. Copyright (c) 2014 Doctrine Project
  27235. Permission is hereby granted, free of charge, to any person obtaining a copy of
  27236. this software and associated documentation files (the "Software"), to deal in
  27237. the Software without restriction, including without limitation the rights to
  27238. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  27239. of the Software, and to permit persons to whom the Software is furnished to do
  27240. so, subject to the following conditions:
  27241. The above copyright notice and this permission notice shall be included in all
  27242. copies or substantial portions of the Software.
  27243. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  27244. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  27245. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27246. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  27247. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  27248. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  27249. SOFTWARE.
  27250. <?php
  27251. /*
  27252. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27253. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27254. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27255. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27256. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27257. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27258. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27259. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27260. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27261. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27262. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27263. *
  27264. * This software consists of voluntary contributions made by many individuals
  27265. * and is licensed under the MIT license. For more information, see
  27266. * <http://www.doctrine-project.org>.
  27267. */
  27268. namespace Doctrine\Instantiator;
  27269. /**
  27270. * Instantiator provides utility methods to build objects without invoking their constructors
  27271. *
  27272. * @author Marco Pivetta <ocramius@gmail.com>
  27273. */
  27274. interface InstantiatorInterface
  27275. {
  27276. /**
  27277. * @param string $className
  27278. *
  27279. * @return object
  27280. *
  27281. * @throws \Doctrine\Instantiator\Exception\ExceptionInterface
  27282. */
  27283. public function instantiate($className);
  27284. }
  27285. <?php
  27286. /*
  27287. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27288. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27289. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27290. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27291. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27292. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27293. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27294. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27295. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27296. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27297. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27298. *
  27299. * This software consists of voluntary contributions made by many individuals
  27300. * and is licensed under the MIT license. For more information, see
  27301. * <http://www.doctrine-project.org>.
  27302. */
  27303. namespace Doctrine\Instantiator\Exception;
  27304. /**
  27305. * Base exception marker interface for the instantiator component
  27306. *
  27307. * @author Marco Pivetta <ocramius@gmail.com>
  27308. */
  27309. interface ExceptionInterface
  27310. {
  27311. }
  27312. <?php
  27313. /*
  27314. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27315. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27316. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27317. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27318. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27319. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27320. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27321. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27322. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27323. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27324. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27325. *
  27326. * This software consists of voluntary contributions made by many individuals
  27327. * and is licensed under the MIT license. For more information, see
  27328. * <http://www.doctrine-project.org>.
  27329. */
  27330. namespace Doctrine\Instantiator\Exception;
  27331. use InvalidArgumentException as BaseInvalidArgumentException;
  27332. use ReflectionClass;
  27333. /**
  27334. * Exception for invalid arguments provided to the instantiator
  27335. *
  27336. * @author Marco Pivetta <ocramius@gmail.com>
  27337. */
  27338. class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface
  27339. {
  27340. /**
  27341. * @param string $className
  27342. *
  27343. * @return self
  27344. */
  27345. public static function fromNonExistingClass($className)
  27346. {
  27347. if (interface_exists($className)) {
  27348. return new self(sprintf('The provided type "%s" is an interface, and can not be instantiated', $className));
  27349. }
  27350. if (PHP_VERSION_ID >= 50400 && trait_exists($className)) {
  27351. return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className));
  27352. }
  27353. return new self(sprintf('The provided class "%s" does not exist', $className));
  27354. }
  27355. /**
  27356. * @param ReflectionClass $reflectionClass
  27357. *
  27358. * @return self
  27359. */
  27360. public static function fromAbstractClass(ReflectionClass $reflectionClass)
  27361. {
  27362. return new self(sprintf(
  27363. 'The provided class "%s" is abstract, and can not be instantiated',
  27364. $reflectionClass->getName()
  27365. ));
  27366. }
  27367. }
  27368. <?php
  27369. /*
  27370. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27371. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27372. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27373. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27374. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27375. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27376. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27377. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27378. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27379. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27380. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27381. *
  27382. * This software consists of voluntary contributions made by many individuals
  27383. * and is licensed under the MIT license. For more information, see
  27384. * <http://www.doctrine-project.org>.
  27385. */
  27386. namespace Doctrine\Instantiator\Exception;
  27387. use Exception;
  27388. use ReflectionClass;
  27389. use UnexpectedValueException as BaseUnexpectedValueException;
  27390. /**
  27391. * Exception for given parameters causing invalid/unexpected state on instantiation
  27392. *
  27393. * @author Marco Pivetta <ocramius@gmail.com>
  27394. */
  27395. class UnexpectedValueException extends BaseUnexpectedValueException implements ExceptionInterface
  27396. {
  27397. /**
  27398. * @param ReflectionClass $reflectionClass
  27399. * @param Exception $exception
  27400. *
  27401. * @return self
  27402. */
  27403. public static function fromSerializationTriggeredException(ReflectionClass $reflectionClass, Exception $exception)
  27404. {
  27405. return new self(
  27406. sprintf(
  27407. 'An exception was raised while trying to instantiate an instance of "%s" via un-serialization',
  27408. $reflectionClass->getName()
  27409. ),
  27410. 0,
  27411. $exception
  27412. );
  27413. }
  27414. /**
  27415. * @param ReflectionClass $reflectionClass
  27416. * @param string $errorString
  27417. * @param int $errorCode
  27418. * @param string $errorFile
  27419. * @param int $errorLine
  27420. *
  27421. * @return UnexpectedValueException
  27422. */
  27423. public static function fromUncleanUnSerialization(
  27424. ReflectionClass $reflectionClass,
  27425. $errorString,
  27426. $errorCode,
  27427. $errorFile,
  27428. $errorLine
  27429. ) {
  27430. return new self(
  27431. sprintf(
  27432. 'Could not produce an instance of "%s" via un-serialization, since an error was triggered '
  27433. . 'in file "%s" at line "%d"',
  27434. $reflectionClass->getName(),
  27435. $errorFile,
  27436. $errorLine
  27437. ),
  27438. 0,
  27439. new Exception($errorString, $errorCode)
  27440. );
  27441. }
  27442. }
  27443. <?php
  27444. /*
  27445. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27446. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27447. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27448. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27449. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27450. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27451. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27452. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27453. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27454. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27455. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27456. *
  27457. * This software consists of voluntary contributions made by many individuals
  27458. * and is licensed under the MIT license. For more information, see
  27459. * <http://www.doctrine-project.org>.
  27460. */
  27461. namespace Doctrine\Instantiator;
  27462. use Closure;
  27463. use Doctrine\Instantiator\Exception\InvalidArgumentException;
  27464. use Doctrine\Instantiator\Exception\UnexpectedValueException;
  27465. use Exception;
  27466. use ReflectionClass;
  27467. /**
  27468. * {@inheritDoc}
  27469. *
  27470. * @author Marco Pivetta <ocramius@gmail.com>
  27471. */
  27472. final class Instantiator implements InstantiatorInterface
  27473. {
  27474. /**
  27475. * Markers used internally by PHP to define whether {@see \unserialize} should invoke
  27476. * the method {@see \Serializable::unserialize()} when dealing with classes implementing
  27477. * the {@see \Serializable} interface.
  27478. */
  27479. const SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C';
  27480. const SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O';
  27481. /**
  27482. * @var \Closure[] of {@see \Closure} instances used to instantiate specific classes
  27483. */
  27484. private static $cachedInstantiators = array();
  27485. /**
  27486. * @var object[] of objects that can directly be cloned
  27487. */
  27488. private static $cachedCloneables = array();
  27489. /**
  27490. * {@inheritDoc}
  27491. */
  27492. public function instantiate($className)
  27493. {
  27494. if (isset(self::$cachedCloneables[$className])) {
  27495. return clone self::$cachedCloneables[$className];
  27496. }
  27497. if (isset(self::$cachedInstantiators[$className])) {
  27498. $factory = self::$cachedInstantiators[$className];
  27499. return $factory();
  27500. }
  27501. $factory = self::$cachedInstantiators[$className] = $this->buildFactory($className);
  27502. $instance = $factory();
  27503. $reflection = new ReflectionClass($instance);
  27504. if ($this->isSafeToClone($reflection)) {
  27505. self::$cachedCloneables[$className] = clone $instance;
  27506. }
  27507. return $instance;
  27508. }
  27509. /**
  27510. * @internal
  27511. * @private
  27512. *
  27513. * Builds a {@see \Closure} capable of instantiating the given $className without
  27514. * invoking its constructor.
  27515. * This method is only exposed as public because of PHP 5.3 compatibility. Do not
  27516. * use this method in your own code
  27517. *
  27518. * @param string $className
  27519. *
  27520. * @return Closure
  27521. */
  27522. public function buildFactory($className)
  27523. {
  27524. $reflectionClass = $this->getReflectionClass($className);
  27525. if ($this->isInstantiableViaReflection($reflectionClass)) {
  27526. return function () use ($reflectionClass) {
  27527. return $reflectionClass->newInstanceWithoutConstructor();
  27528. };
  27529. }
  27530. $serializedString = sprintf(
  27531. '%s:%d:"%s":0:{}',
  27532. $this->getSerializationFormat($reflectionClass),
  27533. strlen($className),
  27534. $className
  27535. );
  27536. $this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString);
  27537. return function () use ($serializedString) {
  27538. return unserialize($serializedString);
  27539. };
  27540. }
  27541. /**
  27542. * @param string $className
  27543. *
  27544. * @return ReflectionClass
  27545. *
  27546. * @throws InvalidArgumentException
  27547. */
  27548. private function getReflectionClass($className)
  27549. {
  27550. if (! class_exists($className)) {
  27551. throw InvalidArgumentException::fromNonExistingClass($className);
  27552. }
  27553. $reflection = new ReflectionClass($className);
  27554. if ($reflection->isAbstract()) {
  27555. throw InvalidArgumentException::fromAbstractClass($reflection);
  27556. }
  27557. return $reflection;
  27558. }
  27559. /**
  27560. * @param ReflectionClass $reflectionClass
  27561. * @param string $serializedString
  27562. *
  27563. * @throws UnexpectedValueException
  27564. *
  27565. * @return void
  27566. */
  27567. private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, $serializedString)
  27568. {
  27569. set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) {
  27570. $error = UnexpectedValueException::fromUncleanUnSerialization(
  27571. $reflectionClass,
  27572. $message,
  27573. $code,
  27574. $file,
  27575. $line
  27576. );
  27577. });
  27578. try {
  27579. unserialize($serializedString);
  27580. } catch (Exception $exception) {
  27581. restore_error_handler();
  27582. throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception);
  27583. }
  27584. restore_error_handler();
  27585. if ($error) {
  27586. throw $error;
  27587. }
  27588. }
  27589. /**
  27590. * @param ReflectionClass $reflectionClass
  27591. *
  27592. * @return bool
  27593. */
  27594. private function isInstantiableViaReflection(ReflectionClass $reflectionClass)
  27595. {
  27596. if (\PHP_VERSION_ID >= 50600) {
  27597. return ! ($reflectionClass->isInternal() && $reflectionClass->isFinal());
  27598. }
  27599. return \PHP_VERSION_ID >= 50400 && ! $this->hasInternalAncestors($reflectionClass);
  27600. }
  27601. /**
  27602. * Verifies whether the given class is to be considered internal
  27603. *
  27604. * @param ReflectionClass $reflectionClass
  27605. *
  27606. * @return bool
  27607. */
  27608. private function hasInternalAncestors(ReflectionClass $reflectionClass)
  27609. {
  27610. do {
  27611. if ($reflectionClass->isInternal()) {
  27612. return true;
  27613. }
  27614. } while ($reflectionClass = $reflectionClass->getParentClass());
  27615. return false;
  27616. }
  27617. /**
  27618. * Verifies if the given PHP version implements the `Serializable` interface serialization
  27619. * with an incompatible serialization format. If that's the case, use serialization marker
  27620. * "C" instead of "O".
  27621. *
  27622. * @link http://news.php.net/php.internals/74654
  27623. *
  27624. * @param ReflectionClass $reflectionClass
  27625. *
  27626. * @return string the serialization format marker, either self::SERIALIZATION_FORMAT_USE_UNSERIALIZER
  27627. * or self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER
  27628. */
  27629. private function getSerializationFormat(ReflectionClass $reflectionClass)
  27630. {
  27631. if ($this->isPhpVersionWithBrokenSerializationFormat()
  27632. && $reflectionClass->implementsInterface('Serializable')
  27633. ) {
  27634. return self::SERIALIZATION_FORMAT_USE_UNSERIALIZER;
  27635. }
  27636. return self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER;
  27637. }
  27638. /**
  27639. * Checks whether the current PHP runtime uses an incompatible serialization format
  27640. *
  27641. * @return bool
  27642. */
  27643. private function isPhpVersionWithBrokenSerializationFormat()
  27644. {
  27645. return PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513;
  27646. }
  27647. /**
  27648. * Checks if a class is cloneable
  27649. *
  27650. * @param ReflectionClass $reflection
  27651. *
  27652. * @return bool
  27653. */
  27654. private function isSafeToClone(ReflectionClass $reflection)
  27655. {
  27656. if (method_exists($reflection, 'isCloneable') && ! $reflection->isCloneable()) {
  27657. return false;
  27658. }
  27659. // not cloneable if it implements `__clone`, as we want to avoid calling it
  27660. return ! $reflection->hasMethod('__clone');
  27661. }
  27662. }
  27663. PHP_TokenStream
  27664. Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  27665. All rights reserved.
  27666. Redistribution and use in source and binary forms, with or without
  27667. modification, are permitted provided that the following conditions
  27668. are met:
  27669. * Redistributions of source code must retain the above copyright
  27670. notice, this list of conditions and the following disclaimer.
  27671. * Redistributions in binary form must reproduce the above copyright
  27672. notice, this list of conditions and the following disclaimer in
  27673. the documentation and/or other materials provided with the
  27674. distribution.
  27675. * Neither the name of Sebastian Bergmann nor the names of his
  27676. contributors may be used to endorse or promote products derived
  27677. from this software without specific prior written permission.
  27678. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27679. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27680. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  27681. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  27682. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  27683. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27684. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27685. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  27686. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27687. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  27688. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27689. POSSIBILITY OF SUCH DAMAGE.
  27690. <?php
  27691. /*
  27692. * This file is part of the PHP_TokenStream package.
  27693. *
  27694. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27695. *
  27696. * For the full copyright and license information, please view the LICENSE
  27697. * file that was distributed with this source code.
  27698. */
  27699. /**
  27700. * A caching factory for token stream objects.
  27701. *
  27702. * @author Sebastian Bergmann <sebastian@phpunit.de>
  27703. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  27704. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  27705. * @version Release: @package_version@
  27706. * @link http://github.com/sebastianbergmann/php-token-stream/tree
  27707. * @since Class available since Release 1.0.0
  27708. */
  27709. class PHP_Token_Stream_CachingFactory
  27710. {
  27711. /**
  27712. * @var array
  27713. */
  27714. protected static $cache = array();
  27715. /**
  27716. * @param string $filename
  27717. * @return PHP_Token_Stream
  27718. */
  27719. public static function get($filename)
  27720. {
  27721. if (!isset(self::$cache[$filename])) {
  27722. self::$cache[$filename] = new PHP_Token_Stream($filename);
  27723. }
  27724. return self::$cache[$filename];
  27725. }
  27726. /**
  27727. * @param string $filename
  27728. */
  27729. public static function clear($filename = NULL)
  27730. {
  27731. if (is_string($filename)) {
  27732. unset(self::$cache[$filename]);
  27733. } else {
  27734. self::$cache = array();
  27735. }
  27736. }
  27737. }
  27738. <?php
  27739. /*
  27740. * This file is part of the PHP_TokenStream package.
  27741. *
  27742. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27743. *
  27744. * For the full copyright and license information, please view the LICENSE
  27745. * file that was distributed with this source code.
  27746. */
  27747. /**
  27748. * A stream of PHP tokens.
  27749. *
  27750. * @author Sebastian Bergmann <sebastian@phpunit.de>
  27751. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  27752. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  27753. * @version Release: @package_version@
  27754. * @link http://github.com/sebastianbergmann/php-token-stream/tree
  27755. * @since Class available since Release 1.0.0
  27756. */
  27757. class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
  27758. {
  27759. /**
  27760. * @var array
  27761. */
  27762. protected static $customTokens = array(
  27763. '(' => 'PHP_Token_OPEN_BRACKET',
  27764. ')' => 'PHP_Token_CLOSE_BRACKET',
  27765. '[' => 'PHP_Token_OPEN_SQUARE',
  27766. ']' => 'PHP_Token_CLOSE_SQUARE',
  27767. '{' => 'PHP_Token_OPEN_CURLY',
  27768. '}' => 'PHP_Token_CLOSE_CURLY',
  27769. ';' => 'PHP_Token_SEMICOLON',
  27770. '.' => 'PHP_Token_DOT',
  27771. ',' => 'PHP_Token_COMMA',
  27772. '=' => 'PHP_Token_EQUAL',
  27773. '<' => 'PHP_Token_LT',
  27774. '>' => 'PHP_Token_GT',
  27775. '+' => 'PHP_Token_PLUS',
  27776. '-' => 'PHP_Token_MINUS',
  27777. '*' => 'PHP_Token_MULT',
  27778. '/' => 'PHP_Token_DIV',
  27779. '?' => 'PHP_Token_QUESTION_MARK',
  27780. '!' => 'PHP_Token_EXCLAMATION_MARK',
  27781. ':' => 'PHP_Token_COLON',
  27782. '"' => 'PHP_Token_DOUBLE_QUOTES',
  27783. '@' => 'PHP_Token_AT',
  27784. '&' => 'PHP_Token_AMPERSAND',
  27785. '%' => 'PHP_Token_PERCENT',
  27786. '|' => 'PHP_Token_PIPE',
  27787. '$' => 'PHP_Token_DOLLAR',
  27788. '^' => 'PHP_Token_CARET',
  27789. '~' => 'PHP_Token_TILDE',
  27790. '`' => 'PHP_Token_BACKTICK'
  27791. );
  27792. /**
  27793. * @var string
  27794. */
  27795. protected $filename;
  27796. /**
  27797. * @var array
  27798. */
  27799. protected $tokens = array();
  27800. /**
  27801. * @var integer
  27802. */
  27803. protected $position = 0;
  27804. /**
  27805. * @var array
  27806. */
  27807. protected $linesOfCode = array('loc' => 0, 'cloc' => 0, 'ncloc' => 0);
  27808. /**
  27809. * @var array
  27810. */
  27811. protected $classes;
  27812. /**
  27813. * @var array
  27814. */
  27815. protected $functions;
  27816. /**
  27817. * @var array
  27818. */
  27819. protected $includes;
  27820. /**
  27821. * @var array
  27822. */
  27823. protected $interfaces;
  27824. /**
  27825. * @var array
  27826. */
  27827. protected $traits;
  27828. /**
  27829. * @var array
  27830. */
  27831. protected $lineToFunctionMap = array();
  27832. /**
  27833. * Constructor.
  27834. *
  27835. * @param string $sourceCode
  27836. */
  27837. public function __construct($sourceCode)
  27838. {
  27839. if (is_file($sourceCode)) {
  27840. $this->filename = $sourceCode;
  27841. $sourceCode = file_get_contents($sourceCode);
  27842. }
  27843. $this->scan($sourceCode);
  27844. }
  27845. /**
  27846. * Destructor.
  27847. */
  27848. public function __destruct()
  27849. {
  27850. $this->tokens = array();
  27851. }
  27852. /**
  27853. * @return string
  27854. */
  27855. public function __toString()
  27856. {
  27857. $buffer = '';
  27858. foreach ($this as $token) {
  27859. $buffer .= $token;
  27860. }
  27861. return $buffer;
  27862. }
  27863. /**
  27864. * @return string
  27865. * @since Method available since Release 1.1.0
  27866. */
  27867. public function getFilename()
  27868. {
  27869. return $this->filename;
  27870. }
  27871. /**
  27872. * Scans the source for sequences of characters and converts them into a
  27873. * stream of tokens.
  27874. *
  27875. * @param string $sourceCode
  27876. */
  27877. protected function scan($sourceCode)
  27878. {
  27879. $line = 1;
  27880. $tokens = token_get_all($sourceCode);
  27881. $numTokens = count($tokens);
  27882. $lastNonWhitespaceTokenWasDoubleColon = FALSE;
  27883. for ($i = 0; $i < $numTokens; ++$i) {
  27884. $token = $tokens[$i];
  27885. unset($tokens[$i]);
  27886. if (is_array($token)) {
  27887. $name = substr(token_name($token[0]), 2);
  27888. $text = $token[1];
  27889. if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') {
  27890. $name = 'CLASS_NAME_CONSTANT';
  27891. }
  27892. $tokenClass = 'PHP_Token_' . $name;
  27893. } else {
  27894. $text = $token;
  27895. $tokenClass = self::$customTokens[$token];
  27896. }
  27897. $this->tokens[] = new $tokenClass($text, $line, $this, $i);
  27898. $lines = substr_count($text, "\n");
  27899. $line += $lines;
  27900. if ($tokenClass == 'PHP_Token_HALT_COMPILER') {
  27901. break;
  27902. }
  27903. else if ($tokenClass == 'PHP_Token_COMMENT' ||
  27904. $tokenClass == 'PHP_Token_DOC_COMMENT') {
  27905. $this->linesOfCode['cloc'] += $lines + 1;
  27906. }
  27907. if ($name == 'DOUBLE_COLON') {
  27908. $lastNonWhitespaceTokenWasDoubleColon = TRUE;
  27909. }
  27910. else if ($name != 'WHITESPACE') {
  27911. $lastNonWhitespaceTokenWasDoubleColon = FALSE;
  27912. }
  27913. }
  27914. $this->linesOfCode['loc'] = substr_count($sourceCode, "\n");
  27915. $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] -
  27916. $this->linesOfCode['cloc'];
  27917. }
  27918. /**
  27919. * @return integer
  27920. */
  27921. public function count()
  27922. {
  27923. return count($this->tokens);
  27924. }
  27925. /**
  27926. * @return PHP_Token[]
  27927. */
  27928. public function tokens()
  27929. {
  27930. return $this->tokens;
  27931. }
  27932. /**
  27933. * @return array
  27934. */
  27935. public function getClasses()
  27936. {
  27937. if ($this->classes !== NULL) {
  27938. return $this->classes;
  27939. }
  27940. $this->parse();
  27941. return $this->classes;
  27942. }
  27943. /**
  27944. * @return array
  27945. */
  27946. public function getFunctions()
  27947. {
  27948. if ($this->functions !== NULL) {
  27949. return $this->functions;
  27950. }
  27951. $this->parse();
  27952. return $this->functions;
  27953. }
  27954. /**
  27955. * @return array
  27956. */
  27957. public function getInterfaces()
  27958. {
  27959. if ($this->interfaces !== NULL) {
  27960. return $this->interfaces;
  27961. }
  27962. $this->parse();
  27963. return $this->interfaces;
  27964. }
  27965. /**
  27966. * @return array
  27967. * @since Method available since Release 1.1.0
  27968. */
  27969. public function getTraits()
  27970. {
  27971. if ($this->traits !== NULL) {
  27972. return $this->traits;
  27973. }
  27974. $this->parse();
  27975. return $this->traits;
  27976. }
  27977. /**
  27978. * Gets the names of all files that have been included
  27979. * using include(), include_once(), require() or require_once().
  27980. *
  27981. * Parameter $categorize set to TRUE causing this function to return a
  27982. * multi-dimensional array with categories in the keys of the first dimension
  27983. * and constants and their values in the second dimension.
  27984. *
  27985. * Parameter $category allow to filter following specific inclusion type
  27986. *
  27987. * @param bool $categorize OPTIONAL
  27988. * @param string $category OPTIONAL Either 'require_once', 'require',
  27989. * 'include_once', 'include'.
  27990. * @return array
  27991. * @since Method available since Release 1.1.0
  27992. */
  27993. public function getIncludes($categorize = FALSE, $category = NULL)
  27994. {
  27995. if ($this->includes === NULL) {
  27996. $this->includes = array(
  27997. 'require_once' => array(),
  27998. 'require' => array(),
  27999. 'include_once' => array(),
  28000. 'include' => array()
  28001. );
  28002. foreach ($this->tokens as $token) {
  28003. switch (get_class($token)) {
  28004. case 'PHP_Token_REQUIRE_ONCE':
  28005. case 'PHP_Token_REQUIRE':
  28006. case 'PHP_Token_INCLUDE_ONCE':
  28007. case 'PHP_Token_INCLUDE': {
  28008. $this->includes[$token->getType()][] = $token->getName();
  28009. }
  28010. break;
  28011. }
  28012. }
  28013. }
  28014. if (isset($this->includes[$category])) {
  28015. $includes = $this->includes[$category];
  28016. }
  28017. else if ($categorize === FALSE) {
  28018. $includes = array_merge(
  28019. $this->includes['require_once'],
  28020. $this->includes['require'],
  28021. $this->includes['include_once'],
  28022. $this->includes['include']
  28023. );
  28024. } else {
  28025. $includes = $this->includes;
  28026. }
  28027. return $includes;
  28028. }
  28029. /**
  28030. * Returns the name of the function or method a line belongs to.
  28031. *
  28032. * @return string or null if the line is not in a function or method
  28033. * @since Method available since Release 1.2.0
  28034. */
  28035. public function getFunctionForLine($line)
  28036. {
  28037. $this->parse();
  28038. if (isset($this->lineToFunctionMap[$line])) {
  28039. return $this->lineToFunctionMap[$line];
  28040. }
  28041. }
  28042. protected function parse()
  28043. {
  28044. $this->interfaces = array();
  28045. $this->classes = array();
  28046. $this->traits = array();
  28047. $this->functions = array();
  28048. $class = FALSE;
  28049. $classEndLine = FALSE;
  28050. $trait = FALSE;
  28051. $traitEndLine = FALSE;
  28052. $interface = FALSE;
  28053. $interfaceEndLine = FALSE;
  28054. foreach ($this->tokens as $token) {
  28055. switch (get_class($token)) {
  28056. case 'PHP_Token_HALT_COMPILER': {
  28057. return;
  28058. }
  28059. break;
  28060. case 'PHP_Token_INTERFACE': {
  28061. $interface = $token->getName();
  28062. $interfaceEndLine = $token->getEndLine();
  28063. $this->interfaces[$interface] = array(
  28064. 'methods' => array(),
  28065. 'parent' => $token->getParent(),
  28066. 'keywords' => $token->getKeywords(),
  28067. 'docblock' => $token->getDocblock(),
  28068. 'startLine' => $token->getLine(),
  28069. 'endLine' => $interfaceEndLine,
  28070. 'package' => $token->getPackage(),
  28071. 'file' => $this->filename
  28072. );
  28073. }
  28074. break;
  28075. case 'PHP_Token_CLASS':
  28076. case 'PHP_Token_TRAIT': {
  28077. $tmp = array(
  28078. 'methods' => array(),
  28079. 'parent' => $token->getParent(),
  28080. 'interfaces'=> $token->getInterfaces(),
  28081. 'keywords' => $token->getKeywords(),
  28082. 'docblock' => $token->getDocblock(),
  28083. 'startLine' => $token->getLine(),
  28084. 'endLine' => $token->getEndLine(),
  28085. 'package' => $token->getPackage(),
  28086. 'file' => $this->filename
  28087. );
  28088. if ($token instanceof PHP_Token_CLASS) {
  28089. $class = $token->getName();
  28090. $classEndLine = $token->getEndLine();
  28091. $this->classes[$class] = $tmp;
  28092. } else {
  28093. $trait = $token->getName();
  28094. $traitEndLine = $token->getEndLine();
  28095. $this->traits[$trait] = $tmp;
  28096. }
  28097. }
  28098. break;
  28099. case 'PHP_Token_FUNCTION': {
  28100. $name = $token->getName();
  28101. $tmp = array(
  28102. 'docblock' => $token->getDocblock(),
  28103. 'keywords' => $token->getKeywords(),
  28104. 'visibility'=> $token->getVisibility(),
  28105. 'signature' => $token->getSignature(),
  28106. 'startLine' => $token->getLine(),
  28107. 'endLine' => $token->getEndLine(),
  28108. 'ccn' => $token->getCCN(),
  28109. 'file' => $this->filename
  28110. );
  28111. if ($class === FALSE &&
  28112. $trait === FALSE &&
  28113. $interface === FALSE) {
  28114. $this->functions[$name] = $tmp;
  28115. $this->addFunctionToMap(
  28116. $name, $tmp['startLine'], $tmp['endLine']
  28117. );
  28118. }
  28119. else if ($class !== FALSE) {
  28120. $this->classes[$class]['methods'][$name] = $tmp;
  28121. $this->addFunctionToMap(
  28122. $class . '::' . $name,
  28123. $tmp['startLine'],
  28124. $tmp['endLine']
  28125. );
  28126. }
  28127. else if ($trait !== FALSE) {
  28128. $this->traits[$trait]['methods'][$name] = $tmp;
  28129. $this->addFunctionToMap(
  28130. $trait . '::' . $name,
  28131. $tmp['startLine'],
  28132. $tmp['endLine']
  28133. );
  28134. }
  28135. else {
  28136. $this->interfaces[$interface]['methods'][$name] = $tmp;
  28137. }
  28138. }
  28139. break;
  28140. case 'PHP_Token_CLOSE_CURLY': {
  28141. if ($classEndLine !== FALSE &&
  28142. $classEndLine == $token->getLine()) {
  28143. $class = FALSE;
  28144. $classEndLine = FALSE;
  28145. }
  28146. else if ($traitEndLine !== FALSE &&
  28147. $traitEndLine == $token->getLine()) {
  28148. $trait = FALSE;
  28149. $traitEndLine = FALSE;
  28150. }
  28151. else if ($interfaceEndLine !== FALSE &&
  28152. $interfaceEndLine == $token->getLine()) {
  28153. $interface = FALSE;
  28154. $interfaceEndLine = FALSE;
  28155. }
  28156. }
  28157. break;
  28158. }
  28159. }
  28160. }
  28161. /**
  28162. * @return array
  28163. */
  28164. public function getLinesOfCode()
  28165. {
  28166. return $this->linesOfCode;
  28167. }
  28168. /**
  28169. */
  28170. public function rewind()
  28171. {
  28172. $this->position = 0;
  28173. }
  28174. /**
  28175. * @return boolean
  28176. */
  28177. public function valid()
  28178. {
  28179. return isset($this->tokens[$this->position]);
  28180. }
  28181. /**
  28182. * @return integer
  28183. */
  28184. public function key()
  28185. {
  28186. return $this->position;
  28187. }
  28188. /**
  28189. * @return PHP_Token
  28190. */
  28191. public function current()
  28192. {
  28193. return $this->tokens[$this->position];
  28194. }
  28195. /**
  28196. */
  28197. public function next()
  28198. {
  28199. $this->position++;
  28200. }
  28201. /**
  28202. * @param mixed $offset
  28203. */
  28204. public function offsetExists($offset)
  28205. {
  28206. return isset($this->tokens[$offset]);
  28207. }
  28208. /**
  28209. * @param mixed $offset
  28210. * @return mixed
  28211. */
  28212. public function offsetGet($offset)
  28213. {
  28214. return $this->tokens[$offset];
  28215. }
  28216. /**
  28217. * @param mixed $offset
  28218. * @param mixed $value
  28219. */
  28220. public function offsetSet($offset, $value)
  28221. {
  28222. $this->tokens[$offset] = $value;
  28223. }
  28224. /**
  28225. * @param mixed $offset
  28226. */
  28227. public function offsetUnset($offset)
  28228. {
  28229. unset($this->tokens[$offset]);
  28230. }
  28231. /**
  28232. * Seek to an absolute position.
  28233. *
  28234. * @param integer $position
  28235. * @throws OutOfBoundsException
  28236. */
  28237. public function seek($position)
  28238. {
  28239. $this->position = $position;
  28240. if (!$this->valid()) {
  28241. throw new OutOfBoundsException('Invalid seek position');
  28242. }
  28243. }
  28244. private function addFunctionToMap($name, $startLine, $endLine)
  28245. {
  28246. for ($line = $startLine; $line <= $endLine; $line++) {
  28247. $this->lineToFunctionMap[$line] = $name;
  28248. }
  28249. }
  28250. }
  28251. <?php
  28252. /*
  28253. * This file is part of the PHP_TokenStream package.
  28254. *
  28255. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28256. *
  28257. * For the full copyright and license information, please view the LICENSE
  28258. * file that was distributed with this source code.
  28259. */
  28260. /**
  28261. * A PHP token.
  28262. *
  28263. * @author Sebastian Bergmann <sebastian@phpunit.de>
  28264. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  28265. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28266. * @version Release: @package_version@
  28267. * @link http://github.com/sebastianbergmann/php-token-stream/tree
  28268. * @since Class available since Release 1.0.0
  28269. */
  28270. abstract class PHP_Token
  28271. {
  28272. /**
  28273. * @var string
  28274. */
  28275. protected $text;
  28276. /**
  28277. * @var integer
  28278. */
  28279. protected $line;
  28280. /**
  28281. * @var PHP_Token_Stream
  28282. */
  28283. protected $tokenStream;
  28284. /**
  28285. * @var integer
  28286. */
  28287. protected $id;
  28288. /**
  28289. * Constructor.
  28290. *
  28291. * @param string $text
  28292. * @param integer $line
  28293. * @param PHP_Token_Stream $tokenStream
  28294. * @param integer $id
  28295. */
  28296. public function __construct($text, $line, PHP_Token_Stream $tokenStream, $id)
  28297. {
  28298. $this->text = $text;
  28299. $this->line = $line;
  28300. $this->tokenStream = $tokenStream;
  28301. $this->id = $id;
  28302. }
  28303. /**
  28304. * @return string
  28305. */
  28306. public function __toString()
  28307. {
  28308. return $this->text;
  28309. }
  28310. /**
  28311. * @return integer
  28312. */
  28313. public function getLine()
  28314. {
  28315. return $this->line;
  28316. }
  28317. }
  28318. abstract class PHP_TokenWithScope extends PHP_Token
  28319. {
  28320. protected $endTokenId;
  28321. /**
  28322. * Get the docblock for this token
  28323. *
  28324. * This method will fetch the docblock belonging to the current token. The
  28325. * docblock must be placed on the line directly above the token to be
  28326. * recognized.
  28327. *
  28328. * @return string|null Returns the docblock as a string if found
  28329. */
  28330. public function getDocblock()
  28331. {
  28332. $tokens = $this->tokenStream->tokens();
  28333. $currentLineNumber = $tokens[$this->id]->getLine();
  28334. $prevLineNumber = $currentLineNumber - 1;
  28335. for ($i = $this->id - 1; $i; $i--) {
  28336. if (!isset($tokens[$i])) {
  28337. return;
  28338. }
  28339. if ($tokens[$i] instanceof PHP_Token_FUNCTION ||
  28340. $tokens[$i] instanceof PHP_Token_CLASS ||
  28341. $tokens[$i] instanceof PHP_Token_TRAIT) {
  28342. // Some other trait, class or function, no docblock can be
  28343. // used for the current token
  28344. break;
  28345. }
  28346. $line = $tokens[$i]->getLine();
  28347. if ($line == $currentLineNumber ||
  28348. ($line == $prevLineNumber &&
  28349. $tokens[$i] instanceof PHP_Token_WHITESPACE)) {
  28350. continue;
  28351. }
  28352. if ($line < $currentLineNumber &&
  28353. !$tokens[$i] instanceof PHP_Token_DOC_COMMENT) {
  28354. break;
  28355. }
  28356. return (string)$tokens[$i];
  28357. }
  28358. }
  28359. public function getEndTokenId()
  28360. {
  28361. $block = 0;
  28362. $i = $this->id;
  28363. $tokens = $this->tokenStream->tokens();
  28364. while ($this->endTokenId === NULL && isset($tokens[$i])) {
  28365. if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY ||
  28366. $tokens[$i] instanceof PHP_Token_CURLY_OPEN) {
  28367. $block++;
  28368. }
  28369. else if ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) {
  28370. $block--;
  28371. if ($block === 0) {
  28372. $this->endTokenId = $i;
  28373. }
  28374. }
  28375. else if (($this instanceof PHP_Token_FUNCTION ||
  28376. $this instanceof PHP_Token_NAMESPACE) &&
  28377. $tokens[$i] instanceof PHP_Token_SEMICOLON) {
  28378. if ($block === 0) {
  28379. $this->endTokenId = $i;
  28380. }
  28381. }
  28382. $i++;
  28383. }
  28384. if ($this->endTokenId === NULL) {
  28385. $this->endTokenId = $this->id;
  28386. }
  28387. return $this->endTokenId;
  28388. }
  28389. public function getEndLine()
  28390. {
  28391. return $this->tokenStream[$this->getEndTokenId()]->getLine();
  28392. }
  28393. }
  28394. abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope {
  28395. public function getVisibility()
  28396. {
  28397. $tokens = $this->tokenStream->tokens();
  28398. for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
  28399. if (isset($tokens[$i]) &&
  28400. ($tokens[$i] instanceof PHP_Token_PRIVATE ||
  28401. $tokens[$i] instanceof PHP_Token_PROTECTED ||
  28402. $tokens[$i] instanceof PHP_Token_PUBLIC)) {
  28403. return strtolower(
  28404. str_replace('PHP_Token_', '', get_class($tokens[$i]))
  28405. );
  28406. }
  28407. if (isset($tokens[$i]) &&
  28408. !($tokens[$i] instanceof PHP_Token_STATIC ||
  28409. $tokens[$i] instanceof PHP_Token_FINAL ||
  28410. $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
  28411. // no keywords; stop visibility search
  28412. break;
  28413. }
  28414. }
  28415. }
  28416. public function getKeywords()
  28417. {
  28418. $keywords = array();
  28419. $tokens = $this->tokenStream->tokens();
  28420. for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
  28421. if (isset($tokens[$i]) &&
  28422. ($tokens[$i] instanceof PHP_Token_PRIVATE ||
  28423. $tokens[$i] instanceof PHP_Token_PROTECTED ||
  28424. $tokens[$i] instanceof PHP_Token_PUBLIC)) {
  28425. continue;
  28426. }
  28427. if (isset($tokens[$i]) &&
  28428. ($tokens[$i] instanceof PHP_Token_STATIC ||
  28429. $tokens[$i] instanceof PHP_Token_FINAL ||
  28430. $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
  28431. $keywords[] = strtolower(
  28432. str_replace('PHP_Token_', '', get_class($tokens[$i]))
  28433. );
  28434. }
  28435. }
  28436. return implode(',', $keywords);
  28437. }
  28438. }
  28439. abstract class PHP_Token_Includes extends PHP_Token
  28440. {
  28441. protected $name;
  28442. protected $type;
  28443. public function getName()
  28444. {
  28445. if ($this->name !== NULL) {
  28446. return $this->name;
  28447. }
  28448. $tokens = $this->tokenStream->tokens();
  28449. if ($tokens[$this->id+2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) {
  28450. $this->name = trim($tokens[$this->id+2], "'\"");
  28451. $this->type = strtolower(
  28452. str_replace('PHP_Token_', '', get_class($tokens[$this->id]))
  28453. );
  28454. }
  28455. return $this->name;
  28456. }
  28457. public function getType()
  28458. {
  28459. $this->getName();
  28460. return $this->type;
  28461. }
  28462. }
  28463. class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility
  28464. {
  28465. protected $arguments;
  28466. protected $ccn;
  28467. protected $name;
  28468. protected $signature;
  28469. public function getArguments()
  28470. {
  28471. if ($this->arguments !== NULL) {
  28472. return $this->arguments;
  28473. }
  28474. $this->arguments = array();
  28475. $tokens = $this->tokenStream->tokens();
  28476. $typeHint = NULL;
  28477. // Search for first token inside brackets
  28478. $i = $this->id + 2;
  28479. while (!$tokens[$i-1] instanceof PHP_Token_OPEN_BRACKET) {
  28480. $i++;
  28481. }
  28482. while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) {
  28483. if ($tokens[$i] instanceof PHP_Token_STRING) {
  28484. $typeHint = (string)$tokens[$i];
  28485. }
  28486. else if ($tokens[$i] instanceof PHP_Token_VARIABLE) {
  28487. $this->arguments[(string)$tokens[$i]] = $typeHint;
  28488. $typeHint = NULL;
  28489. }
  28490. $i++;
  28491. }
  28492. return $this->arguments;
  28493. }
  28494. public function getName()
  28495. {
  28496. if ($this->name !== NULL) {
  28497. return $this->name;
  28498. }
  28499. $tokens = $this->tokenStream->tokens();
  28500. for ($i = $this->id + 1; $i < count($tokens); $i++) {
  28501. if ($tokens[$i] instanceof PHP_Token_STRING) {
  28502. $this->name = (string)$tokens[$i];
  28503. break;
  28504. }
  28505. else if ($tokens[$i] instanceof PHP_Token_AMPERSAND &&
  28506. $tokens[$i+1] instanceof PHP_Token_STRING) {
  28507. $this->name = (string)$tokens[$i+1];
  28508. break;
  28509. }
  28510. else if ($tokens[$i] instanceof PHP_Token_OPEN_BRACKET) {
  28511. $this->name = 'anonymous function';
  28512. break;
  28513. }
  28514. }
  28515. if ($this->name != 'anonymous function') {
  28516. for ($i = $this->id; $i; --$i) {
  28517. if ($tokens[$i] instanceof PHP_Token_NAMESPACE) {
  28518. $this->name = $tokens[$i]->getName() . '\\' . $this->name;
  28519. break;
  28520. }
  28521. if ($tokens[$i] instanceof PHP_Token_INTERFACE) {
  28522. break;
  28523. }
  28524. }
  28525. }
  28526. return $this->name;
  28527. }
  28528. public function getCCN()
  28529. {
  28530. if ($this->ccn !== NULL) {
  28531. return $this->ccn;
  28532. }
  28533. $this->ccn = 1;
  28534. $end = $this->getEndTokenId();
  28535. $tokens = $this->tokenStream->tokens();
  28536. for ($i = $this->id; $i <= $end; $i++) {
  28537. switch (get_class($tokens[$i])) {
  28538. case 'PHP_Token_IF':
  28539. case 'PHP_Token_ELSEIF':
  28540. case 'PHP_Token_FOR':
  28541. case 'PHP_Token_FOREACH':
  28542. case 'PHP_Token_WHILE':
  28543. case 'PHP_Token_CASE':
  28544. case 'PHP_Token_CATCH':
  28545. case 'PHP_Token_BOOLEAN_AND':
  28546. case 'PHP_Token_LOGICAL_AND':
  28547. case 'PHP_Token_BOOLEAN_OR':
  28548. case 'PHP_Token_LOGICAL_OR':
  28549. case 'PHP_Token_QUESTION_MARK': {
  28550. $this->ccn++;
  28551. }
  28552. break;
  28553. }
  28554. }
  28555. return $this->ccn;
  28556. }
  28557. public function getSignature()
  28558. {
  28559. if ($this->signature !== NULL) {
  28560. return $this->signature;
  28561. }
  28562. if ($this->getName() == 'anonymous function') {
  28563. $this->signature = 'anonymous function';
  28564. $i = $this->id + 1;
  28565. } else {
  28566. $this->signature = '';
  28567. $i = $this->id + 2;
  28568. }
  28569. $tokens = $this->tokenStream->tokens();
  28570. while (isset($tokens[$i]) &&
  28571. !$tokens[$i] instanceof PHP_Token_OPEN_CURLY &&
  28572. !$tokens[$i] instanceof PHP_Token_SEMICOLON) {
  28573. $this->signature .= $tokens[$i++];
  28574. }
  28575. $this->signature = trim($this->signature);
  28576. return $this->signature;
  28577. }
  28578. }
  28579. class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility
  28580. {
  28581. protected $interfaces;
  28582. public function getName()
  28583. {
  28584. return (string)$this->tokenStream[$this->id + 2];
  28585. }
  28586. public function hasParent()
  28587. {
  28588. return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS;
  28589. }
  28590. public function getPackage()
  28591. {
  28592. $className = $this->getName();
  28593. $docComment = $this->getDocblock();
  28594. $result = array(
  28595. 'namespace' => '',
  28596. 'fullPackage' => '',
  28597. 'category' => '',
  28598. 'package' => '',
  28599. 'subpackage' => ''
  28600. );
  28601. for ($i = $this->id; $i; --$i) {
  28602. if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) {
  28603. $result['namespace'] = $this->tokenStream[$i]->getName();
  28604. break;
  28605. }
  28606. }
  28607. if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) {
  28608. $result['category'] = $matches[1];
  28609. }
  28610. if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) {
  28611. $result['package'] = $matches[1];
  28612. $result['fullPackage'] = $matches[1];
  28613. }
  28614. if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) {
  28615. $result['subpackage'] = $matches[1];
  28616. $result['fullPackage'] .= '.' . $matches[1];
  28617. }
  28618. if (empty($result['fullPackage'])) {
  28619. $result['fullPackage'] = $this->arrayToName(
  28620. explode('_', str_replace('\\', '_', $className)), '.'
  28621. );
  28622. }
  28623. return $result;
  28624. }
  28625. protected function arrayToName(array $parts, $join = '\\')
  28626. {
  28627. $result = '';
  28628. if (count($parts) > 1) {
  28629. array_pop($parts);
  28630. $result = join($join, $parts);
  28631. }
  28632. return $result;
  28633. }
  28634. public function getParent()
  28635. {
  28636. if (!$this->hasParent()) {
  28637. return FALSE;
  28638. }
  28639. $i = $this->id + 6;
  28640. $tokens = $this->tokenStream->tokens();
  28641. $className = (string)$tokens[$i];
  28642. while (isset($tokens[$i+1]) &&
  28643. !$tokens[$i+1] instanceof PHP_Token_WHITESPACE) {
  28644. $className .= (string)$tokens[++$i];
  28645. }
  28646. return $className;
  28647. }
  28648. public function hasInterfaces()
  28649. {
  28650. return (isset($this->tokenStream[$this->id + 4]) &&
  28651. $this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) ||
  28652. (isset($this->tokenStream[$this->id + 8]) &&
  28653. $this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS);
  28654. }
  28655. public function getInterfaces()
  28656. {
  28657. if ($this->interfaces !== NULL) {
  28658. return $this->interfaces;
  28659. }
  28660. if (!$this->hasInterfaces()) {
  28661. return ($this->interfaces = FALSE);
  28662. }
  28663. if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) {
  28664. $i = $this->id + 3;
  28665. } else {
  28666. $i = $this->id + 7;
  28667. }
  28668. $tokens = $this->tokenStream->tokens();
  28669. while (!$tokens[$i+1] instanceof PHP_Token_OPEN_CURLY) {
  28670. $i++;
  28671. if ($tokens[$i] instanceof PHP_Token_STRING) {
  28672. $this->interfaces[] = (string)$tokens[$i];
  28673. }
  28674. }
  28675. return $this->interfaces;
  28676. }
  28677. }
  28678. class PHP_Token_ABSTRACT extends PHP_Token {}
  28679. class PHP_Token_AMPERSAND extends PHP_Token {}
  28680. class PHP_Token_AND_EQUAL extends PHP_Token {}
  28681. class PHP_Token_ARRAY extends PHP_Token {}
  28682. class PHP_Token_ARRAY_CAST extends PHP_Token {}
  28683. class PHP_Token_AS extends PHP_Token {}
  28684. class PHP_Token_AT extends PHP_Token {}
  28685. class PHP_Token_BACKTICK extends PHP_Token {}
  28686. class PHP_Token_BAD_CHARACTER extends PHP_Token {}
  28687. class PHP_Token_BOOLEAN_AND extends PHP_Token {}
  28688. class PHP_Token_BOOLEAN_OR extends PHP_Token {}
  28689. class PHP_Token_BOOL_CAST extends PHP_Token {}
  28690. class PHP_Token_BREAK extends PHP_Token {}
  28691. class PHP_Token_CARET extends PHP_Token {}
  28692. class PHP_Token_CASE extends PHP_Token {}
  28693. class PHP_Token_CATCH extends PHP_Token {}
  28694. class PHP_Token_CHARACTER extends PHP_Token {}
  28695. class PHP_Token_CLASS extends PHP_Token_INTERFACE {}
  28696. class PHP_Token_CLASS_C extends PHP_Token {}
  28697. class PHP_Token_CLASS_NAME_CONSTANT extends PHP_Token {}
  28698. class PHP_Token_CLONE extends PHP_Token {}
  28699. class PHP_Token_CLOSE_BRACKET extends PHP_Token {}
  28700. class PHP_Token_CLOSE_CURLY extends PHP_Token {}
  28701. class PHP_Token_CLOSE_SQUARE extends PHP_Token {}
  28702. class PHP_Token_CLOSE_TAG extends PHP_Token {}
  28703. class PHP_Token_COLON extends PHP_Token {}
  28704. class PHP_Token_COMMA extends PHP_Token {}
  28705. class PHP_Token_COMMENT extends PHP_Token {}
  28706. class PHP_Token_CONCAT_EQUAL extends PHP_Token {}
  28707. class PHP_Token_CONST extends PHP_Token {}
  28708. class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token {}
  28709. class PHP_Token_CONTINUE extends PHP_Token {}
  28710. class PHP_Token_CURLY_OPEN extends PHP_Token {}
  28711. class PHP_Token_DEC extends PHP_Token {}
  28712. class PHP_Token_DECLARE extends PHP_Token {}
  28713. class PHP_Token_DEFAULT extends PHP_Token {}
  28714. class PHP_Token_DIV extends PHP_Token {}
  28715. class PHP_Token_DIV_EQUAL extends PHP_Token {}
  28716. class PHP_Token_DNUMBER extends PHP_Token {}
  28717. class PHP_Token_DO extends PHP_Token {}
  28718. class PHP_Token_DOC_COMMENT extends PHP_Token {}
  28719. class PHP_Token_DOLLAR extends PHP_Token {}
  28720. class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token {}
  28721. class PHP_Token_DOT extends PHP_Token {}
  28722. class PHP_Token_DOUBLE_ARROW extends PHP_Token {}
  28723. class PHP_Token_DOUBLE_CAST extends PHP_Token {}
  28724. class PHP_Token_DOUBLE_COLON extends PHP_Token {}
  28725. class PHP_Token_DOUBLE_QUOTES extends PHP_Token {}
  28726. class PHP_Token_ECHO extends PHP_Token {}
  28727. class PHP_Token_ELSE extends PHP_Token {}
  28728. class PHP_Token_ELSEIF extends PHP_Token {}
  28729. class PHP_Token_EMPTY extends PHP_Token {}
  28730. class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token {}
  28731. class PHP_Token_ENDDECLARE extends PHP_Token {}
  28732. class PHP_Token_ENDFOR extends PHP_Token {}
  28733. class PHP_Token_ENDFOREACH extends PHP_Token {}
  28734. class PHP_Token_ENDIF extends PHP_Token {}
  28735. class PHP_Token_ENDSWITCH extends PHP_Token {}
  28736. class PHP_Token_ENDWHILE extends PHP_Token {}
  28737. class PHP_Token_END_HEREDOC extends PHP_Token {}
  28738. class PHP_Token_EQUAL extends PHP_Token {}
  28739. class PHP_Token_EVAL extends PHP_Token {}
  28740. class PHP_Token_EXCLAMATION_MARK extends PHP_Token {}
  28741. class PHP_Token_EXIT extends PHP_Token {}
  28742. class PHP_Token_EXTENDS extends PHP_Token {}
  28743. class PHP_Token_FILE extends PHP_Token {}
  28744. class PHP_Token_FINAL extends PHP_Token {}
  28745. class PHP_Token_FOR extends PHP_Token {}
  28746. class PHP_Token_FOREACH extends PHP_Token {}
  28747. class PHP_Token_FUNC_C extends PHP_Token {}
  28748. class PHP_Token_GLOBAL extends PHP_Token {}
  28749. class PHP_Token_GT extends PHP_Token {}
  28750. class PHP_Token_IF extends PHP_Token {}
  28751. class PHP_Token_IMPLEMENTS extends PHP_Token {}
  28752. class PHP_Token_INC extends PHP_Token {}
  28753. class PHP_Token_INCLUDE extends PHP_Token_Includes {}
  28754. class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes {}
  28755. class PHP_Token_INLINE_HTML extends PHP_Token {}
  28756. class PHP_Token_INSTANCEOF extends PHP_Token {}
  28757. class PHP_Token_INT_CAST extends PHP_Token {}
  28758. class PHP_Token_ISSET extends PHP_Token {}
  28759. class PHP_Token_IS_EQUAL extends PHP_Token {}
  28760. class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token {}
  28761. class PHP_Token_IS_IDENTICAL extends PHP_Token {}
  28762. class PHP_Token_IS_NOT_EQUAL extends PHP_Token {}
  28763. class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token {}
  28764. class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token {}
  28765. class PHP_Token_LINE extends PHP_Token {}
  28766. class PHP_Token_LIST extends PHP_Token {}
  28767. class PHP_Token_LNUMBER extends PHP_Token {}
  28768. class PHP_Token_LOGICAL_AND extends PHP_Token {}
  28769. class PHP_Token_LOGICAL_OR extends PHP_Token {}
  28770. class PHP_Token_LOGICAL_XOR extends PHP_Token {}
  28771. class PHP_Token_LT extends PHP_Token {}
  28772. class PHP_Token_METHOD_C extends PHP_Token {}
  28773. class PHP_Token_MINUS extends PHP_Token {}
  28774. class PHP_Token_MINUS_EQUAL extends PHP_Token {}
  28775. class PHP_Token_MOD_EQUAL extends PHP_Token {}
  28776. class PHP_Token_MULT extends PHP_Token {}
  28777. class PHP_Token_MUL_EQUAL extends PHP_Token {}
  28778. class PHP_Token_NEW extends PHP_Token {}
  28779. class PHP_Token_NUM_STRING extends PHP_Token {}
  28780. class PHP_Token_OBJECT_CAST extends PHP_Token {}
  28781. class PHP_Token_OBJECT_OPERATOR extends PHP_Token {}
  28782. class PHP_Token_OPEN_BRACKET extends PHP_Token {}
  28783. class PHP_Token_OPEN_CURLY extends PHP_Token {}
  28784. class PHP_Token_OPEN_SQUARE extends PHP_Token {}
  28785. class PHP_Token_OPEN_TAG extends PHP_Token {}
  28786. class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token {}
  28787. class PHP_Token_OR_EQUAL extends PHP_Token {}
  28788. class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token {}
  28789. class PHP_Token_PERCENT extends PHP_Token {}
  28790. class PHP_Token_PIPE extends PHP_Token {}
  28791. class PHP_Token_PLUS extends PHP_Token {}
  28792. class PHP_Token_PLUS_EQUAL extends PHP_Token {}
  28793. class PHP_Token_PRINT extends PHP_Token {}
  28794. class PHP_Token_PRIVATE extends PHP_Token {}
  28795. class PHP_Token_PROTECTED extends PHP_Token {}
  28796. class PHP_Token_PUBLIC extends PHP_Token {}
  28797. class PHP_Token_QUESTION_MARK extends PHP_Token {}
  28798. class PHP_Token_REQUIRE extends PHP_Token_Includes {}
  28799. class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes {}
  28800. class PHP_Token_RETURN extends PHP_Token {}
  28801. class PHP_Token_SEMICOLON extends PHP_Token {}
  28802. class PHP_Token_SL extends PHP_Token {}
  28803. class PHP_Token_SL_EQUAL extends PHP_Token {}
  28804. class PHP_Token_SR extends PHP_Token {}
  28805. class PHP_Token_SR_EQUAL extends PHP_Token {}
  28806. class PHP_Token_START_HEREDOC extends PHP_Token {}
  28807. class PHP_Token_STATIC extends PHP_Token {}
  28808. class PHP_Token_STRING extends PHP_Token {}
  28809. class PHP_Token_STRING_CAST extends PHP_Token {}
  28810. class PHP_Token_STRING_VARNAME extends PHP_Token {}
  28811. class PHP_Token_SWITCH extends PHP_Token {}
  28812. class PHP_Token_THROW extends PHP_Token {}
  28813. class PHP_Token_TILDE extends PHP_Token {}
  28814. class PHP_Token_TRY extends PHP_Token {}
  28815. class PHP_Token_UNSET extends PHP_Token {}
  28816. class PHP_Token_UNSET_CAST extends PHP_Token {}
  28817. class PHP_Token_USE extends PHP_Token {}
  28818. class PHP_Token_VAR extends PHP_Token {}
  28819. class PHP_Token_VARIABLE extends PHP_Token {}
  28820. class PHP_Token_WHILE extends PHP_Token {}
  28821. class PHP_Token_WHITESPACE extends PHP_Token {}
  28822. class PHP_Token_XOR_EQUAL extends PHP_Token {}
  28823. // Tokens introduced in PHP 5.1
  28824. class PHP_Token_HALT_COMPILER extends PHP_Token {}
  28825. // Tokens introduced in PHP 5.3
  28826. class PHP_Token_DIR extends PHP_Token {}
  28827. class PHP_Token_GOTO extends PHP_Token {}
  28828. class PHP_Token_NAMESPACE extends PHP_TokenWithScope
  28829. {
  28830. public function getName()
  28831. {
  28832. $tokens = $this->tokenStream->tokens();
  28833. $namespace = (string)$tokens[$this->id+2];
  28834. for ($i = $this->id + 3; ; $i += 2) {
  28835. if (isset($tokens[$i]) &&
  28836. $tokens[$i] instanceof PHP_Token_NS_SEPARATOR) {
  28837. $namespace .= '\\' . $tokens[$i+1];
  28838. } else {
  28839. break;
  28840. }
  28841. }
  28842. return $namespace;
  28843. }
  28844. }
  28845. class PHP_Token_NS_C extends PHP_Token {}
  28846. class PHP_Token_NS_SEPARATOR extends PHP_Token {}
  28847. // Tokens introduced in PHP 5.4
  28848. class PHP_Token_CALLABLE extends PHP_Token {}
  28849. class PHP_Token_INSTEADOF extends PHP_Token {}
  28850. class PHP_Token_TRAIT extends PHP_Token_INTERFACE {}
  28851. class PHP_Token_TRAIT_C extends PHP_Token {}
  28852. // Tokens introduced in PHP 5.5
  28853. class PHP_Token_FINALLY extends PHP_Token {}
  28854. class PHP_Token_YIELD extends PHP_Token {}
  28855. // Tokens introduced in PHP 5.6
  28856. class PHP_Token_ELLIPSIS extends PHP_Token {}
  28857. class PHP_Token_POW extends PHP_Token {}
  28858. class PHP_Token_POW_EQUAL extends PHP_Token {}
  28859. // Tokens introduced in HackLang
  28860. class PHP_Token_TYPELIST_LT extends PHP_Token {}
  28861. class PHP_Token_TYPELIST_GT extends PHP_Token {}
  28862. class PHP_Token_TYPE extends PHP_Token {}
  28863. class PHP_Token_SHAPE extends PHP_Token {}
  28864. class PHP_Token_LAMBDA_OP extends PHP_Token {}
  28865. class PHP_Token_LAMBDA_CP extends PHP_Token {}
  28866. class PHP_Token_LAMBDA_ARROW extends PHP_Token {}
  28867. class PHP_Token_IN extends PHP_Token {}
  28868. class PHP_Token_JOIN extends PHP_Token {}
  28869. <?php
  28870. /*
  28871. * This file is part of DBUnit.
  28872. *
  28873. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28874. *
  28875. * For the full copyright and license information, please view the LICENSE
  28876. * file that was distributed with this source code.
  28877. */
  28878. /**
  28879. * Thrown for exceptions encountered with database operations. Provides
  28880. * information regarding which operations failed and the query (if any) it
  28881. * failed on.
  28882. *
  28883. * @package DbUnit
  28884. * @author Mike Lively <m@digitalsandwich.com>
  28885. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  28886. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28887. * @version Release: @package_version@
  28888. * @link http://www.phpunit.de/
  28889. * @since Class available since Release 1.0.0
  28890. */
  28891. class PHPUnit_Extensions_Database_Exception extends Exception
  28892. {
  28893. }
  28894. <?php
  28895. /*
  28896. * This file is part of DBUnit.
  28897. *
  28898. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28899. *
  28900. * For the full copyright and license information, please view the LICENSE
  28901. * file that was distributed with this source code.
  28902. */
  28903. /**
  28904. * Defines the interface necessary to create new medium printers.
  28905. *
  28906. * @package DbUnit
  28907. * @author Mike Lively <m@digitalsandwich.com>
  28908. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  28909. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28910. * @version Release: @package_version@
  28911. * @link http://www.phpunit.de//**
  28912. * @since Class available since Release 1.0.0
  28913. */
  28914. interface PHPUnit_Extensions_Database_UI_IMediumPrinter
  28915. {
  28916. /**
  28917. * Prints standard output messages.
  28918. *
  28919. * @param string $message
  28920. */
  28921. public function output($message);
  28922. /**
  28923. * Prints standard error messages.
  28924. *
  28925. * @param string $message
  28926. */
  28927. public function error($message);
  28928. }
  28929. <?php
  28930. /*
  28931. * This file is part of DBUnit.
  28932. *
  28933. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28934. *
  28935. * For the full copyright and license information, please view the LICENSE
  28936. * file that was distributed with this source code.
  28937. */
  28938. /**
  28939. * Delegates database extension commands to the appropriate mode classes.
  28940. *
  28941. * @package DbUnit
  28942. * @author Mike Lively <m@digitalsandwich.com>
  28943. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  28944. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28945. * @version Release: @package_version@
  28946. * @link http://www.phpunit.de//**
  28947. * @since Class available since Release 1.0.0
  28948. */
  28949. class PHPUnit_Extensions_Database_UI_Command
  28950. {
  28951. /**
  28952. * @var PHPUnit_Extensions_Database_UI_IModeFactory
  28953. */
  28954. protected $modeFactory;
  28955. /**
  28956. * @param PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory
  28957. */
  28958. public function __construct(PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory)
  28959. {
  28960. $this->modeFactory = $modeFactory;
  28961. }
  28962. /**
  28963. * Executes the database extension ui.
  28964. *
  28965. * @param PHPUnit_Extensions_Database_UI_IMedium $medium
  28966. * @param PHPUnit_Extensions_Database_UI_Context $context
  28967. */
  28968. public function main(PHPUnit_Extensions_Database_UI_IMedium $medium, PHPUnit_Extensions_Database_UI_Context $context)
  28969. {
  28970. try {
  28971. $medium->buildContext($context);
  28972. $mode = $this->modeFactory->getMode($context->getMode());
  28973. $mode->execute($context->getModeArguments(), $medium);
  28974. } catch (Exception $e) {
  28975. $medium->handleException($e);
  28976. }
  28977. }
  28978. }
  28979. <?php
  28980. /*
  28981. * This file is part of DBUnit.
  28982. *
  28983. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28984. *
  28985. * For the full copyright and license information, please view the LICENSE
  28986. * file that was distributed with this source code.
  28987. */
  28988. /**
  28989. * A text medium for the database extension tool.
  28990. *
  28991. * This class builds the call context based on command line parameters and
  28992. * prints output to stdout and stderr as appropriate.
  28993. *
  28994. * @package DbUnit
  28995. * @author Mike Lively <m@digitalsandwich.com>
  28996. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  28997. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28998. * @version Release: @package_version@
  28999. * @link http://www.phpunit.de/
  29000. * @since Class available since Release 1.0.0
  29001. */
  29002. class PHPUnit_Extensions_Database_UI_Mediums_Text implements PHPUnit_Extensions_Database_UI_IMedium
  29003. {
  29004. /**
  29005. * @var array
  29006. */
  29007. protected $arguments;
  29008. /**
  29009. * @var string
  29010. */
  29011. protected $command;
  29012. /**
  29013. * @param array $arguments
  29014. */
  29015. public function __construct(Array $arguments)
  29016. {
  29017. $this->arguments = $arguments;
  29018. }
  29019. /**
  29020. * Builds the context for the application.
  29021. *
  29022. * @param PHPUnit_Extensions_Database_UI_Context $context
  29023. */
  29024. public function buildContext(PHPUnit_Extensions_Database_UI_Context $context)
  29025. {
  29026. $arguments = $this->arguments;
  29027. $this->command = array_shift($arguments);
  29028. $context->setMode(array_shift($arguments));
  29029. $context->setModeArguments($arguments);
  29030. }
  29031. /**
  29032. * Handles the displaying of exceptions received from the application.
  29033. *
  29034. * @param Exception $e
  29035. */
  29036. public function handleException(Exception $e)
  29037. {
  29038. try {
  29039. throw $e;
  29040. } catch (PHPUnit_Extensions_Database_UI_InvalidModeException $invalidMode) {
  29041. if ($invalidMode->getMode() == '') {
  29042. $this->error('Please Specify a Command!' . PHP_EOL);
  29043. } else {
  29044. $this->error('Command Does Not Exist: ' . $invalidMode->getMode() . PHP_EOL);
  29045. }
  29046. $this->error('Valid Commands:' . PHP_EOL);
  29047. foreach ($invalidMode->getValidModes() as $mode) {
  29048. $this->error(' ' . $mode . PHP_EOL);
  29049. }
  29050. } catch (Exception $e) {
  29051. $this->error('Unknown Error: ' . $e->getMessage() . PHP_EOL);
  29052. }
  29053. }
  29054. /**
  29055. * Prints the message to stdout.
  29056. *
  29057. * @param string $message
  29058. */
  29059. public function output($message)
  29060. {
  29061. echo $message;
  29062. }
  29063. /**
  29064. * Prints the message to stderr
  29065. *
  29066. * @param string $message
  29067. */
  29068. public function error($message)
  29069. {
  29070. fputs(STDERR, $message);
  29071. }
  29072. }
  29073. <?php
  29074. /*
  29075. * This file is part of DBUnit.
  29076. *
  29077. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29078. *
  29079. * For the full copyright and license information, please view the LICENSE
  29080. * file that was distributed with this source code.
  29081. */
  29082. /**
  29083. * An exception thrown when an invalid mode is requested from a mode factory.
  29084. *
  29085. * @package DbUnit
  29086. * @author Mike Lively <m@digitalsandwich.com>
  29087. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29088. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29089. * @version Release: @package_version@
  29090. * @link http://www.phpunit.de//**
  29091. * @since Class available since Release 1.0.0
  29092. */
  29093. class PHPUnit_Extensions_Database_UI_InvalidModeException extends LogicException
  29094. {
  29095. /**
  29096. * @var string
  29097. */
  29098. protected $mode;
  29099. /**
  29100. * @var PHPUnit_Extensions_Database_UI_IModeFactory
  29101. */
  29102. protected $modeFactory;
  29103. /**
  29104. * @param string $mode
  29105. * @param string $msg
  29106. * @param PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory
  29107. */
  29108. public function __construct($mode, $msg, PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory)
  29109. {
  29110. $this->mode = $mode;
  29111. $this->modeFactory = $modeFactory;
  29112. parent::__construct($msg);
  29113. }
  29114. /**
  29115. * @return string
  29116. */
  29117. public function getMode()
  29118. {
  29119. return $this->mode;
  29120. }
  29121. /**
  29122. * @return array
  29123. */
  29124. public function getValidModes()
  29125. {
  29126. return $this->modeFactory->getModeList();
  29127. }
  29128. }
  29129. <?php
  29130. /*
  29131. * This file is part of DBUnit.
  29132. *
  29133. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29134. *
  29135. * For the full copyright and license information, please view the LICENSE
  29136. * file that was distributed with this source code.
  29137. */
  29138. /**
  29139. * Defines the interface necessary to create new modes
  29140. *
  29141. * @package DbUnit
  29142. * @author Mike Lively <m@digitalsandwich.com>
  29143. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29144. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29145. * @version Release: @package_version@
  29146. * @link http://www.phpunit.de//**
  29147. * @since Class available since Release 1.0.0
  29148. */
  29149. interface PHPUnit_Extensions_Database_UI_IMode
  29150. {
  29151. /**
  29152. * Executes the mode using the given arguments and medium.
  29153. *
  29154. * @param array $modeArguments
  29155. * @param PHPUnit_Extensions_Database_UI_IMediumPrinter $medium
  29156. */
  29157. public function execute(array $modeArguments, PHPUnit_Extensions_Database_UI_IMediumPrinter $medium);
  29158. }
  29159. <?php
  29160. /*
  29161. * This file is part of DBUnit.
  29162. *
  29163. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29164. *
  29165. * For the full copyright and license information, please view the LICENSE
  29166. * file that was distributed with this source code.
  29167. */
  29168. /**
  29169. * Holds the context of a particular database extension ui call.
  29170. *
  29171. * @package DbUnit
  29172. * @author Mike Lively <m@digitalsandwich.com>
  29173. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29174. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29175. * @version Release: @package_version@
  29176. * @link http://www.phpunit.de//**
  29177. * @since Class available since Release 1.0.0
  29178. */
  29179. class PHPUnit_Extensions_Database_UI_Context
  29180. {
  29181. /**
  29182. * @var string
  29183. */
  29184. protected $mode;
  29185. /**
  29186. * @var array
  29187. */
  29188. protected $modeArguments;
  29189. /**
  29190. * @param string $mode
  29191. */
  29192. public function setMode($mode)
  29193. {
  29194. $this->mode = $mode;
  29195. }
  29196. /**
  29197. * @return string
  29198. */
  29199. public function getMode()
  29200. {
  29201. return $this->mode;
  29202. }
  29203. /**
  29204. * @param array $arguments
  29205. */
  29206. public function setModeArguments(array $arguments)
  29207. {
  29208. $this->mode_arguments = $arguments;
  29209. }
  29210. /**
  29211. * @return array
  29212. */
  29213. public function getModeArguments()
  29214. {
  29215. return $this->mode_arguments;
  29216. }
  29217. }
  29218. <?php
  29219. /*
  29220. * This file is part of DBUnit.
  29221. *
  29222. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29223. *
  29224. * For the full copyright and license information, please view the LICENSE
  29225. * file that was distributed with this source code.
  29226. */
  29227. /**
  29228. * Represents arguments received from a medium.
  29229. *
  29230. * @package DbUnit
  29231. * @author Mike Lively <m@digitalsandwich.com>
  29232. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29233. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29234. * @version Release: @package_version@
  29235. * @link http://www.phpunit.de/
  29236. * @since Class available since Release 1.0.0
  29237. */
  29238. class PHPUnit_Extensions_Database_UI_Modes_ExportDataSet_Arguments
  29239. {
  29240. /**
  29241. * @var array
  29242. */
  29243. protected $arguments = array();
  29244. /**
  29245. * @param array $arguments
  29246. */
  29247. public function __construct(array $arguments)
  29248. {
  29249. foreach ($arguments as $argument) {
  29250. list($argName, $argValue) = explode('=', $argument, 2);
  29251. $argName = trim($argName, '-');
  29252. if (!isset($this->arguments[$argName])) {
  29253. $this->arguments[$argName] = array();
  29254. }
  29255. $this->arguments[$argName][] = $argValue;
  29256. }
  29257. }
  29258. /**
  29259. * Returns an array of arguments matching the given $argName
  29260. *
  29261. * @param string $argName
  29262. * @return array
  29263. */
  29264. public function getArgumentArray($argName)
  29265. {
  29266. if ($this->argumentIsSet($argName)) {
  29267. return $this->arguments[$argName];
  29268. } else {
  29269. return NULL;
  29270. }
  29271. }
  29272. /**
  29273. * Returns a single argument value.
  29274. *
  29275. * If $argName points to an array the first argument will be returned.
  29276. *
  29277. * @param string $argName
  29278. * @return mixed
  29279. */
  29280. public function getSingleArgument($argName)
  29281. {
  29282. if ($this->argumentIsSet($argName)) {
  29283. return reset($this->arguments[$argName]);
  29284. } else {
  29285. return NULL;
  29286. }
  29287. }
  29288. /**
  29289. * Returns whether an argument is set.
  29290. *
  29291. * @param string $argName
  29292. * @return bool
  29293. */
  29294. public function argumentIsSet($argName)
  29295. {
  29296. return array_key_exists($argName, $this->arguments);
  29297. }
  29298. /**
  29299. * Returns an array containing the names of all arguments provided.
  29300. *
  29301. * @return array
  29302. */
  29303. public function getArgumentNames()
  29304. {
  29305. return array_keys($this->arguments);
  29306. }
  29307. /**
  29308. * Returns an array of database arguments keyed by name.
  29309. *
  29310. * @todo this should be moved.
  29311. * @return array
  29312. */
  29313. public function getDatabases()
  29314. {
  29315. $databases = $this->getArgumentArray('database');
  29316. $retDb = array();
  29317. foreach ($databases as $db) {
  29318. list($name, $arg) = explode(':', $db, 2);
  29319. $retDb[$name] = $arg;
  29320. }
  29321. return $retDb;
  29322. }
  29323. }
  29324. <?php
  29325. /*
  29326. * This file is part of DBUnit.
  29327. *
  29328. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29329. *
  29330. * For the full copyright and license information, please view the LICENSE
  29331. * file that was distributed with this source code.
  29332. */
  29333. /**
  29334. * The class for the export-dataset command.
  29335. *
  29336. * This command is used to convert existing data sets or data in the database
  29337. * into a valid data set format.
  29338. *
  29339. * @package DbUnit
  29340. * @author Mike Lively <m@digitalsandwich.com>
  29341. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29342. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29343. * @version Release: @package_version@
  29344. * @link http://www.phpunit.de/
  29345. * @since Class available since Release 1.0.0
  29346. */
  29347. class PHPUnit_Extensions_Database_UI_Modes_ExportDataSet implements PHPUnit_Extensions_Database_UI_IMode
  29348. {
  29349. /**
  29350. * Executes the export dataset command.
  29351. *
  29352. * @param array $modeArguments
  29353. * @param PHPUnit_Extensions_Database_UI_IMediumPrinter $medium
  29354. */
  29355. public function execute(array $modeArguments, PHPUnit_Extensions_Database_UI_IMediumPrinter $medium)
  29356. {
  29357. $arguments = new PHPUnit_Extensions_Database_UI_Modes_ExportDataSet_Arguments($modeArguments);
  29358. if (FALSE && !$arguments->areValid()) {
  29359. throw new InvalidArgumentException("The arguments for this command are incorrect.");
  29360. }
  29361. $datasets = array();
  29362. foreach ($arguments->getArgumentArray('dataset') as $argString) {
  29363. $datasets[] = $this->getDataSetFromArgument($argString, $arguments->getDatabases());
  29364. }
  29365. $finalDataset = new PHPUnit_Extensions_Database_DataSet_CompositeDataSet($datasets);
  29366. $outputDataset = $this->getPersistorFromArgument($arguments->getSingleArgument('output'));
  29367. $outputDataset->write($finalDataset);
  29368. }
  29369. /**
  29370. * Returns the correct dataset given an argument containing a dataset spec.
  29371. *
  29372. * @param string $argString
  29373. * @param array $databaseList
  29374. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  29375. */
  29376. protected function getDataSetFromArgument($argString, $databaseList)
  29377. {
  29378. $dataSetSpecFactory = new PHPUnit_Extensions_Database_DataSet_Specs_Factory();
  29379. list($type, $dataSetSpecStr) = explode(':', $argString, 2);
  29380. $dataSetSpec = $dataSetSpecFactory->getDataSetSpecByType($type);
  29381. if ($dataSetSpec instanceof PHPUnit_Extensions_Database_IDatabaseListConsumer) {
  29382. $dataSetSpec->setDatabases($databaseList);
  29383. }
  29384. return $dataSetSpec->getDataSet($dataSetSpecStr);
  29385. }
  29386. /**
  29387. * Returns the correct persistor given an argument containing a persistor spec.
  29388. *
  29389. * @param string $argString
  29390. * @return PHPUnit_Extensions_Database_DataSet_IPersistable
  29391. */
  29392. protected function getPersistorFromArgument($argString)
  29393. {
  29394. $persistorFactory = new PHPUnit_Extensions_Database_DataSet_Persistors_Factory();
  29395. list($type, $spec) = explode(':', $argString, 2);
  29396. return $persistorFactory->getPersistorBySpec($type, $spec);
  29397. }
  29398. }
  29399. <?php
  29400. /*
  29401. * This file is part of DBUnit.
  29402. *
  29403. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29404. *
  29405. * For the full copyright and license information, please view the LICENSE
  29406. * file that was distributed with this source code.
  29407. */
  29408. /**
  29409. * Defines the interface necessary to create new mediums.
  29410. *
  29411. * @package DbUnit
  29412. * @author Mike Lively <m@digitalsandwich.com>
  29413. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29414. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29415. * @version Release: @package_version@
  29416. * @link http://www.phpunit.de//**
  29417. * @since Class available since Release 1.0.0
  29418. */
  29419. interface PHPUnit_Extensions_Database_UI_IMedium extends PHPUnit_Extensions_Database_UI_IMediumPrinter
  29420. {
  29421. /**
  29422. * Builds the context for the application.
  29423. *
  29424. * @param PHPUnit_Extensions_Database_UI_Context $context
  29425. */
  29426. public function buildContext(PHPUnit_Extensions_Database_UI_Context $context);
  29427. /**
  29428. * Handles the displaying of exceptions received from the application.
  29429. *
  29430. * @param Exception $e
  29431. */
  29432. public function handleException(Exception $e);
  29433. }
  29434. <?php
  29435. /*
  29436. * This file is part of DBUnit.
  29437. *
  29438. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29439. *
  29440. * For the full copyright and license information, please view the LICENSE
  29441. * file that was distributed with this source code.
  29442. */
  29443. /**
  29444. * The default factory for db extension modes.
  29445. *
  29446. * @package DbUnit
  29447. * @author Mike Lively <m@digitalsandwich.com>
  29448. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29449. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29450. * @version Release: @package_version@
  29451. * @link http://www.phpunit.de//**
  29452. * @since Class available since Release 1.0.0
  29453. */
  29454. class PHPUnit_Extensions_Database_UI_ModeFactory implements PHPUnit_Extensions_Database_UI_IModeFactory
  29455. {
  29456. /**
  29457. * Generates a new mode based on a given name.
  29458. *
  29459. * @param string $mode
  29460. * @return PHPUnit_Extensions_Database_UI_IMode
  29461. */
  29462. public function getMode($mode)
  29463. {
  29464. if ($mode == '') {
  29465. throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'A mode was not provided.', $this);
  29466. }
  29467. $modeMap = $this->getModeMap();
  29468. if (isset($modeMap[$mode])) {
  29469. $modeClass = $this->getModeClass($mode, $modeMap[$mode]);
  29470. return new $modeClass();
  29471. } else {
  29472. throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode does not exist. Attempting to load mode ' . $mode, $this);
  29473. }
  29474. }
  29475. /**
  29476. * Returns the names of valid modes this factory can create.
  29477. *
  29478. * @return array
  29479. */
  29480. public function getModeList()
  29481. {
  29482. return array_keys($this->getModeMap());
  29483. }
  29484. /**
  29485. * Returns a map of modes to class name parts
  29486. *
  29487. * @return array
  29488. */
  29489. protected function getModeMap()
  29490. {
  29491. return array('export-dataset' => 'ExportDataSet');
  29492. }
  29493. /**
  29494. * Given a $mode label and a $mode_name class part attempts to return the
  29495. * class name necessary to instantiate the mode.
  29496. *
  29497. * @param string $mode
  29498. * @param string $mode_name
  29499. * @return string
  29500. */
  29501. protected function getModeClass($mode, $mode_name)
  29502. {
  29503. $modeClass = 'PHPUnit_Extensions_Database_UI_Modes_' . $mode_name;
  29504. $modeFile = dirname(__FILE__) . '/Modes/' . $mode_name . '.php';
  29505. if (class_exists($modeClass)) {
  29506. return $modeClass;
  29507. }
  29508. if (!is_readable($modeFile)) {
  29509. throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode\'s file could not be loaded. Trying file ' . $modeFile, $this);
  29510. }
  29511. require_once ($modeFile);
  29512. if (!class_exists($modeClass)) {
  29513. throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode class was not found in the file. Expecting class name ' . $modeClass, $this);
  29514. }
  29515. return $modeClass;
  29516. }
  29517. }
  29518. <?php
  29519. /*
  29520. * This file is part of DBUnit.
  29521. *
  29522. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29523. *
  29524. * For the full copyright and license information, please view the LICENSE
  29525. * file that was distributed with this source code.
  29526. */
  29527. /**
  29528. * Defines the interface necessary to create new mode factories
  29529. *
  29530. * @package DbUnit
  29531. * @author Mike Lively <m@digitalsandwich.com>
  29532. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29533. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29534. * @version Release: @package_version@
  29535. * @link http://www.phpunit.de//**
  29536. * @since Class available since Release 1.0.0
  29537. */
  29538. interface PHPUnit_Extensions_Database_UI_IModeFactory
  29539. {
  29540. /**
  29541. * Generates a new mode based on a given name.
  29542. *
  29543. * @param string $mode
  29544. * @return PHPUnit_Extensions_Database_UI_IMode
  29545. */
  29546. public function getMode($mode);
  29547. /**
  29548. * Returns the names of valid modes this factory can create.
  29549. *
  29550. * @return array
  29551. */
  29552. public function getModeList();
  29553. }
  29554. <?php
  29555. /*
  29556. * This file is part of DBUnit.
  29557. *
  29558. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29559. *
  29560. * For the full copyright and license information, please view the LICENSE
  29561. * file that was distributed with this source code.
  29562. */
  29563. /**
  29564. * An interface for classes that require a list of databases to operate.
  29565. *
  29566. * @package DbUnit
  29567. * @author Mike Lively <m@digitalsandwich.com>
  29568. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29569. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29570. * @version Release: @package_version@
  29571. * @link http://www.phpunit.de/
  29572. * @since Class available since Release 1.0.0
  29573. */
  29574. interface PHPUnit_Extensions_Database_IDatabaseListConsumer
  29575. {
  29576. /**
  29577. * Sets the database for the spec
  29578. *
  29579. * @param array $databases
  29580. */
  29581. public function setDatabases(array $databases);
  29582. }
  29583. <?php
  29584. /*
  29585. * This file is part of DBUnit.
  29586. *
  29587. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29588. *
  29589. * For the full copyright and license information, please view the LICENSE
  29590. * file that was distributed with this source code.
  29591. */
  29592. /**
  29593. * Thrown for exceptions encountered with database operations. Provides
  29594. * information regarding which operations failed and the query (if any) it
  29595. * failed on.
  29596. *
  29597. * @package DbUnit
  29598. * @author Mike Lively <m@digitalsandwich.com>
  29599. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29600. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29601. * @version Release: @package_version@
  29602. * @link http://www.phpunit.de/
  29603. * @since Class available since Release 1.0.0
  29604. */
  29605. class PHPUnit_Extensions_Database_Operation_Exception extends RuntimeException
  29606. {
  29607. /**
  29608. * @var string
  29609. */
  29610. protected $operation;
  29611. /**
  29612. * @var string
  29613. */
  29614. protected $preparedQuery;
  29615. /**
  29616. * @var array
  29617. */
  29618. protected $preparedArgs;
  29619. /**
  29620. * @var PHPUnit_Extensions_Database_DataSet_ITable
  29621. */
  29622. protected $table;
  29623. /**
  29624. * @var string
  29625. */
  29626. protected $error;
  29627. /**
  29628. * Creates a new dbunit operation exception
  29629. *
  29630. * @param string $operation
  29631. * @param string $current_query
  29632. * @param PHPUnit_Extensions_Database_DataSet_ITable $current_table
  29633. * @param string $error
  29634. */
  29635. public function __construct($operation, $current_query, $current_args, $current_table, $error)
  29636. {
  29637. parent::__construct("{$operation} operation failed on query: {$current_query} using args: " . print_r($current_args, TRUE) . " [{$error}]");
  29638. $this->operation = $operation;
  29639. $this->preparedQuery = $current_query;
  29640. $this->preparedArgs = $current_args;
  29641. $this->table = $current_table;
  29642. $this->error = $error;
  29643. }
  29644. public function getOperation()
  29645. {
  29646. return $this->operation;
  29647. }
  29648. public function getQuery()
  29649. {
  29650. return $this->preparedQuery;
  29651. }
  29652. public function getTable()
  29653. {
  29654. return $this->table;
  29655. }
  29656. public function getArgs()
  29657. {
  29658. return $this->preparedArgs;
  29659. }
  29660. public function getError()
  29661. {
  29662. return $this->error;
  29663. }
  29664. }
  29665. <?php
  29666. /*
  29667. * This file is part of DBUnit.
  29668. *
  29669. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29670. *
  29671. * For the full copyright and license information, please view the LICENSE
  29672. * file that was distributed with this source code.
  29673. */
  29674. /**
  29675. * Updates the rows in a given dataset using primary key columns.
  29676. *
  29677. * @package DbUnit
  29678. * @author Mike Lively <m@digitalsandwich.com>
  29679. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29680. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29681. * @version Release: @package_version@
  29682. * @link http://www.phpunit.de/
  29683. * @since Class available since Release 1.0.0
  29684. */
  29685. class PHPUnit_Extensions_Database_Operation_Replace extends PHPUnit_Extensions_Database_Operation_RowBased
  29686. {
  29687. protected $operationName = 'REPLACE';
  29688. protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29689. {
  29690. $keys = $databaseTableMetaData->getPrimaryKeys();
  29691. $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection));
  29692. $query = "
  29693. SELECT COUNT(*)
  29694. FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  29695. {$whereStatement}
  29696. ";
  29697. return $query;
  29698. }
  29699. protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row)
  29700. {
  29701. $args = array();
  29702. foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) {
  29703. $args[] = $table->getValue($row, $columnName);
  29704. }
  29705. return $args;
  29706. }
  29707. /**
  29708. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  29709. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  29710. */
  29711. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  29712. {
  29713. $insertOperation = new PHPUnit_Extensions_Database_Operation_Insert;
  29714. $updateOperation = new PHPUnit_Extensions_Database_Operation_Update;
  29715. $databaseDataSet = $connection->createDataSet();
  29716. foreach ($dataSet as $table) {
  29717. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  29718. $databaseTableMetaData = $databaseDataSet->getTableMetaData($table->getTableMetaData()->getTableName());
  29719. $insertQuery = $insertOperation->buildOperationQuery($databaseTableMetaData, $table, $connection);
  29720. $updateQuery = $updateOperation->buildOperationQuery($databaseTableMetaData, $table, $connection);
  29721. $selectQuery = $this->buildOperationQuery($databaseTableMetaData, $table, $connection);
  29722. $insertStatement = $connection->getConnection()->prepare($insertQuery);
  29723. $updateStatement = $connection->getConnection()->prepare($updateQuery);
  29724. $selectStatement = $connection->getConnection()->prepare($selectQuery);
  29725. $rowCount = $table->getRowCount();
  29726. for ($i = 0; $i < $rowCount; $i++) {
  29727. $selectArgs = $this->buildOperationArguments($databaseTableMetaData, $table, $i);
  29728. $query = $selectQuery;
  29729. $args = $selectArgs;
  29730. try {
  29731. $selectStatement->execute($selectArgs);
  29732. if ($selectStatement->fetchColumn(0) > 0) {
  29733. $updateArgs = $updateOperation->buildOperationArguments($databaseTableMetaData, $table, $i);
  29734. $query = $updateQuery;
  29735. $args = $updateArgs;
  29736. $updateStatement->execute($updateArgs);
  29737. } else {
  29738. $insertArgs = $insertOperation->buildOperationArguments($databaseTableMetaData, $table, $i);
  29739. $query = $insertQuery;
  29740. $args = $insertArgs;
  29741. $insertStatement->execute($insertArgs);
  29742. }
  29743. }
  29744. catch (Exception $e) {
  29745. throw new PHPUnit_Extensions_Database_Operation_Exception(
  29746. $this->operationName, $query, $args, $table, $e->getMessage()
  29747. );
  29748. }
  29749. }
  29750. }
  29751. }
  29752. }
  29753. <?php
  29754. /*
  29755. * This file is part of DBUnit.
  29756. *
  29757. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29758. *
  29759. * For the full copyright and license information, please view the LICENSE
  29760. * file that was distributed with this source code.
  29761. */
  29762. /**
  29763. * This class provides functionality for inserting rows from a dataset into a database.
  29764. *
  29765. * @package DbUnit
  29766. * @author Mike Lively <m@digitalsandwich.com>
  29767. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29768. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29769. * @version Release: @package_version@
  29770. * @link http://www.phpunit.de/
  29771. * @since Class available since Release 1.0.0
  29772. */
  29773. class PHPUnit_Extensions_Database_Operation_Insert extends PHPUnit_Extensions_Database_Operation_RowBased
  29774. {
  29775. protected $operationName = 'INSERT';
  29776. protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29777. {
  29778. $columnCount = count($table->getTableMetaData()->getColumns());
  29779. if ($columnCount > 0) {
  29780. $placeHolders = implode(', ', array_fill(0, $columnCount, '?'));
  29781. $columns = '';
  29782. foreach ($table->getTableMetaData()->getColumns() as $column) {
  29783. $columns .= $connection->quoteSchemaObject($column).', ';
  29784. }
  29785. $columns = substr($columns, 0, -2);
  29786. $query = "
  29787. INSERT INTO {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  29788. ({$columns})
  29789. VALUES
  29790. ({$placeHolders})
  29791. ";
  29792. return $query;
  29793. } else {
  29794. return FALSE;
  29795. }
  29796. }
  29797. protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row)
  29798. {
  29799. $args = array();
  29800. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  29801. $args[] = $table->getValue($row, $columnName);
  29802. }
  29803. return $args;
  29804. }
  29805. protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29806. {
  29807. if (count($databaseTableMetaData->getPrimaryKeys())) {
  29808. return TRUE;
  29809. }
  29810. return FALSE;
  29811. }
  29812. }
  29813. <?php
  29814. /*
  29815. * This file is part of DBUnit.
  29816. *
  29817. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29818. *
  29819. * For the full copyright and license information, please view the LICENSE
  29820. * file that was distributed with this source code.
  29821. */
  29822. /**
  29823. * Deletes the rows in a given dataset using primary key columns.
  29824. *
  29825. * @package DbUnit
  29826. * @author Mike Lively <m@digitalsandwich.com>
  29827. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29828. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29829. * @version Release: @package_version@
  29830. * @link http://www.phpunit.de/
  29831. * @since Class available since Release 1.0.0
  29832. */
  29833. class PHPUnit_Extensions_Database_Operation_Delete extends PHPUnit_Extensions_Database_Operation_RowBased
  29834. {
  29835. protected $operationName = 'DELETE';
  29836. protected $iteratorDirection = self::ITERATOR_TYPE_REVERSE;
  29837. protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29838. {
  29839. $keys = $databaseTableMetaData->getPrimaryKeys();
  29840. $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection));
  29841. $query = "
  29842. DELETE FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  29843. {$whereStatement}
  29844. ";
  29845. return $query;
  29846. }
  29847. protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row)
  29848. {
  29849. $args = array();
  29850. foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) {
  29851. $args[] = $table->getValue($row, $columnName);
  29852. }
  29853. return $args;
  29854. }
  29855. }
  29856. <?php
  29857. /*
  29858. * This file is part of DBUnit.
  29859. *
  29860. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29861. *
  29862. * For the full copyright and license information, please view the LICENSE
  29863. * file that was distributed with this source code.
  29864. */
  29865. /**
  29866. * Provides a basic interface and functionality for executing database
  29867. * operations against a connection using a specific dataSet.
  29868. *
  29869. * @package DbUnit
  29870. * @author Mike Lively <m@digitalsandwich.com>
  29871. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29872. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29873. * @version Release: @package_version@
  29874. * @link http://www.phpunit.de/
  29875. * @since Class available since Release 1.0.0
  29876. */
  29877. interface PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  29878. {
  29879. /**
  29880. * Executes the database operation against the given $connection for the
  29881. * given $dataSet.
  29882. *
  29883. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  29884. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  29885. * @throws PHPUnit_Extensions_Database_Operation_Exception
  29886. */
  29887. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet);
  29888. }
  29889. <?php
  29890. /*
  29891. * This file is part of DBUnit.
  29892. *
  29893. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29894. *
  29895. * For the full copyright and license information, please view the LICENSE
  29896. * file that was distributed with this source code.
  29897. */
  29898. /**
  29899. * This class represents a null database operation.
  29900. *
  29901. * @package DbUnit
  29902. * @author Mike Lively <m@digitalsandwich.com>
  29903. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  29904. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29905. * @version Release: @package_version@
  29906. * @link http://www.phpunit.de/
  29907. * @since Class available since Release 1.0.0
  29908. */
  29909. class PHPUnit_Extensions_Database_Operation_Null implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  29910. {
  29911. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  29912. {
  29913. /* do nothing */
  29914. }
  29915. }
  29916. <?php
  29917. /*
  29918. * This file is part of DBUnit.
  29919. *
  29920. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29921. *
  29922. * For the full copyright and license information, please view the LICENSE
  29923. * file that was distributed with this source code.
  29924. */
  29925. /**
  29926. * Deletes all rows from all tables in a dataset.
  29927. *
  29928. * @package DbUnit
  29929. * @author Mike Lively <m@digitalsandwich.com>
  29930. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29931. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29932. * @version Release: @package_version@
  29933. * @link http://www.phpunit.de/
  29934. * @since Class available since Release 1.0.0
  29935. */
  29936. class PHPUnit_Extensions_Database_Operation_DeleteAll implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  29937. {
  29938. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  29939. {
  29940. foreach ($dataSet->getReverseIterator() as $table) {
  29941. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  29942. $query = "
  29943. DELETE FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  29944. ";
  29945. try {
  29946. $connection->getConnection()->query($query);
  29947. } catch (PDOException $e) {
  29948. throw new PHPUnit_Extensions_Database_Operation_Exception('DELETE_ALL', $query, array(), $table, $e->getMessage());
  29949. }
  29950. }
  29951. }
  29952. }
  29953. <?php
  29954. /*
  29955. * This file is part of DBUnit.
  29956. *
  29957. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29958. *
  29959. * For the full copyright and license information, please view the LICENSE
  29960. * file that was distributed with this source code.
  29961. */
  29962. /**
  29963. * Updates the rows in a given dataset using primary key columns.
  29964. *
  29965. * @package DbUnit
  29966. * @author Mike Lively <m@digitalsandwich.com>
  29967. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29968. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29969. * @version Release: @package_version@
  29970. * @link http://www.phpunit.de/
  29971. * @since Class available since Release 1.0.0
  29972. */
  29973. class PHPUnit_Extensions_Database_Operation_Update extends PHPUnit_Extensions_Database_Operation_RowBased
  29974. {
  29975. protected $operationName = 'UPDATE';
  29976. protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29977. {
  29978. $keys = $databaseTableMetaData->getPrimaryKeys();
  29979. $columns = $table->getTableMetaData()->getColumns();
  29980. $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection));
  29981. $setStatement = 'SET ' . implode(', ', $this->buildPreparedColumnArray($columns, $connection));
  29982. $query = "
  29983. UPDATE {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  29984. {$setStatement}
  29985. {$whereStatement}
  29986. ";
  29987. return $query;
  29988. }
  29989. protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row)
  29990. {
  29991. $args = array();
  29992. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  29993. $args[] = $table->getValue($row, $columnName);
  29994. }
  29995. foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) {
  29996. $args[] = $table->getValue($row, $columnName);
  29997. }
  29998. return $args;
  29999. }
  30000. protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30001. {
  30002. if (count($databaseTableMetaData->getPrimaryKeys())) {
  30003. return TRUE;
  30004. }
  30005. return FALSE;
  30006. }
  30007. }
  30008. <?php
  30009. /*
  30010. * This file is part of DBUnit.
  30011. *
  30012. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30013. *
  30014. * For the full copyright and license information, please view the LICENSE
  30015. * file that was distributed with this source code.
  30016. */
  30017. /**
  30018. * Provides basic functionality for row based operations.
  30019. *
  30020. * To create a row based operation you must create two functions. The first
  30021. * one, buildOperationQuery(), must return a query that will be used to create
  30022. * a prepared statement. The second one, buildOperationArguments(), should
  30023. * return an array containing arguments for each row.
  30024. *
  30025. * @package DbUnit
  30026. * @author Mike Lively <m@digitalsandwich.com>
  30027. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  30028. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30029. * @version Release: @package_version@
  30030. * @link http://www.phpunit.de/
  30031. * @since Class available since Release 1.0.0
  30032. */
  30033. abstract class PHPUnit_Extensions_Database_Operation_RowBased implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30034. {
  30035. const ITERATOR_TYPE_FORWARD = 0;
  30036. const ITERATOR_TYPE_REVERSE = 1;
  30037. protected $operationName;
  30038. protected $iteratorDirection = self::ITERATOR_TYPE_FORWARD;
  30039. /**
  30040. * @return string|boolean String containing the query or FALSE if a valid query cannot be constructed
  30041. */
  30042. protected abstract function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection);
  30043. protected abstract function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row);
  30044. /**
  30045. * Allows an operation to disable primary keys if necessary.
  30046. *
  30047. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData
  30048. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  30049. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  30050. */
  30051. protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30052. {
  30053. return FALSE;
  30054. }
  30055. /**
  30056. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  30057. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  30058. */
  30059. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  30060. {
  30061. $databaseDataSet = $connection->createDataSet();
  30062. $dsIterator = $this->iteratorDirection == self::ITERATOR_TYPE_REVERSE ? $dataSet->getReverseIterator() : $dataSet->getIterator();
  30063. foreach ($dsIterator as $table) {
  30064. $rowCount = $table->getRowCount();
  30065. if($rowCount == 0) continue;
  30066. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  30067. $databaseTableMetaData = $databaseDataSet->getTableMetaData($table->getTableMetaData()->getTableName());
  30068. $query = $this->buildOperationQuery($databaseTableMetaData, $table, $connection);
  30069. $disablePrimaryKeys = $this->disablePrimaryKeys($databaseTableMetaData, $table, $connection);
  30070. if ($query === FALSE) {
  30071. if ($table->getRowCount() > 0) {
  30072. throw new PHPUnit_Extensions_Database_Operation_Exception($this->operationName, '', array(), $table, "Rows requested for insert, but no columns provided!");
  30073. }
  30074. continue;
  30075. }
  30076. if ($disablePrimaryKeys) {
  30077. $connection->disablePrimaryKeys($databaseTableMetaData->getTableName());
  30078. }
  30079. $statement = $connection->getConnection()->prepare($query);
  30080. for ($i = 0; $i < $rowCount; $i++) {
  30081. $args = $this->buildOperationArguments($databaseTableMetaData, $table, $i);
  30082. try {
  30083. $statement->execute($args);
  30084. }
  30085. catch (Exception $e) {
  30086. throw new PHPUnit_Extensions_Database_Operation_Exception(
  30087. $this->operationName, $query, $args, $table, $e->getMessage()
  30088. );
  30089. }
  30090. }
  30091. if ($disablePrimaryKeys) {
  30092. $connection->enablePrimaryKeys($databaseTableMetaData->getTableName());
  30093. }
  30094. }
  30095. }
  30096. protected function buildPreparedColumnArray($columns, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30097. {
  30098. $columnArray = array();
  30099. foreach ($columns as $columnName) {
  30100. $columnArray[] = "{$connection->quoteSchemaObject($columnName)} = ?";
  30101. }
  30102. return $columnArray;
  30103. }
  30104. }
  30105. <?php
  30106. /*
  30107. * This file is part of DBUnit.
  30108. *
  30109. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30110. *
  30111. * For the full copyright and license information, please view the LICENSE
  30112. * file that was distributed with this source code.
  30113. */
  30114. /**
  30115. * A class factory to easily return database operations.
  30116. *
  30117. * @package DbUnit
  30118. * @author Mike Lively <m@digitalsandwich.com>
  30119. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  30120. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30121. * @version Release: @package_version@
  30122. * @link http://www.phpunit.de/
  30123. * @since Class available since Release 1.0.0
  30124. */
  30125. class PHPUnit_Extensions_Database_Operation_Factory
  30126. {
  30127. /**
  30128. * Returns a null database operation
  30129. *
  30130. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30131. */
  30132. public static function NONE()
  30133. {
  30134. return new PHPUnit_Extensions_Database_Operation_Null();
  30135. }
  30136. /**
  30137. * Returns a clean insert database operation. It will remove all contents
  30138. * from the table prior to re-inserting rows.
  30139. *
  30140. * @param bool $cascadeTruncates Set to true to force truncates to cascade on databases that support this.
  30141. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30142. */
  30143. public static function CLEAN_INSERT($cascadeTruncates = FALSE)
  30144. {
  30145. return new PHPUnit_Extensions_Database_Operation_Composite(array(
  30146. self::TRUNCATE($cascadeTruncates),
  30147. self::INSERT()
  30148. ));
  30149. }
  30150. /**
  30151. * Returns an insert database operation.
  30152. *
  30153. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30154. */
  30155. public static function INSERT()
  30156. {
  30157. return new PHPUnit_Extensions_Database_Operation_Insert();
  30158. }
  30159. /**
  30160. * Returns a truncate database operation.
  30161. *
  30162. * @param bool $cascadeTruncates Set to true to force truncates to cascade on databases that support this.
  30163. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30164. */
  30165. public static function TRUNCATE($cascadeTruncates = FALSE)
  30166. {
  30167. $truncate = new PHPUnit_Extensions_Database_Operation_Truncate();
  30168. $truncate->setCascade($cascadeTruncates);
  30169. return $truncate;
  30170. }
  30171. /**
  30172. * Returns a delete database operation.
  30173. *
  30174. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30175. */
  30176. public static function DELETE()
  30177. {
  30178. return new PHPUnit_Extensions_Database_Operation_Delete();
  30179. }
  30180. /**
  30181. * Returns a delete_all database operation.
  30182. *
  30183. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30184. */
  30185. public static function DELETE_ALL()
  30186. {
  30187. return new PHPUnit_Extensions_Database_Operation_DeleteAll();
  30188. }
  30189. /**
  30190. * Returns an update database operation.
  30191. *
  30192. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30193. */
  30194. public static function UPDATE()
  30195. {
  30196. return new PHPUnit_Extensions_Database_Operation_Update();
  30197. }
  30198. }
  30199. <?php
  30200. /*
  30201. * This file is part of DBUnit.
  30202. *
  30203. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30204. *
  30205. * For the full copyright and license information, please view the LICENSE
  30206. * file that was distributed with this source code.
  30207. */
  30208. /**
  30209. * This class facilitates combining database operations. To create a composite
  30210. * operation pass an array of classes that implement
  30211. * PHPUnit_Extensions_Database_Operation_IDatabaseOperation and they will be
  30212. * executed in that order against all data sets.
  30213. *
  30214. * @package DbUnit
  30215. * @author Mike Lively <m@digitalsandwich.com>
  30216. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  30217. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30218. * @version Release: @package_version@
  30219. * @link http://www.phpunit.de/
  30220. * @since Class available since Release 1.0.0
  30221. */
  30222. class PHPUnit_Extensions_Database_Operation_Composite implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30223. {
  30224. /**
  30225. * @var array
  30226. */
  30227. protected $operations = array();
  30228. /**
  30229. * Creates a composite operation.
  30230. *
  30231. * @param array $operations
  30232. */
  30233. public function __construct(Array $operations)
  30234. {
  30235. foreach ($operations as $operation) {
  30236. if ($operation instanceof PHPUnit_Extensions_Database_Operation_IDatabaseOperation) {
  30237. $this->operations[] = $operation;
  30238. } else {
  30239. throw new InvalidArgumentException("Only database operation instances can be passed to a composite database operation.");
  30240. }
  30241. }
  30242. }
  30243. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  30244. {
  30245. try {
  30246. foreach ($this->operations as $operation) {
  30247. /* @var $operation PHPUnit_Extensions_Database_Operation_IDatabaseOperation */
  30248. $operation->execute($connection, $dataSet);
  30249. }
  30250. } catch (PHPUnit_Extensions_Database_Operation_Exception $e) {
  30251. throw new PHPUnit_Extensions_Database_Operation_Exception("COMPOSITE[{$e->getOperation()}]", $e->getQuery(), $e->getArgs(), $e->getTable(), $e->getError());
  30252. }
  30253. }
  30254. }
  30255. <?php
  30256. /*
  30257. * This file is part of DBUnit.
  30258. *
  30259. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30260. *
  30261. * For the full copyright and license information, please view the LICENSE
  30262. * file that was distributed with this source code.
  30263. */
  30264. /**
  30265. * Executes a truncate against all tables in a dataset.
  30266. *
  30267. * @package DbUnit
  30268. * @author Mike Lively <m@digitalsandwich.com>
  30269. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  30270. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30271. * @version Release: @package_version@
  30272. * @link http://www.phpunit.de/
  30273. * @since Class available since Release 1.0.0
  30274. */
  30275. class PHPUnit_Extensions_Database_Operation_Truncate implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30276. {
  30277. protected $useCascade = FALSE;
  30278. public function setCascade($cascade = TRUE)
  30279. {
  30280. $this->useCascade = $cascade;
  30281. }
  30282. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  30283. {
  30284. foreach ($dataSet->getReverseIterator() as $table) {
  30285. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  30286. $query = "
  30287. {$connection->getTruncateCommand()} {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  30288. ";
  30289. if ($this->useCascade && $connection->allowsCascading()) {
  30290. $query .= " CASCADE";
  30291. }
  30292. try {
  30293. $this->disableForeignKeyChecksForMysql($connection);
  30294. $connection->getConnection()->query($query);
  30295. $this->enableForeignKeyChecksForMysql($connection);
  30296. } catch (\Exception $e) {
  30297. $this->enableForeignKeyChecksForMysql($connection);
  30298. if ($e instanceof PDOException) {
  30299. throw new PHPUnit_Extensions_Database_Operation_Exception('TRUNCATE', $query, array(), $table, $e->getMessage());
  30300. }
  30301. throw $e;
  30302. }
  30303. }
  30304. }
  30305. private function disableForeignKeyChecksForMysql(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30306. {
  30307. if ($this->isMysql($connection)) {
  30308. $connection->getConnection()->query('SET FOREIGN_KEY_CHECKS = 0');
  30309. }
  30310. }
  30311. private function enableForeignKeyChecksForMysql(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30312. {
  30313. if ($this->isMysql($connection)) {
  30314. $connection->getConnection()->query('SET FOREIGN_KEY_CHECKS = 1');
  30315. }
  30316. }
  30317. private function isMysql(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30318. {
  30319. return $connection->getConnection()->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql';
  30320. }
  30321. }
  30322. <?php
  30323. /*
  30324. * This file is part of DBUnit.
  30325. *
  30326. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30327. *
  30328. * For the full copyright and license information, please view the LICENSE
  30329. * file that was distributed with this source code.
  30330. */
  30331. /**
  30332. * A TestCase extension that provides functionality for testing and asserting
  30333. * against a real database.
  30334. *
  30335. * @package DbUnit
  30336. * @author Mike Lively <m@digitalsandwich.com>
  30337. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  30338. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30339. * @version Release: @package_version@
  30340. * @link http://www.phpunit.de/
  30341. * @since Class available since Release 1.0.0
  30342. */
  30343. abstract class PHPUnit_Extensions_Database_TestCase extends PHPUnit_Framework_TestCase
  30344. {
  30345. /**
  30346. * @var PHPUnit_Extensions_Database_ITester
  30347. */
  30348. protected $databaseTester;
  30349. /**
  30350. * Closes the specified connection.
  30351. *
  30352. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  30353. */
  30354. protected function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30355. {
  30356. $this->getDatabaseTester()->closeConnection($connection);
  30357. }
  30358. /**
  30359. * Returns the test database connection.
  30360. *
  30361. * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
  30362. */
  30363. protected abstract function getConnection();
  30364. /**
  30365. * Gets the IDatabaseTester for this testCase. If the IDatabaseTester is
  30366. * not set yet, this method calls newDatabaseTester() to obtain a new
  30367. * instance.
  30368. *
  30369. * @return PHPUnit_Extensions_Database_ITester
  30370. */
  30371. protected function getDatabaseTester()
  30372. {
  30373. if (empty($this->databaseTester)) {
  30374. $this->databaseTester = $this->newDatabaseTester();
  30375. }
  30376. return $this->databaseTester;
  30377. }
  30378. /**
  30379. * Returns the test dataset.
  30380. *
  30381. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  30382. */
  30383. protected abstract function getDataSet();
  30384. /**
  30385. * Returns the database operation executed in test setup.
  30386. *
  30387. * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation
  30388. */
  30389. protected function getSetUpOperation()
  30390. {
  30391. return PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT();
  30392. }
  30393. /**
  30394. * Returns the database operation executed in test cleanup.
  30395. *
  30396. * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation
  30397. */
  30398. protected function getTearDownOperation()
  30399. {
  30400. return PHPUnit_Extensions_Database_Operation_Factory::NONE();
  30401. }
  30402. /**
  30403. * Creates a IDatabaseTester for this testCase.
  30404. *
  30405. * @return PHPUnit_Extensions_Database_ITester
  30406. */
  30407. protected function newDatabaseTester()
  30408. {
  30409. return new PHPUnit_Extensions_Database_DefaultTester($this->getConnection());
  30410. }
  30411. /**
  30412. * Creates a new DefaultDatabaseConnection using the given PDO connection
  30413. * and database schema name.
  30414. *
  30415. * @param PDO $connection
  30416. * @param string $schema
  30417. * @return PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection
  30418. */
  30419. protected function createDefaultDBConnection(PDO $connection, $schema = '')
  30420. {
  30421. return new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($connection, $schema);
  30422. }
  30423. /**
  30424. * Creates a new ArrayDataSet with the given array.
  30425. * The array parameter is an associative array of tables where the key is
  30426. * the table name and the value an array of rows. Each row is an associative
  30427. * array by itself with keys representing the field names and the values the
  30428. * actual data.
  30429. * For example:
  30430. * array(
  30431. * "addressbook" => array(
  30432. * array("id" => 1, "name" => "...", "address" => "..."),
  30433. * array("id" => 2, "name" => "...", "address" => "...")
  30434. * )
  30435. * )
  30436. *
  30437. * @param array $data
  30438. * @return PHPUnit_Extensions_Database_DataSet_ArrayDataSet
  30439. */
  30440. protected function createArrayDataSet(array $data)
  30441. {
  30442. return new PHPUnit_Extensions_Database_DataSet_ArrayDataSet($data);
  30443. }
  30444. /**
  30445. * Creates a new FlatXmlDataSet with the given $xmlFile. (absolute path.)
  30446. *
  30447. * @param string $xmlFile
  30448. * @return PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet
  30449. */
  30450. protected function createFlatXMLDataSet($xmlFile)
  30451. {
  30452. return new PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet($xmlFile);
  30453. }
  30454. /**
  30455. * Creates a new XMLDataSet with the given $xmlFile. (absolute path.)
  30456. *
  30457. * @param string $xmlFile
  30458. * @return PHPUnit_Extensions_Database_DataSet_XmlDataSet
  30459. */
  30460. protected function createXMLDataSet($xmlFile)
  30461. {
  30462. return new PHPUnit_Extensions_Database_DataSet_XmlDataSet($xmlFile);
  30463. }
  30464. /**
  30465. * Create a a new MysqlXmlDataSet with the given $xmlFile. (absolute path.)
  30466. *
  30467. * @param string $xmlFile
  30468. * @return PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet
  30469. * @since Method available since Release 1.0.0
  30470. */
  30471. protected function createMySQLXMLDataSet($xmlFile)
  30472. {
  30473. return new PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet($xmlFile);
  30474. }
  30475. /**
  30476. * Returns an operation factory instance that can be used to instantiate
  30477. * new operations.
  30478. *
  30479. * @return PHPUnit_Extensions_Database_Operation_Factory
  30480. */
  30481. protected function getOperations()
  30482. {
  30483. return new PHPUnit_Extensions_Database_Operation_Factory();
  30484. }
  30485. /**
  30486. * Performs operation returned by getSetUpOperation().
  30487. */
  30488. protected function setUp()
  30489. {
  30490. parent::setUp();
  30491. $this->databaseTester = NULL;
  30492. $this->getDatabaseTester()->setSetUpOperation($this->getSetUpOperation());
  30493. $this->getDatabaseTester()->setDataSet($this->getDataSet());
  30494. $this->getDatabaseTester()->onSetUp();
  30495. }
  30496. /**
  30497. * Performs operation returned by getTearDownOperation().
  30498. */
  30499. protected function tearDown()
  30500. {
  30501. $this->getDatabaseTester()->setTearDownOperation($this->getTearDownOperation());
  30502. $this->getDatabaseTester()->setDataSet($this->getDataSet());
  30503. $this->getDatabaseTester()->onTearDown();
  30504. /**
  30505. * Destroy the tester after the test is run to keep DB connections
  30506. * from piling up.
  30507. */
  30508. $this->databaseTester = NULL;
  30509. }
  30510. /**
  30511. * Asserts that two given tables are equal.
  30512. *
  30513. * @param PHPUnit_Extensions_Database_DataSet_ITable $expected
  30514. * @param PHPUnit_Extensions_Database_DataSet_ITable $actual
  30515. * @param string $message
  30516. */
  30517. public static function assertTablesEqual(PHPUnit_Extensions_Database_DataSet_ITable $expected, PHPUnit_Extensions_Database_DataSet_ITable $actual, $message = '')
  30518. {
  30519. $constraint = new PHPUnit_Extensions_Database_Constraint_TableIsEqual($expected);
  30520. self::assertThat($actual, $constraint, $message);
  30521. }
  30522. /**
  30523. * Asserts that two given datasets are equal.
  30524. *
  30525. * @param PHPUnit_Extensions_Database_DataSet_ITable $expected
  30526. * @param PHPUnit_Extensions_Database_DataSet_ITable $actual
  30527. * @param string $message
  30528. */
  30529. public static function assertDataSetsEqual(PHPUnit_Extensions_Database_DataSet_IDataSet $expected, PHPUnit_Extensions_Database_DataSet_IDataSet $actual, $message = '')
  30530. {
  30531. $constraint = new PHPUnit_Extensions_Database_Constraint_DataSetIsEqual($expected);
  30532. self::assertThat($actual, $constraint, $message);
  30533. }
  30534. /**
  30535. * Assert that a given table has a given amount of rows
  30536. *
  30537. * @param string $tableName Name of the table
  30538. * @param int $expected Expected amount of rows in the table
  30539. * @param string $message Optional message
  30540. */
  30541. public function assertTableRowCount($tableName, $expected, $message = '')
  30542. {
  30543. $constraint = new PHPUnit_Extensions_Database_Constraint_TableRowCount($tableName, $expected);
  30544. $actual = $this->getConnection()->getRowCount($tableName);
  30545. self::assertThat($actual, $constraint, $message);
  30546. }
  30547. /**
  30548. * Asserts that a given table contains a given row
  30549. *
  30550. * @param array $expectedRow Row expected to find
  30551. * @param PHPUnit_Extensions_Database_DataSet_ITable $table Table to look into
  30552. * @param string $message Optional message
  30553. */
  30554. public function assertTableContains(array $expectedRow, PHPUnit_Extensions_Database_DataSet_ITable $table, $message = '')
  30555. {
  30556. self::assertThat($table->assertContainsRow($expectedRow), self::isTrue(), $message);
  30557. }
  30558. }
  30559. <?php
  30560. /*
  30561. * This file is part of DBUnit.
  30562. *
  30563. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30564. *
  30565. * For the full copyright and license information, please view the LICENSE
  30566. * file that was distributed with this source code.
  30567. */
  30568. /**
  30569. * Can be used as a foundation for new DatabaseTesters.
  30570. *
  30571. * @package DbUnit
  30572. * @author Mike Lively <m@digitalsandwich.com>
  30573. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  30574. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30575. * @version Release: @package_version@
  30576. * @link http://www.phpunit.de/
  30577. * @since Class available since Release 1.0.0
  30578. */
  30579. abstract class PHPUnit_Extensions_Database_AbstractTester implements PHPUnit_Extensions_Database_ITester
  30580. {
  30581. /**
  30582. * @var PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30583. */
  30584. protected $setUpOperation;
  30585. /**
  30586. * @var PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30587. */
  30588. protected $tearDownOperation;
  30589. /**
  30590. * @var PHPUnit_Extensions_Database_DataSet_IDataSet
  30591. */
  30592. protected $dataSet;
  30593. /**
  30594. * @var string
  30595. */
  30596. protected $schema;
  30597. /**
  30598. * Creates a new database tester.
  30599. */
  30600. public function __construct()
  30601. {
  30602. $this->setUpOperation = PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT();
  30603. $this->tearDownOperation = PHPUnit_Extensions_Database_Operation_Factory::NONE();
  30604. }
  30605. /**
  30606. * Closes the specified connection.
  30607. *
  30608. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  30609. */
  30610. public function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30611. {
  30612. $connection->close();
  30613. }
  30614. /**
  30615. * Returns the test dataset.
  30616. *
  30617. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  30618. */
  30619. public function getDataSet()
  30620. {
  30621. return $this->dataSet;
  30622. }
  30623. /**
  30624. * TestCases must call this method inside setUp().
  30625. */
  30626. public function onSetUp()
  30627. {
  30628. $this->getSetUpOperation()->execute($this->getConnection(), $this->getDataSet());
  30629. }
  30630. /**
  30631. * TestCases must call this method inside tearDown().
  30632. */
  30633. public function onTearDown()
  30634. {
  30635. $this->getTearDownOperation()->execute($this->getConnection(), $this->getDataSet());
  30636. }
  30637. /**
  30638. * Sets the test dataset to use.
  30639. *
  30640. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  30641. */
  30642. public function setDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  30643. {
  30644. $this->dataSet = $dataSet;
  30645. }
  30646. /**
  30647. * Sets the schema value.
  30648. *
  30649. * @param string $schema
  30650. */
  30651. public function setSchema($schema)
  30652. {
  30653. $this->schema = $schema;
  30654. }
  30655. /**
  30656. * Sets the DatabaseOperation to call when starting the test.
  30657. *
  30658. * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $setUpOperation
  30659. */
  30660. public function setSetUpOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $setUpOperation)
  30661. {
  30662. $this->setUpOperation = $setUpOperation;
  30663. }
  30664. /**
  30665. * Sets the DatabaseOperation to call when ending the test.
  30666. *
  30667. * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $tearDownOperation
  30668. */
  30669. public function setTearDownOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $tearDownOperation)
  30670. {
  30671. $this->tearDownOperation = $tearDownOperation;
  30672. }
  30673. /**
  30674. * Returns the schema value
  30675. *
  30676. * @return string
  30677. */
  30678. protected function getSchema()
  30679. {
  30680. return $this->schema;
  30681. }
  30682. /**
  30683. * Returns the database operation that will be called when starting the test.
  30684. *
  30685. * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation
  30686. */
  30687. protected function getSetUpOperation()
  30688. {
  30689. return $this->setUpOperation;
  30690. }
  30691. /**
  30692. * Returns the database operation that will be called when ending the test.
  30693. *
  30694. * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation
  30695. */
  30696. protected function getTearDownOperation()
  30697. {
  30698. return $this->tearDownOperation;
  30699. }
  30700. }
  30701. <?php
  30702. /*
  30703. * This file is part of DBUnit.
  30704. *
  30705. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30706. *
  30707. * For the full copyright and license information, please view the LICENSE
  30708. * file that was distributed with this source code.
  30709. */
  30710. /**
  30711. * Provides functionality to retrieve meta data from an Sqlite database.
  30712. *
  30713. * @package DbUnit
  30714. * @author Mike Lively <m@digitalsandwich.com>
  30715. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  30716. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30717. * @version Release: @package_version@
  30718. * @link http://www.phpunit.de/
  30719. * @since Class available since Release 1.0.0
  30720. */
  30721. class PHPUnit_Extensions_Database_DB_MetaData_Sqlite extends PHPUnit_Extensions_Database_DB_MetaData
  30722. {
  30723. protected $columns = array();
  30724. protected $keys = array();
  30725. protected $truncateCommand = 'DELETE FROM';
  30726. /**
  30727. * Returns an array containing the names of all the tables in the database.
  30728. *
  30729. * @return array
  30730. */
  30731. public function getTableNames()
  30732. {
  30733. $query = "
  30734. SELECT name
  30735. FROM sqlite_master
  30736. WHERE
  30737. type='table' AND
  30738. name <> 'sqlite_sequence'
  30739. ORDER BY name
  30740. ";
  30741. $result = $this->pdo->query($query);
  30742. $tableNames = array();
  30743. while ($tableName = $result->fetchColumn(0)) {
  30744. $tableNames[] = $tableName;
  30745. }
  30746. return $tableNames;
  30747. }
  30748. /**
  30749. * Returns an array containing the names of all the columns in the
  30750. * $tableName table,
  30751. *
  30752. * @param string $tableName
  30753. * @return array
  30754. */
  30755. public function getTableColumns($tableName)
  30756. {
  30757. if (!isset($this->columns[$tableName])) {
  30758. $this->loadColumnInfo($tableName);
  30759. }
  30760. return $this->columns[$tableName];
  30761. }
  30762. /**
  30763. * Returns an array containing the names of all the primary key columns in
  30764. * the $tableName table.
  30765. *
  30766. * @param string $tableName
  30767. * @return array
  30768. */
  30769. public function getTablePrimaryKeys($tableName)
  30770. {
  30771. if (!isset($this->keys[$tableName])) {
  30772. $this->loadColumnInfo($tableName);
  30773. }
  30774. return $this->keys[$tableName];
  30775. }
  30776. /**
  30777. * Loads column info from a sqlite database.
  30778. *
  30779. * @param string $tableName
  30780. */
  30781. protected function loadColumnInfo($tableName)
  30782. {
  30783. $query = "PRAGMA table_info('{$tableName}')";
  30784. $statement = $this->pdo->query($query);
  30785. /* @var $statement PDOStatement */
  30786. $this->columns[$tableName] = array();
  30787. $this->keys[$tableName] = array();
  30788. while ($columnData = $statement->fetch(PDO::FETCH_NUM)) {
  30789. $this->columns[$tableName][] = $columnData[1];
  30790. if ($columnData[5] == 1) {
  30791. $this->keys[$tableName][] = $columnData[1];
  30792. }
  30793. }
  30794. }
  30795. }
  30796. <?php
  30797. /**
  30798. * Provides functionality to retrieve meta data from an Dblib (SQL Server) database.
  30799. *
  30800. * @package DbUnit
  30801. * @author Tom Ford <tom@switchsystems.co.uk>
  30802. * @copyright Sebastian Bergmann <sb@sebastian-bergmann.de>
  30803. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  30804. * @link http://www.phpunit.de/
  30805. */
  30806. class PHPUnit_Extensions_Database_DB_MetaData_Dblib extends PHPUnit_Extensions_Database_DB_MetaData
  30807. {
  30808. /**
  30809. * No character used to quote schema objects.
  30810. * @var string
  30811. */
  30812. protected $schemaObjectQuoteChar = '';
  30813. /**
  30814. * The command used to perform a TRUNCATE operation.
  30815. * @var string
  30816. */
  30817. protected $truncateCommand = 'TRUNCATE TABLE';
  30818. /**
  30819. * @var array
  30820. */
  30821. protected $columns = array();
  30822. /**
  30823. * @var array
  30824. */
  30825. protected $keys = array();
  30826. /**
  30827. * Returns an array containing the names of all the tables in the database.
  30828. *
  30829. * @return array
  30830. */
  30831. public function getTableNames()
  30832. {
  30833. $tableNames = array();
  30834. $query = "SELECT name
  30835. FROM sys.tables
  30836. ORDER BY name";
  30837. $result = $this->pdo->query($query);
  30838. while ($tableName = $result->fetchColumn(0)) {
  30839. $tableNames[] = $tableName;
  30840. }
  30841. return $tableNames;
  30842. }
  30843. /**
  30844. * Returns an array containing the names of all the columns in the
  30845. * $tableName table,
  30846. *
  30847. * @param string $tableName
  30848. * @return array
  30849. */
  30850. public function getTableColumns($tableName)
  30851. {
  30852. if (!isset($this->columns[$tableName])) {
  30853. $this->loadColumnInfo($tableName);
  30854. }
  30855. return $this->columns[$tableName];
  30856. }
  30857. /**
  30858. * Returns an array containing the names of all the primary key columns in
  30859. * the $tableName table.
  30860. *
  30861. * @param string $tableName
  30862. * @return array
  30863. */
  30864. public function getTablePrimaryKeys($tableName)
  30865. {
  30866. if (!isset($this->keys[$tableName])) {
  30867. $this->loadColumnInfo($tableName);
  30868. }
  30869. return $this->keys[$tableName];
  30870. }
  30871. /**
  30872. * Loads column info from a sql server database.
  30873. *
  30874. * @param string $tableName
  30875. */
  30876. protected function loadColumnInfo($tableName)
  30877. {
  30878. $query = "SELECT name
  30879. FROM sys.columns
  30880. WHERE object_id = OBJECT_ID('".$tableName."')
  30881. ORDER BY column_id";
  30882. $result = $this->pdo->query($query);
  30883. while ($columnName = $result->fetchColumn(0)) {
  30884. $this->columns[$tableName][] = $columnName;
  30885. }
  30886. $keyQuery = "SELECT COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName
  30887. FROM sys.indexes AS i INNER JOIN
  30888. sys.index_columns AS ic ON i.OBJECT_ID = ic.OBJECT_ID
  30889. AND i.index_id = ic.index_id
  30890. WHERE i.is_primary_key = 1 AND OBJECT_NAME(ic.OBJECT_ID) = '".$tableName."'";
  30891. $result = $this->pdo->query($keyQuery);
  30892. while ($columnName = $result->fetchColumn(0)) {
  30893. $this->keys[$tableName][] = $columnName;
  30894. }
  30895. }
  30896. }
  30897. <?php
  30898. /*
  30899. * This file is part of DBUnit.
  30900. *
  30901. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30902. *
  30903. * For the full copyright and license information, please view the LICENSE
  30904. * file that was distributed with this source code.
  30905. */
  30906. /**
  30907. * Provides functionality to retrieve meta data from a MySQL database.
  30908. *
  30909. * @package DbUnit
  30910. * @author Mike Lively <m@digitalsandwich.com>
  30911. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  30912. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30913. * @version Release: @package_version@
  30914. * @link http://www.phpunit.de/
  30915. * @since Class available since Release 1.0.0
  30916. */
  30917. class PHPUnit_Extensions_Database_DB_MetaData_MySQL extends PHPUnit_Extensions_Database_DB_MetaData
  30918. {
  30919. protected $schemaObjectQuoteChar = '`';
  30920. /**
  30921. * Returns an array containing the names of all the tables in the database.
  30922. *
  30923. * @return array
  30924. */
  30925. public function getTableNames()
  30926. {
  30927. $query = 'SHOW TABLES';
  30928. $statement = $this->pdo->prepare($query);
  30929. $statement->execute();
  30930. $tableNames = array();
  30931. while (($tableName = $statement->fetchColumn(0))) {
  30932. $tableNames[] = $tableName;
  30933. }
  30934. return $tableNames;
  30935. }
  30936. /**
  30937. * Returns an array containing the names of all the columns in the
  30938. * $tableName table,
  30939. *
  30940. * @param string $tableName
  30941. * @return array
  30942. */
  30943. public function getTableColumns($tableName)
  30944. {
  30945. $query = 'SHOW COLUMNS FROM ' . $this->quoteSchemaObject($tableName);
  30946. $statement = $this->pdo->prepare($query);
  30947. $statement->execute();
  30948. $columnNames = array();
  30949. while (($columnName = $statement->fetchColumn(0))) {
  30950. $columnNames[] = $columnName;
  30951. }
  30952. return $columnNames;
  30953. }
  30954. /**
  30955. * Returns an array containing the names of all the primary key columns in
  30956. * the $tableName table.
  30957. *
  30958. * @param string $tableName
  30959. * @return array
  30960. */
  30961. public function getTablePrimaryKeys($tableName)
  30962. {
  30963. $query = 'SHOW INDEX FROM ' . $this->quoteSchemaObject($tableName);
  30964. $statement = $this->pdo->prepare($query);
  30965. $statement->execute();
  30966. $statement->setFetchMode(PDO::FETCH_ASSOC);
  30967. $columnNames = array();
  30968. while (($column = $statement->fetch())) {
  30969. if ($column['Key_name'] == 'PRIMARY') {
  30970. $columnNames[] = $column['Column_name'];
  30971. }
  30972. }
  30973. return $columnNames;
  30974. }
  30975. }
  30976. <?php
  30977. /*
  30978. * This file is part of DBUnit.
  30979. *
  30980. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30981. *
  30982. * For the full copyright and license information, please view the LICENSE
  30983. * file that was distributed with this source code.
  30984. */
  30985. /**
  30986. * Provides functionality to retrieve meta data from a database with information_schema support.
  30987. *
  30988. * @package DbUnit
  30989. * @author Mike Lively <m@digitalsandwich.com>
  30990. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  30991. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30992. * @version Release: @package_version@
  30993. * @link http://www.phpunit.de/
  30994. * @since Class available since Release 1.0.0
  30995. */
  30996. class PHPUnit_Extensions_Database_DB_MetaData_InformationSchema extends PHPUnit_Extensions_Database_DB_MetaData
  30997. {
  30998. protected $columns = array();
  30999. protected $keys = array();
  31000. /**
  31001. * Returns an array containing the names of all the tables in the database.
  31002. *
  31003. * @return array
  31004. */
  31005. public function getTableNames()
  31006. {
  31007. $query = "
  31008. SELECT DISTINCT
  31009. TABLE_NAME
  31010. FROM INFORMATION_SCHEMA.TABLES
  31011. WHERE
  31012. TABLE_TYPE='BASE TABLE' AND
  31013. TABLE_SCHEMA = ?
  31014. ORDER BY TABLE_NAME
  31015. ";
  31016. $statement = $this->pdo->prepare($query);
  31017. $statement->execute(array($this->getSchema()));
  31018. $tableNames = array();
  31019. while ($tableName = $statement->fetchColumn(0)) {
  31020. $tableNames[] = $tableName;
  31021. }
  31022. return $tableNames;
  31023. }
  31024. /**
  31025. * Returns an array containing the names of all the columns in the
  31026. * $tableName table,
  31027. *
  31028. * @param string $tableName
  31029. * @return array
  31030. */
  31031. public function getTableColumns($tableName)
  31032. {
  31033. if (!isset($this->columns[$tableName])) {
  31034. $this->loadColumnInfo($tableName);
  31035. }
  31036. return $this->columns[$tableName];
  31037. }
  31038. /**
  31039. * Returns an array containing the names of all the primary key columns in
  31040. * the $tableName table.
  31041. *
  31042. * @param string $tableName
  31043. * @return array
  31044. */
  31045. public function getTablePrimaryKeys($tableName)
  31046. {
  31047. if (!isset($this->keys[$tableName])) {
  31048. $this->loadColumnInfo($tableName);
  31049. }
  31050. return $this->keys[$tableName];
  31051. }
  31052. /**
  31053. * Loads column info from a sqlite database.
  31054. *
  31055. * @param string $tableName
  31056. */
  31057. protected function loadColumnInfo($tableName)
  31058. {
  31059. $this->columns[$tableName] = array();
  31060. $this->keys[$tableName] = array();
  31061. $columnQuery = "
  31062. SELECT DISTINCT
  31063. COLUMN_NAME
  31064. FROM INFORMATION_SCHEMA.COLUMNS
  31065. WHERE
  31066. TABLE_NAME = ? AND
  31067. TABLE_SCHEMA = ?
  31068. ORDER BY ORDINAL_POSITION
  31069. ";
  31070. $columnStatement = $this->pdo->prepare($columnQuery);
  31071. $columnStatement->execute(array($tableName, $this->getSchema()));
  31072. while ($columName = $columnStatement->fetchColumn(0)) {
  31073. $this->columns[$tableName][] = $columName;
  31074. }
  31075. $keyQuery = "
  31076. SELECT
  31077. KCU.COLUMN_NAME
  31078. FROM
  31079. INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC,
  31080. INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU
  31081. WHERE
  31082. TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME AND
  31083. TC.TABLE_NAME = KCU.TABLE_NAME AND
  31084. TC.TABLE_SCHEMA = KCU.TABLE_SCHEMA AND
  31085. TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND
  31086. TC.TABLE_NAME = ? AND
  31087. TC.TABLE_SCHEMA = ?
  31088. ORDER BY
  31089. KCU.ORDINAL_POSITION ASC
  31090. ";
  31091. $keyStatement = $this->pdo->prepare($keyQuery);
  31092. $keyStatement->execute(array($tableName, $this->getSchema()));
  31093. while ($columName = $keyStatement->fetchColumn(0)) {
  31094. $this->keys[$tableName][] = $columName;
  31095. }
  31096. }
  31097. }
  31098. <?php
  31099. /*
  31100. * This file is part of DBUnit.
  31101. *
  31102. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31103. *
  31104. * For the full copyright and license information, please view the LICENSE
  31105. * file that was distributed with this source code.
  31106. */
  31107. /**
  31108. * Provides functionality to retrieve meta data from a Firebird database.
  31109. *
  31110. * @package DbUnit
  31111. * @author Matheus Degiovani (matheus@gigatron.com.br)
  31112. * @copyright 2002-2014 Matheus Degiovani (matheus@gigatron.com.br)
  31113. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  31114. * @version Release: 1.1.2
  31115. * @link http://www.phpunit.de/
  31116. * @since
  31117. */
  31118. class PHPUnit_Extensions_Database_DB_MetaData_Firebird extends PHPUnit_Extensions_Database_DB_MetaData
  31119. {
  31120. /**
  31121. * The command used to perform a TRUNCATE operation.
  31122. * @var string
  31123. */
  31124. protected $truncateCommand = 'DELETE FROM';
  31125. /**
  31126. * Returns an array containing the names of all the tables in the database.
  31127. *
  31128. * @return array
  31129. */
  31130. public function getTableNames()
  31131. {
  31132. $query = "
  31133. SELECT DISTINCT
  31134. TABLE_NAME
  31135. FROM INFORMATION_SCHEMA.TABLES
  31136. WHERE
  31137. TABLE_TYPE='BASE TABLE' AND
  31138. TABLE_SCHEMA = ?
  31139. ORDER BY TABLE_NAME
  31140. ";
  31141. $query = "
  31142. select
  31143. RDB$RELATION_NAME as TABLE_NAME
  31144. from RDB$RELATIONS
  31145. where
  31146. ((RDB$RELATION_TYPE = 0) or
  31147. (RDB$RELATION_TYPE is null)) and
  31148. (RDB$SYSTEM_FLAG = 0)
  31149. order by (RDB$RELATION_NAME)
  31150. ";
  31151. $statement = $this->pdo->prepare($query);
  31152. $statement->execute(array($this->getSchema()));
  31153. $tableNames = array();
  31154. while ($tableName = $statement->fetchColumn(0)) {
  31155. $tableNames[] = $tableName;
  31156. }
  31157. return $tableNames;
  31158. }
  31159. /**
  31160. * Returns an array containing the names of all the columns in the
  31161. * $tableName table,
  31162. *
  31163. * @param string $tableName
  31164. * @return array
  31165. */
  31166. public function getTableColumns($tableName)
  31167. {
  31168. if (!isset($this->columns[$tableName])) {
  31169. $this->loadColumnInfo($tableName);
  31170. }
  31171. return $this->columns[$tableName];
  31172. }
  31173. /**
  31174. * Returns an array containing the names of all the primary key columns in
  31175. * the $tableName table.
  31176. *
  31177. * @param string $tableName
  31178. * @return array
  31179. */
  31180. public function getTablePrimaryKeys($tableName)
  31181. {
  31182. if (!isset($this->keys[$tableName])) {
  31183. $this->loadColumnInfo($tableName);
  31184. }
  31185. return $this->keys[$tableName];
  31186. }
  31187. /**
  31188. * Loads column info from a database table.
  31189. *
  31190. * @param string $tableName
  31191. */
  31192. protected function loadColumnInfo($tableName)
  31193. {
  31194. $this->columns[$tableName] = array();
  31195. $this->keys[$tableName] = array();
  31196. $columnQuery = "
  31197. SELECT DISTINCT
  31198. COLUMN_NAME, ORDINAL_POSITION
  31199. FROM INFORMATION_SCHEMA.COLUMNS
  31200. WHERE
  31201. TABLE_NAME = ? AND
  31202. TABLE_SCHEMA = ?
  31203. ORDER BY ORDINAL_POSITION
  31204. ";
  31205. $columnQuery = "
  31206. select
  31207. rf.RDB\$FIELD_NAME as COLUMN_NAME,
  31208. rf.RDB\$FIELD_POSITION as ORDINAL_POSITION
  31209. from RDB\$RELATION_FIELDS as rf
  31210. where
  31211. upper(RDB\$RELATION_NAME) = upper(?)
  31212. order by
  31213. ORDINAL_POSITION
  31214. ";
  31215. $columnStatement = $this->pdo->prepare($columnQuery);
  31216. $columnStatement->execute(array($tableName));
  31217. while ($columName = $columnStatement->fetchColumn(0)) {
  31218. $this->columns[$tableName][] = $columName;
  31219. }
  31220. $keyQuery = "
  31221. SELECT
  31222. KCU.COLUMN_NAME,
  31223. KCU.ORDINAL_POSITION
  31224. FROM
  31225. INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU
  31226. LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC
  31227. ON TC.TABLE_NAME = KCU.TABLE_NAME
  31228. WHERE
  31229. TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND
  31230. TC.TABLE_NAME = ? AND
  31231. TC.TABLE_SCHEMA = ?
  31232. ORDER BY
  31233. KCU.ORDINAL_POSITION ASC
  31234. ";
  31235. $keyQuery = "
  31236. select
  31237. idseg.rdb\$field_name as COLUMN_NAME,
  31238. idseg.rdb\$field_position as ORDINAL_POSITION,
  31239. rc.rdb\$relation_name as tablename,
  31240. rc.rdb\$constraint_name as pk_name
  31241. from
  31242. RDB\$RELATION_CONSTRAINTS AS rc
  31243. left join
  31244. rdb\$index_segments as idseg on
  31245. (rc.rdb\$index_name = idseg.rdb\$index_name)
  31246. where
  31247. rc.RDB\$CONSTRAINT_TYPE = 'PRIMARY KEY'
  31248. and upper(rc.RDB\$RELATION_NAME) = upper(?)
  31249. order by
  31250. rc.rdb\$constraint_name, idseg.rdb\$field_position
  31251. ";
  31252. $keyStatement = $this->pdo->prepare($keyQuery);
  31253. $keyStatement->execute(array($tableName));
  31254. while ($columName = $keyStatement->fetchColumn(0)) {
  31255. $this->keys[$tableName][] = $columName;
  31256. }
  31257. }
  31258. /**
  31259. * Returns the schema for the connection.
  31260. *
  31261. * @return string
  31262. */
  31263. public function getSchema()
  31264. {
  31265. if (empty($this->schema)) {
  31266. return 'public';
  31267. } else {
  31268. return $this->schema;
  31269. }
  31270. }
  31271. /**
  31272. * Returns true if the rdbms allows cascading
  31273. *
  31274. * @return bool
  31275. */
  31276. public function allowsCascading()
  31277. {
  31278. return false;
  31279. }
  31280. /**
  31281. * Returns a quoted schema object. (table name, column name, etc)
  31282. *
  31283. * @param string $object
  31284. * @return string
  31285. */
  31286. public function quoteSchemaObject($object) {
  31287. return $object; //firebird does not allow object quoting
  31288. }
  31289. }
  31290. <?php
  31291. /*
  31292. * This file is part of DBUnit.
  31293. *
  31294. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31295. *
  31296. * For the full copyright and license information, please view the LICENSE
  31297. * file that was distributed with this source code.
  31298. */
  31299. /**
  31300. * Provides functionality to retrieve meta data from an Oracle database.
  31301. *
  31302. * @package DbUnit
  31303. * @author Trond Hansen <trond@xait.no>
  31304. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  31305. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31306. * @version Release: @package_version@
  31307. * @link http://www.phpunit.de/
  31308. * @since Class available since Release 3.2.3
  31309. */
  31310. class PHPUnit_Extensions_Database_DB_MetaData_Oci extends PHPUnit_Extensions_Database_DB_MetaData
  31311. {
  31312. /**
  31313. * No character used to quote schema objects.
  31314. * @var string
  31315. */
  31316. protected $schemaObjectQuoteChar = '';
  31317. /**
  31318. * The command used to perform a TRUNCATE operation.
  31319. * @var string
  31320. */
  31321. protected $truncateCommand = 'TRUNCATE TABLE';
  31322. /**
  31323. * @var array
  31324. */
  31325. protected $columns = array();
  31326. /**
  31327. * @var array
  31328. */
  31329. protected $keys = array();
  31330. /**
  31331. * Returns an array containing the names of all the tables in the database.
  31332. *
  31333. * @return array
  31334. */
  31335. public function getTableNames()
  31336. {
  31337. $tableNames = array();
  31338. $query = "SELECT table_name
  31339. FROM cat
  31340. WHERE table_type='TABLE'
  31341. ORDER BY table_name";
  31342. $result = $this->pdo->query($query);
  31343. while ($tableName = $result->fetchColumn(0)) {
  31344. $tableNames[] = $tableName;
  31345. }
  31346. return $tableNames;
  31347. }
  31348. /**
  31349. * Returns an array containing the names of all the columns in the
  31350. * $tableName table,
  31351. *
  31352. * @param string $tableName
  31353. * @return array
  31354. */
  31355. public function getTableColumns($tableName)
  31356. {
  31357. if (!isset($this->columns[$tableName])) {
  31358. $this->loadColumnInfo($tableName);
  31359. }
  31360. return $this->columns[$tableName];
  31361. }
  31362. /**
  31363. * Returns an array containing the names of all the primary key columns in
  31364. * the $tableName table.
  31365. *
  31366. * @param string $tableName
  31367. * @return array
  31368. */
  31369. public function getTablePrimaryKeys($tableName)
  31370. {
  31371. if (!isset($this->keys[$tableName])) {
  31372. $this->loadColumnInfo($tableName);
  31373. }
  31374. return $this->keys[$tableName];
  31375. }
  31376. /**
  31377. * Loads column info from a oracle database.
  31378. *
  31379. * @param string $tableName
  31380. */
  31381. protected function loadColumnInfo($tableName)
  31382. {
  31383. $ownerQuery = '';
  31384. $conOwnerQuery = '';
  31385. $tableParts = $this->splitTableName($tableName);
  31386. $this->columns[$tableName] = array();
  31387. $this->keys[$tableName] = array();
  31388. if (!empty($tableParts['schema']))
  31389. {
  31390. $ownerQuery = " AND OWNER = '{$tableParts['schema']}'";
  31391. $conOwnerQuery = " AND a.owner = '{$tableParts['schema']}'";
  31392. }
  31393. $query = "SELECT DISTINCT COLUMN_NAME
  31394. FROM USER_TAB_COLUMNS
  31395. WHERE TABLE_NAME='".$tableParts['table']."'
  31396. $ownerQuery
  31397. ORDER BY COLUMN_NAME";
  31398. $result = $this->pdo->query($query);
  31399. while ($columnName = $result->fetchColumn(0)) {
  31400. $this->columns[$tableName][] = $columnName;
  31401. }
  31402. $keyQuery = "SELECT b.column_name
  31403. FROM user_constraints a, user_cons_columns b
  31404. WHERE a.constraint_type='P'
  31405. AND a.constraint_name=b.constraint_name
  31406. $conOwnerQuery
  31407. AND a.table_name = '".$tableParts['table']."' ";
  31408. $result = $this->pdo->query($keyQuery);
  31409. while ($columnName = $result->fetchColumn(0)) {
  31410. $this->keys[$tableName][] = $columnName;
  31411. }
  31412. }
  31413. }
  31414. <?php
  31415. /*
  31416. * This file is part of DBUnit.
  31417. *
  31418. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31419. *
  31420. * For the full copyright and license information, please view the LICENSE
  31421. * file that was distributed with this source code.
  31422. */
  31423. /**
  31424. * Provides functionality to retrieve meta data from a PostgreSQL database.
  31425. *
  31426. * @package DbUnit
  31427. * @author Mike Lively <m@digitalsandwich.com>
  31428. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  31429. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31430. * @version Release: @package_version@
  31431. * @link http://www.phpunit.de/
  31432. * @since Class available since Release 1.0.0
  31433. */
  31434. class PHPUnit_Extensions_Database_DB_MetaData_PgSQL extends PHPUnit_Extensions_Database_DB_MetaData
  31435. {
  31436. /**
  31437. * Returns an array containing the names of all the tables in the database.
  31438. *
  31439. * @return array
  31440. */
  31441. public function getTableNames()
  31442. {
  31443. $query = "
  31444. SELECT DISTINCT
  31445. TABLE_NAME
  31446. FROM INFORMATION_SCHEMA.TABLES
  31447. WHERE
  31448. TABLE_TYPE='BASE TABLE' AND
  31449. TABLE_SCHEMA = ?
  31450. ORDER BY TABLE_NAME
  31451. ";
  31452. $statement = $this->pdo->prepare($query);
  31453. $statement->execute(array($this->getSchema()));
  31454. $tableNames = array();
  31455. while ($tableName = $statement->fetchColumn(0)) {
  31456. $tableNames[] = $tableName;
  31457. }
  31458. return $tableNames;
  31459. }
  31460. /**
  31461. * Returns an array containing the names of all the columns in the
  31462. * $tableName table,
  31463. *
  31464. * @param string $tableName
  31465. * @return array
  31466. */
  31467. public function getTableColumns($tableName)
  31468. {
  31469. if (!isset($this->columns[$tableName])) {
  31470. $this->loadColumnInfo($tableName);
  31471. }
  31472. return $this->columns[$tableName];
  31473. }
  31474. /**
  31475. * Returns an array containing the names of all the primary key columns in
  31476. * the $tableName table.
  31477. *
  31478. * @param string $tableName
  31479. * @return array
  31480. */
  31481. public function getTablePrimaryKeys($tableName)
  31482. {
  31483. if (!isset($this->keys[$tableName])) {
  31484. $this->loadColumnInfo($tableName);
  31485. }
  31486. return $this->keys[$tableName];
  31487. }
  31488. /**
  31489. * Loads column info from a database table.
  31490. *
  31491. * @param string $tableName
  31492. */
  31493. protected function loadColumnInfo($tableName)
  31494. {
  31495. $this->columns[$tableName] = array();
  31496. $this->keys[$tableName] = array();
  31497. $columnQuery = "
  31498. SELECT DISTINCT
  31499. COLUMN_NAME, ORDINAL_POSITION
  31500. FROM INFORMATION_SCHEMA.COLUMNS
  31501. WHERE
  31502. TABLE_NAME = ? AND
  31503. TABLE_SCHEMA = ?
  31504. ORDER BY ORDINAL_POSITION
  31505. ";
  31506. $columnStatement = $this->pdo->prepare($columnQuery);
  31507. $columnStatement->execute(array($tableName, $this->getSchema()));
  31508. while ($columName = $columnStatement->fetchColumn(0)) {
  31509. $this->columns[$tableName][] = $columName;
  31510. }
  31511. $keyQuery = "
  31512. SELECT
  31513. KCU.COLUMN_NAME,
  31514. KCU.ORDINAL_POSITION
  31515. FROM
  31516. INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU
  31517. LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC
  31518. ON TC.TABLE_NAME = KCU.TABLE_NAME AND
  31519. TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME
  31520. WHERE
  31521. TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND
  31522. TC.TABLE_NAME = ? AND
  31523. TC.TABLE_SCHEMA = ?
  31524. ORDER BY
  31525. KCU.ORDINAL_POSITION ASC
  31526. ";
  31527. $keyStatement = $this->pdo->prepare($keyQuery);
  31528. $keyStatement->execute(array($tableName, $this->getSchema()));
  31529. while ($columName = $keyStatement->fetchColumn(0)) {
  31530. $this->keys[$tableName][] = $columName;
  31531. }
  31532. }
  31533. /**
  31534. * Returns the schema for the connection.
  31535. *
  31536. * @return string
  31537. */
  31538. public function getSchema()
  31539. {
  31540. if (empty($this->schema)) {
  31541. return 'public';
  31542. } else {
  31543. return $this->schema;
  31544. }
  31545. }
  31546. /**
  31547. * Returns true if the rdbms allows cascading
  31548. *
  31549. * @return bool
  31550. */
  31551. public function allowsCascading()
  31552. {
  31553. return TRUE;
  31554. }
  31555. }
  31556. <?php
  31557. /*
  31558. * This file is part of DBUnit.
  31559. *
  31560. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31561. *
  31562. * For the full copyright and license information, please view the LICENSE
  31563. * file that was distributed with this source code.
  31564. */
  31565. /**
  31566. * Provides functionality to retrieve meta data from a Microsoft SQL Server database.
  31567. *
  31568. * @package DbUnit
  31569. * @author Nils Adermann <naderman@naderman.de>
  31570. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  31571. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31572. * @version Release: @package_version@
  31573. * @link http://www.phpunit.de/
  31574. * @since Class available since Release 1.1.0
  31575. */
  31576. class PHPUnit_Extensions_Database_DB_MetaData_SqlSrv extends PHPUnit_Extensions_Database_DB_MetaData
  31577. {
  31578. /**
  31579. * No character used to quote schema objects.
  31580. * @var string
  31581. */
  31582. protected $schemaObjectQuoteChar = '';
  31583. /**
  31584. * The command used to perform a TRUNCATE operation.
  31585. * @var string
  31586. */
  31587. protected $truncateCommand = 'TRUNCATE TABLE';
  31588. /**
  31589. * Returns an array containing the names of all the tables in the database.
  31590. *
  31591. * @return array
  31592. */
  31593. public function getTableNames()
  31594. {
  31595. $query = "SELECT name
  31596. FROM sysobjects
  31597. WHERE type='U'";
  31598. $statement = $this->pdo->prepare($query);
  31599. $statement->execute();
  31600. $tableNames = array();
  31601. while (($tableName = $statement->fetchColumn(0))) {
  31602. $tableNames[] = $tableName;
  31603. }
  31604. return $tableNames;
  31605. }
  31606. /**
  31607. * Returns an array containing the names of all the columns in the
  31608. * $tableName table.
  31609. *
  31610. * @param string $tableName
  31611. * @return array
  31612. */
  31613. public function getTableColumns($tableName)
  31614. {
  31615. $query = "SELECT c.name
  31616. FROM syscolumns c
  31617. LEFT JOIN sysobjects o ON c.id = o.id
  31618. WHERE o.name = '$tableName'";
  31619. $statement = $this->pdo->prepare($query);
  31620. $statement->execute();
  31621. $columnNames = array();
  31622. while (($columnName = $statement->fetchColumn(0))) {
  31623. $columnNames[] = $columnName;
  31624. }
  31625. return $columnNames;
  31626. }
  31627. /**
  31628. * Returns an array containing the names of all the primary key columns in
  31629. * the $tableName table.
  31630. *
  31631. * @param string $tableName
  31632. * @return array
  31633. */
  31634. public function getTablePrimaryKeys($tableName)
  31635. {
  31636. $query = "EXEC sp_statistics '$tableName'";
  31637. $statement = $this->pdo->prepare($query);
  31638. $statement->execute();
  31639. $statement->setFetchMode(PDO::FETCH_ASSOC);
  31640. $columnNames = array();
  31641. while (($column = $statement->fetch())) {
  31642. if ($column['TYPE'] == 1) {
  31643. $columnNames[] = $column['COLUMN_NAME'];
  31644. }
  31645. }
  31646. return $columnNames;
  31647. }
  31648. /**
  31649. * Allow overwriting identities for the given table.
  31650. *
  31651. * @param string $tableName
  31652. */
  31653. public function disablePrimaryKeys($tableName)
  31654. {
  31655. try {
  31656. $query = "SET IDENTITY_INSERT $tableName ON";
  31657. $this->pdo->exec($query);
  31658. }
  31659. catch (PDOException $e) {
  31660. // ignore the error here - can happen if primary key is not an identity
  31661. }
  31662. }
  31663. /**
  31664. * Reenable auto creation of identities for the given table.
  31665. *
  31666. * @param string $tableName
  31667. */
  31668. public function enablePrimaryKeys($tableName)
  31669. {
  31670. try {
  31671. $query = "SET IDENTITY_INSERT $tableName OFF";
  31672. $this->pdo->exec($query);
  31673. }
  31674. catch (PDOException $e) {
  31675. // ignore the error here - can happen if primary key is not an identity
  31676. }
  31677. }
  31678. }
  31679. <?php
  31680. /*
  31681. * This file is part of DBUnit.
  31682. *
  31683. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31684. *
  31685. * For the full copyright and license information, please view the LICENSE
  31686. * file that was distributed with this source code.
  31687. */
  31688. /**
  31689. * Provides the functionality to represent a database table.
  31690. *
  31691. * @package DbUnit
  31692. * @author Mike Lively <m@digitalsandwich.com>
  31693. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31694. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31695. * @version Release: @package_version@
  31696. * @link http://www.phpunit.de/
  31697. * @since Class available since Release 1.0.0
  31698. */
  31699. class PHPUnit_Extensions_Database_DB_Table extends PHPUnit_Extensions_Database_DataSet_AbstractTable
  31700. {
  31701. /**
  31702. * Creates a new database table object.
  31703. *
  31704. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData
  31705. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection
  31706. */
  31707. public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection)
  31708. {
  31709. $this->setTableMetaData($tableMetaData);
  31710. $pdoStatement = $databaseConnection->getConnection()->prepare(PHPUnit_Extensions_Database_DB_DataSet::buildTableSelect($tableMetaData, $databaseConnection));
  31711. $pdoStatement->execute();
  31712. $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC);
  31713. }
  31714. }
  31715. <?php
  31716. /*
  31717. * This file is part of DBUnit.
  31718. *
  31719. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31720. *
  31721. * For the full copyright and license information, please view the LICENSE
  31722. * file that was distributed with this source code.
  31723. */
  31724. /**
  31725. * Provides access to a database instance as a data set.
  31726. *
  31727. * @package DbUnit
  31728. * @author Mike Lively <m@digitalsandwich.com>
  31729. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31730. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31731. * @version Release: @package_version@
  31732. * @link http://www.phpunit.de/
  31733. * @since Class available since Release 1.0.0
  31734. */
  31735. class PHPUnit_Extensions_Database_DB_FilteredDataSet extends PHPUnit_Extensions_Database_DB_DataSet
  31736. {
  31737. /**
  31738. * @var Array
  31739. */
  31740. protected $tableNames;
  31741. /**
  31742. * Creates a new dataset using the given database connection.
  31743. *
  31744. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection
  31745. */
  31746. public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection, Array $tableNames)
  31747. {
  31748. parent::__construct($databaseConnection);
  31749. $this->tableNames = $tableNames;
  31750. }
  31751. /**
  31752. * Returns a list of table names for the database
  31753. *
  31754. * @return Array
  31755. */
  31756. public function getTableNames()
  31757. {
  31758. return $this->tableNames;
  31759. }
  31760. }
  31761. <?php
  31762. /*
  31763. * This file is part of DBUnit.
  31764. *
  31765. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31766. *
  31767. * For the full copyright and license information, please view the LICENSE
  31768. * file that was distributed with this source code.
  31769. */
  31770. /**
  31771. * Provides a basic interface for communicating with a database.
  31772. *
  31773. * @package DbUnit
  31774. * @author Mike Lively <m@digitalsandwich.com>
  31775. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31776. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31777. * @version Release: @package_version@
  31778. * @link http://www.phpunit.de/
  31779. * @since Class available since Release 1.0.0
  31780. */
  31781. interface PHPUnit_Extensions_Database_DB_IDatabaseConnection
  31782. {
  31783. /**
  31784. * Close this connection.
  31785. */
  31786. public function close();
  31787. /**
  31788. * Creates a dataset containing the specified table names. If no table
  31789. * names are specified then it will created a dataset over the entire
  31790. * database.
  31791. *
  31792. * @param array $tableNames
  31793. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  31794. */
  31795. public function createDataSet(Array $tableNames = NULL);
  31796. /**
  31797. * Creates a table with the result of the specified SQL statement.
  31798. *
  31799. * @param string $resultName
  31800. * @param string $sql
  31801. * @return PHPUnit_Extensions_Database_DataSet_ITable
  31802. */
  31803. public function createQueryTable($resultName, $sql);
  31804. /**
  31805. * Returns a PDO Connection
  31806. *
  31807. * @return PDO
  31808. */
  31809. public function getConnection();
  31810. /**
  31811. * Returns a database metadata object that can be used to retrieve table
  31812. * meta data from the database.
  31813. *
  31814. * @return PHPUnit_Extensions_Database_DB_IMetaData
  31815. */
  31816. public function getMetaData();
  31817. /**
  31818. * Returns the number of rows in the given table. You can specify an
  31819. * optional where clause to return a subset of the table.
  31820. *
  31821. * @param string $tableName
  31822. * @param string $whereClause
  31823. * @param int
  31824. */
  31825. public function getRowCount($tableName, $whereClause = NULL);
  31826. /**
  31827. * Returns the schema for the connection.
  31828. *
  31829. * @return string
  31830. */
  31831. public function getSchema();
  31832. /**
  31833. * Returns a quoted schema object. (table name, column name, etc)
  31834. *
  31835. * @param string $object
  31836. * @return string
  31837. */
  31838. public function quoteSchemaObject($object);
  31839. /**
  31840. * Returns the command used to truncate a table.
  31841. *
  31842. * @return string
  31843. */
  31844. public function getTruncateCommand();
  31845. /**
  31846. * Returns true if the connection allows cascading
  31847. *
  31848. * @return bool
  31849. */
  31850. public function allowsCascading();
  31851. /**
  31852. * Disables primary keys if connection does not allow setting them otherwise
  31853. *
  31854. * @param string $tableName
  31855. */
  31856. public function disablePrimaryKeys($tableName);
  31857. /**
  31858. * Reenables primary keys after they have been disabled
  31859. *
  31860. * @param string $tableName
  31861. */
  31862. public function enablePrimaryKeys($tableName);
  31863. }
  31864. <?php
  31865. /*
  31866. * This file is part of DBUnit.
  31867. *
  31868. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31869. *
  31870. * For the full copyright and license information, please view the LICENSE
  31871. * file that was distributed with this source code.
  31872. */
  31873. /**
  31874. * This class loads a table metadata object with database metadata.
  31875. *
  31876. * @package DbUnit
  31877. * @author Mike Lively <m@digitalsandwich.com>
  31878. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31879. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31880. * @version Release: @package_version@
  31881. * @link http://www.phpunit.de/
  31882. * @since Class available since Release 1.0.0
  31883. */
  31884. class PHPUnit_Extensions_Database_DB_TableMetaData extends PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData
  31885. {
  31886. public function __construct($tableName, PHPUnit_Extensions_Database_DB_IMetaData $databaseMetaData)
  31887. {
  31888. $this->tableName = $tableName;
  31889. $this->columns = $databaseMetaData->getTableColumns($tableName);
  31890. $this->primaryKeys = $databaseMetaData->getTablePrimaryKeys($tableName);
  31891. }
  31892. }
  31893. <?php
  31894. /*
  31895. * This file is part of DBUnit.
  31896. *
  31897. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31898. *
  31899. * For the full copyright and license information, please view the LICENSE
  31900. * file that was distributed with this source code.
  31901. */
  31902. /**
  31903. * Provides a basic constructor for all meta data classes and a factory for
  31904. * generating the appropriate meta data class.
  31905. *
  31906. * @package DbUnit
  31907. * @author Mike Lively <m@digitalsandwich.com>
  31908. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31909. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31910. * @version Release: @package_version@
  31911. * @link http://www.phpunit.de/
  31912. * @since Class available since Release 1.0.0
  31913. */
  31914. abstract class PHPUnit_Extensions_Database_DB_MetaData implements PHPUnit_Extensions_Database_DB_IMetaData
  31915. {
  31916. protected static $metaDataClassMap = array(
  31917. 'pgsql' => 'PHPUnit_Extensions_Database_DB_MetaData_PgSQL',
  31918. 'mysql' => 'PHPUnit_Extensions_Database_DB_MetaData_MySQL',
  31919. 'oci' => 'PHPUnit_Extensions_Database_DB_MetaData_Oci',
  31920. 'sqlite' => 'PHPUnit_Extensions_Database_DB_MetaData_Sqlite',
  31921. 'sqlite2'=> 'PHPUnit_Extensions_Database_DB_MetaData_Sqlite',
  31922. 'sqlsrv' => 'PHPUnit_Extensions_Database_DB_MetaData_SqlSrv',
  31923. 'firebird' => 'PHPUnit_Extensions_Database_DB_MetaData_Firebird',
  31924. 'dblib' => 'PHPUnit_Extensions_Database_DB_MetaData_Dblib'
  31925. );
  31926. /**
  31927. * The PDO connection used to retreive database meta data
  31928. *
  31929. * @var PDO
  31930. */
  31931. protected $pdo;
  31932. /**
  31933. * The default schema name for the meta data object.
  31934. *
  31935. * @var string
  31936. */
  31937. protected $schema;
  31938. /**
  31939. * The character used to quote schema objects.
  31940. */
  31941. protected $schemaObjectQuoteChar = '"';
  31942. /**
  31943. * The command used to perform a TRUNCATE operation.
  31944. */
  31945. protected $truncateCommand = 'TRUNCATE';
  31946. /**
  31947. * Creates a new database meta data object using the given pdo connection
  31948. * and schema name.
  31949. *
  31950. * @param PDO $pdo
  31951. * @param string $schema
  31952. */
  31953. public final function __construct(PDO $pdo, $schema = '')
  31954. {
  31955. $this->pdo = $pdo;
  31956. $this->schema = $schema;
  31957. }
  31958. /**
  31959. * Creates a meta data object based on the driver of given $pdo object and
  31960. * $schema name.
  31961. *
  31962. * @param PDO $pdo
  31963. * @param string $schema
  31964. * @return PHPUnit_Extensions_Database_DB_MetaData
  31965. */
  31966. public static function createMetaData(PDO $pdo, $schema = '')
  31967. {
  31968. $driverName = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
  31969. if (isset(self::$metaDataClassMap[$driverName])) {
  31970. $className = self::$metaDataClassMap[$driverName];
  31971. if ($className instanceof ReflectionClass) {
  31972. return $className->newInstance($pdo, $schema);
  31973. } else {
  31974. return self::registerClassWithDriver($className, $driverName)->newInstance($pdo, $schema);
  31975. }
  31976. } else {
  31977. throw new PHPUnit_Extensions_Database_Exception("Could not find a meta data driver for {$driverName} pdo driver.");
  31978. }
  31979. }
  31980. /**
  31981. * Validates and registers the given $className with the given $pdoDriver.
  31982. * It should be noted that this function will not attempt to include /
  31983. * require the file. The $pdoDriver can be determined by the value of the
  31984. * PDO::ATTR_DRIVER_NAME attribute for a pdo object.
  31985. *
  31986. * A reflection of the $className is returned.
  31987. *
  31988. * @param string $className
  31989. * @param string $pdoDriver
  31990. * @return ReflectionClass
  31991. */
  31992. public static function registerClassWithDriver($className, $pdoDriver)
  31993. {
  31994. if (!class_exists($className)) {
  31995. throw new PHPUnit_Extensions_Database_Exception("Specified class for {$pdoDriver} driver ({$className}) does not exist.");
  31996. }
  31997. $reflection = new ReflectionClass($className);
  31998. if ($reflection->isSubclassOf('PHPUnit_Extensions_Database_DB_MetaData')) {
  31999. return self::$metaDataClassMap[$pdoDriver] = $reflection;
  32000. } else {
  32001. throw new PHPUnit_Extensions_Database_Exception("Specified class for {$pdoDriver} driver ({$className}) does not extend PHPUnit_Extensions_Database_DB_MetaData.");
  32002. }
  32003. }
  32004. /**
  32005. * Returns the schema for the connection.
  32006. *
  32007. * @return string
  32008. */
  32009. public function getSchema()
  32010. {
  32011. return $this->schema;
  32012. }
  32013. /**
  32014. * Returns a quoted schema object. (table name, column name, etc)
  32015. *
  32016. * @param string $object
  32017. * @return string
  32018. */
  32019. public function quoteSchemaObject($object)
  32020. {
  32021. $parts = explode('.', $object);
  32022. $quotedParts = array();
  32023. foreach ($parts as $part) {
  32024. $quotedParts[] = $this->schemaObjectQuoteChar .
  32025. str_replace($this->schemaObjectQuoteChar, $this->schemaObjectQuoteChar.$this->schemaObjectQuoteChar, $part).
  32026. $this->schemaObjectQuoteChar;
  32027. }
  32028. return implode('.', $quotedParts);
  32029. }
  32030. /**
  32031. * Seperates the schema and the table from a fully qualified table name.
  32032. *
  32033. * Returns an associative array containing the 'schema' and the 'table'.
  32034. *
  32035. * @param string $fullTableName
  32036. * @return array
  32037. */
  32038. public function splitTableName($fullTableName)
  32039. {
  32040. if (($dot = strpos($fullTableName, '.')) !== FALSE) {
  32041. return array(
  32042. 'schema' => substr($fullTableName, 0, $dot),
  32043. 'table' => substr($fullTableName, $dot + 1)
  32044. );
  32045. } else {
  32046. return array(
  32047. 'schema' => NULL,
  32048. 'table' => $fullTableName
  32049. );
  32050. }
  32051. }
  32052. /**
  32053. * Returns the command for the database to truncate a table.
  32054. *
  32055. * @return string
  32056. */
  32057. public function getTruncateCommand()
  32058. {
  32059. return $this->truncateCommand;
  32060. }
  32061. /**
  32062. * Returns true if the rdbms allows cascading
  32063. *
  32064. * @return bool
  32065. */
  32066. public function allowsCascading()
  32067. {
  32068. return FALSE;
  32069. }
  32070. /**
  32071. * Disables primary keys if the rdbms does not allow setting them otherwise
  32072. *
  32073. * @param string $tableName
  32074. */
  32075. public function disablePrimaryKeys($tableName)
  32076. {
  32077. return;
  32078. }
  32079. /**
  32080. * Reenables primary keys after they have been disabled
  32081. *
  32082. * @param string $tableName
  32083. */
  32084. public function enablePrimaryKeys($tableName)
  32085. {
  32086. return;
  32087. }
  32088. }
  32089. <?php
  32090. /*
  32091. * This file is part of DBUnit.
  32092. *
  32093. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32094. *
  32095. * For the full copyright and license information, please view the LICENSE
  32096. * file that was distributed with this source code.
  32097. */
  32098. /**
  32099. * Provides a basic interface for communicating with a database.
  32100. *
  32101. * @package DbUnit
  32102. * @author Mike Lively <m@digitalsandwich.com>
  32103. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32104. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32105. * @version Release: @package_version@
  32106. * @link http://www.phpunit.de/
  32107. * @since Class available since Release 1.0.0
  32108. */
  32109. class PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection implements PHPUnit_Extensions_Database_DB_IDatabaseConnection
  32110. {
  32111. /**
  32112. * @var PDO
  32113. */
  32114. protected $connection;
  32115. /**
  32116. * The metadata object used to retrieve table meta data from the database.
  32117. *
  32118. * @var PHPUnit_Extensions_Database_DB_IMetaData
  32119. */
  32120. protected $metaData;
  32121. /**
  32122. * Creates a new database connection
  32123. *
  32124. * @param PDO $connection
  32125. * @param string $schema - The name of the database schema you will be testing against.
  32126. */
  32127. public function __construct(PDO $connection, $schema = '')
  32128. {
  32129. $this->connection = $connection;
  32130. $this->metaData = PHPUnit_Extensions_Database_DB_MetaData::createMetaData($connection, $schema);
  32131. $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  32132. }
  32133. /**
  32134. * Close this connection.
  32135. */
  32136. public function close()
  32137. {
  32138. unset($this->connection);
  32139. }
  32140. /**
  32141. * Returns a database metadata object that can be used to retrieve table
  32142. * meta data from the database.
  32143. *
  32144. * @return PHPUnit_Extensions_Database_DB_IMetaData
  32145. */
  32146. public function getMetaData()
  32147. {
  32148. return $this->metaData;
  32149. }
  32150. /**
  32151. * Returns the schema for the connection.
  32152. *
  32153. * @return string
  32154. */
  32155. public function getSchema()
  32156. {
  32157. return $this->getMetaData()->getSchema();
  32158. }
  32159. /**
  32160. * Creates a dataset containing the specified table names. If no table
  32161. * names are specified then it will created a dataset over the entire
  32162. * database.
  32163. *
  32164. * @param array $tableNames
  32165. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  32166. * @todo Implement the filtered data set.
  32167. */
  32168. public function createDataSet(array $tableNames = NULL)
  32169. {
  32170. if (empty($tableNames)) {
  32171. return new PHPUnit_Extensions_Database_DB_DataSet($this);
  32172. } else {
  32173. return new PHPUnit_Extensions_Database_DB_FilteredDataSet($this, $tableNames);
  32174. }
  32175. }
  32176. /**
  32177. * Creates a table with the result of the specified SQL statement.
  32178. *
  32179. * @param string $resultName
  32180. * @param string $sql
  32181. * @return PHPUnit_Extensions_Database_DB_Table
  32182. */
  32183. public function createQueryTable($resultName, $sql)
  32184. {
  32185. return new PHPUnit_Extensions_Database_DataSet_QueryTable($resultName, $sql, $this);
  32186. }
  32187. /**
  32188. * Returns this connection database configuration
  32189. *
  32190. * @return PHPUnit_Extensions_Database_Database_DatabaseConfig
  32191. */
  32192. public function getConfig()
  32193. {
  32194. }
  32195. /**
  32196. * Returns a PDO Connection
  32197. *
  32198. * @return PDO
  32199. */
  32200. public function getConnection()
  32201. {
  32202. return $this->connection;
  32203. }
  32204. /**
  32205. * Returns the number of rows in the given table. You can specify an
  32206. * optional where clause to return a subset of the table.
  32207. *
  32208. * @param string $tableName
  32209. * @param string $whereClause
  32210. * @return int
  32211. */
  32212. public function getRowCount($tableName, $whereClause = NULL)
  32213. {
  32214. $query = "SELECT COUNT(*) FROM ".$this->quoteSchemaObject($tableName);
  32215. if (isset($whereClause)) {
  32216. $query .= " WHERE {$whereClause}";
  32217. }
  32218. return (int) $this->connection->query($query)->fetchColumn();
  32219. }
  32220. /**
  32221. * Returns a quoted schema object. (table name, column name, etc)
  32222. *
  32223. * @param string $object
  32224. * @return string
  32225. */
  32226. public function quoteSchemaObject($object)
  32227. {
  32228. return $this->getMetaData()->quoteSchemaObject($object);
  32229. }
  32230. /**
  32231. * Returns the command used to truncate a table.
  32232. *
  32233. * @return string
  32234. */
  32235. public function getTruncateCommand()
  32236. {
  32237. return $this->getMetaData()->getTruncateCommand();
  32238. }
  32239. /**
  32240. * Returns true if the connection allows cascading
  32241. *
  32242. * @return bool
  32243. */
  32244. public function allowsCascading()
  32245. {
  32246. return $this->getMetaData()->allowsCascading();
  32247. }
  32248. /**
  32249. * Disables primary keys if connection does not allow setting them otherwise
  32250. *
  32251. * @param string $tableName
  32252. */
  32253. public function disablePrimaryKeys($tableName)
  32254. {
  32255. $this->getMetaData()->disablePrimaryKeys($tableName);
  32256. }
  32257. /**
  32258. * Reenables primary keys after they have been disabled
  32259. *
  32260. * @param string $tableName
  32261. */
  32262. public function enablePrimaryKeys($tableName)
  32263. {
  32264. $this->getMetaData()->enablePrimaryKeys($tableName);
  32265. }
  32266. }
  32267. <?php
  32268. /*
  32269. * This file is part of DBUnit.
  32270. *
  32271. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32272. *
  32273. * For the full copyright and license information, please view the LICENSE
  32274. * file that was distributed with this source code.
  32275. */
  32276. /**
  32277. * Provides a basic interface for retreiving metadata from a database.
  32278. *
  32279. * @package DbUnit
  32280. * @author Mike Lively <m@digitalsandwich.com>
  32281. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32282. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32283. * @version Release: @package_version@
  32284. * @link http://www.phpunit.de/
  32285. * @since Class available since Release 1.0.0
  32286. */
  32287. interface PHPUnit_Extensions_Database_DB_IMetaData
  32288. {
  32289. /**
  32290. * Returns an array containing the names of all the tables in the database.
  32291. *
  32292. * @return array
  32293. */
  32294. public function getTableNames();
  32295. /**
  32296. * Returns an array containing the names of all the columns in the
  32297. * $tableName table,
  32298. *
  32299. * @param string $tableName
  32300. * @return array
  32301. */
  32302. public function getTableColumns($tableName);
  32303. /**
  32304. * Returns an array containing the names of all the primary key columns in
  32305. * the $tableName table.
  32306. *
  32307. * @param string $tableName
  32308. * @return array
  32309. */
  32310. public function getTablePrimaryKeys($tableName);
  32311. /**
  32312. * Returns the name of the default schema.
  32313. *
  32314. * @return string
  32315. */
  32316. public function getSchema();
  32317. /**
  32318. * Returns a quoted schema object. (table name, column name, etc)
  32319. *
  32320. * @param string $object
  32321. * @return string
  32322. */
  32323. public function quoteSchemaObject($object);
  32324. /**
  32325. * Returns true if the rdbms allows cascading
  32326. *
  32327. * @return bool
  32328. */
  32329. public function allowsCascading();
  32330. /**
  32331. * Disables primary keys if rdbms does not allow setting them otherwise
  32332. *
  32333. * @param string $tableName
  32334. */
  32335. public function disablePrimaryKeys($tableName);
  32336. /**
  32337. * Reenables primary keys after they have been disabled
  32338. *
  32339. * @param string $tableName
  32340. */
  32341. public function enablePrimaryKeys($tableName);
  32342. }
  32343. <?php
  32344. /*
  32345. * This file is part of DBUnit.
  32346. *
  32347. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32348. *
  32349. * For the full copyright and license information, please view the LICENSE
  32350. * file that was distributed with this source code.
  32351. */
  32352. /**
  32353. * Provides iterative access to tables from a database instance.
  32354. *
  32355. * @package DbUnit
  32356. * @author Mike Lively <m@digitalsandwich.com>
  32357. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32358. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32359. * @version Release: @package_version@
  32360. * @link http://www.phpunit.de/
  32361. * @since Class available since Release 1.0.0
  32362. */
  32363. class PHPUnit_Extensions_Database_DB_TableIterator implements PHPUnit_Extensions_Database_DataSet_ITableIterator
  32364. {
  32365. /**
  32366. * An array of tablenames.
  32367. *
  32368. * @var Array
  32369. */
  32370. protected $tableNames;
  32371. /**
  32372. * If this property is true then the tables will be iterated in reverse
  32373. * order.
  32374. *
  32375. * @var bool
  32376. */
  32377. protected $reverse;
  32378. /**
  32379. * The database dataset that this iterator iterates over.
  32380. *
  32381. * @var PHPUnit_Extensions_Database_DB_DataSet
  32382. */
  32383. protected $dataSet;
  32384. public function __construct($tableNames, PHPUnit_Extensions_Database_DB_DataSet $dataSet, $reverse = FALSE)
  32385. {
  32386. $this->tableNames = $tableNames;
  32387. $this->dataSet = $dataSet;
  32388. $this->reverse = $reverse;
  32389. $this->rewind();
  32390. }
  32391. /**
  32392. * Returns the current table.
  32393. *
  32394. * @return PHPUnit_Extensions_Database_DataSet_ITable
  32395. */
  32396. public function getTable()
  32397. {
  32398. return $this->current();
  32399. }
  32400. /**
  32401. * Returns the current table's meta data.
  32402. *
  32403. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  32404. */
  32405. public function getTableMetaData()
  32406. {
  32407. return $this->current()->getTableMetaData();
  32408. }
  32409. /**
  32410. * Returns the current table.
  32411. *
  32412. * @return PHPUnit_Extensions_Database_DataSet_ITable
  32413. */
  32414. public function current()
  32415. {
  32416. $tableName = current($this->tableNames);
  32417. return $this->dataSet->getTable($tableName);
  32418. }
  32419. /**
  32420. * Returns the name of the current table.
  32421. *
  32422. * @return string
  32423. */
  32424. public function key()
  32425. {
  32426. return $this->current()->getTableMetaData()->getTableName();
  32427. }
  32428. /**
  32429. * advances to the next element.
  32430. *
  32431. */
  32432. public function next()
  32433. {
  32434. if ($this->reverse) {
  32435. prev($this->tableNames);
  32436. } else {
  32437. next($this->tableNames);
  32438. }
  32439. }
  32440. /**
  32441. * Rewinds to the first element
  32442. */
  32443. public function rewind()
  32444. {
  32445. if ($this->reverse) {
  32446. end($this->tableNames);
  32447. } else {
  32448. reset($this->tableNames);
  32449. }
  32450. }
  32451. /**
  32452. * Returns true if the current index is valid
  32453. *
  32454. * @return bool
  32455. */
  32456. public function valid()
  32457. {
  32458. return (current($this->tableNames) !== FALSE);
  32459. }
  32460. }
  32461. <?php
  32462. /*
  32463. * This file is part of DBUnit.
  32464. *
  32465. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32466. *
  32467. * For the full copyright and license information, please view the LICENSE
  32468. * file that was distributed with this source code.
  32469. */
  32470. /**
  32471. * Provides access to a database instance as a data set.
  32472. *
  32473. * @package DbUnit
  32474. * @author Mike Lively <m@digitalsandwich.com>
  32475. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32476. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32477. * @version Release: @package_version@
  32478. * @link http://www.phpunit.de/
  32479. * @since Class available since Release 1.0.0
  32480. */
  32481. class PHPUnit_Extensions_Database_DB_DataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  32482. {
  32483. /**
  32484. * An array of ITable objects.
  32485. *
  32486. * @var array
  32487. */
  32488. protected $tables = array();
  32489. /**
  32490. * The database connection this dataset is using.
  32491. *
  32492. * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection
  32493. */
  32494. protected $databaseConnection;
  32495. /**
  32496. * Creates a new dataset using the given database connection.
  32497. *
  32498. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection
  32499. */
  32500. public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection)
  32501. {
  32502. $this->databaseConnection = $databaseConnection;
  32503. }
  32504. /**
  32505. * Creates the query necessary to pull all of the data from a table.
  32506. *
  32507. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData
  32508. * @return unknown
  32509. */
  32510. public static function buildTableSelect(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection = NULL)
  32511. {
  32512. if ($tableMetaData->getTableName() == '') {
  32513. $e = new Exception("Empty Table Name");
  32514. echo $e->getTraceAsString();
  32515. throw $e;
  32516. }
  32517. $columns = $tableMetaData->getColumns();
  32518. if ($databaseConnection) {
  32519. $columns = array_map(array($databaseConnection, 'quoteSchemaObject'), $columns);
  32520. }
  32521. $columnList = implode(', ', $columns);
  32522. if ($databaseConnection) {
  32523. $tableName = $databaseConnection->quoteSchemaObject($tableMetaData->getTableName());
  32524. } else {
  32525. $tableName = $tableMetaData->getTableName();
  32526. }
  32527. $primaryKeys = $tableMetaData->getPrimaryKeys();
  32528. if ($databaseConnection) {
  32529. $primaryKeys = array_map(array($databaseConnection, 'quoteSchemaObject'), $primaryKeys);
  32530. }
  32531. if (count($primaryKeys)) {
  32532. $orderBy = 'ORDER BY ' . implode(' ASC, ', $primaryKeys) . ' ASC';
  32533. } else {
  32534. $orderBy = '';
  32535. }
  32536. return "SELECT {$columnList} FROM {$tableName} {$orderBy}";
  32537. }
  32538. /**
  32539. * Creates an iterator over the tables in the data set. If $reverse is
  32540. * true a reverse iterator will be returned.
  32541. *
  32542. * @param bool $reverse
  32543. * @return PHPUnit_Extensions_Database_DB_TableIterator
  32544. */
  32545. protected function createIterator($reverse = FALSE)
  32546. {
  32547. return new PHPUnit_Extensions_Database_DB_TableIterator($this->getTableNames(), $this, $reverse);
  32548. }
  32549. /**
  32550. * Returns a table object for the given table.
  32551. *
  32552. * @param string $tableName
  32553. * @return PHPUnit_Extensions_Database_DB_Table
  32554. */
  32555. public function getTable($tableName)
  32556. {
  32557. if (!in_array($tableName, $this->getTableNames())) {
  32558. throw new InvalidArgumentException("$tableName is not a table in the current database.");
  32559. }
  32560. if (empty($this->tables[$tableName])) {
  32561. $this->tables[$tableName] = new PHPUnit_Extensions_Database_DB_Table($this->getTableMetaData($tableName), $this->databaseConnection);
  32562. }
  32563. return $this->tables[$tableName];
  32564. }
  32565. /**
  32566. * Returns a table meta data object for the given table.
  32567. *
  32568. * @param string $tableName
  32569. * @return PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData
  32570. */
  32571. public function getTableMetaData($tableName)
  32572. {
  32573. return new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $this->databaseConnection->getMetaData()->getTableColumns($tableName), $this->databaseConnection->getMetaData()->getTablePrimaryKeys($tableName));
  32574. }
  32575. /**
  32576. * Returns a list of table names for the database
  32577. *
  32578. * @return Array
  32579. */
  32580. public function getTableNames()
  32581. {
  32582. return $this->databaseConnection->getMetaData()->getTableNames();
  32583. }
  32584. }
  32585. <?php
  32586. /*
  32587. * This file is part of DBUnit.
  32588. *
  32589. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32590. *
  32591. * For the full copyright and license information, please view the LICENSE
  32592. * file that was distributed with this source code.
  32593. */
  32594. /**
  32595. * Provides the functionality to represent a database result set as a DBUnit
  32596. * table.
  32597. *
  32598. * @package DbUnit
  32599. * @author Mike Lively <m@digitalsandwich.com>
  32600. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32601. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32602. * @version Release: @package_version@
  32603. * @link http://www.phpunit.de/
  32604. * @deprecated The PHPUnit_Extension_Database_DataSet_QueryTable should be used instead
  32605. * @see PHPUnit_Extension_Database_DataSet_QueryTable
  32606. * @see PHPUnit_Extension_Database_DataSet_QueryDataSet
  32607. * @since Class available since Release 1.0.0
  32608. */
  32609. class PHPUnit_Extensions_Database_DB_ResultSetTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable
  32610. {
  32611. /**
  32612. * Creates a new result set table.
  32613. *
  32614. * @param string $tableName
  32615. * @param PDOStatement $pdoStatement
  32616. */
  32617. public function __construct($tableName, PDOStatement $pdoStatement)
  32618. {
  32619. $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC);
  32620. if (count($this->data)) {
  32621. $columns = array_keys($this->data[0]);
  32622. } else {
  32623. $columns = array();
  32624. }
  32625. $this->setTableMetaData(new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns));
  32626. }
  32627. }
  32628. <?php
  32629. /*
  32630. * This file is part of DBUnit.
  32631. *
  32632. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32633. *
  32634. * For the full copyright and license information, please view the LICENSE
  32635. * file that was distributed with this source code.
  32636. */
  32637. /**
  32638. * This is the default implementation of the database tester. It receives its
  32639. * connection object from the constructor.
  32640. *
  32641. * @package DbUnit
  32642. * @author Mike Lively <m@digitalsandwich.com>
  32643. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32644. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32645. * @version Release: @package_version@
  32646. * @link http://www.phpunit.de/
  32647. * @since Class available since Release 1.0.0
  32648. */
  32649. class PHPUnit_Extensions_Database_DefaultTester extends PHPUnit_Extensions_Database_AbstractTester
  32650. {
  32651. /**
  32652. * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection
  32653. */
  32654. protected $connection;
  32655. /**
  32656. * Creates a new default database tester using the given connection.
  32657. *
  32658. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  32659. */
  32660. public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  32661. {
  32662. parent::__construct();
  32663. $this->connection = $connection;
  32664. }
  32665. /**
  32666. * Returns the test database connection.
  32667. *
  32668. * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
  32669. */
  32670. public function getConnection()
  32671. {
  32672. return $this->connection;
  32673. }
  32674. }
  32675. <?php
  32676. /*
  32677. * This file is part of DBUnit.
  32678. *
  32679. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32680. *
  32681. * For the full copyright and license information, please view the LICENSE
  32682. * file that was distributed with this source code.
  32683. */
  32684. /**
  32685. * Asserts whether or not two dbunit tables are equal.
  32686. *
  32687. * @package DbUnit
  32688. * @author Mike Lively <m@digitalsandwich.com>
  32689. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32690. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32691. * @version Release: @package_version@
  32692. * @link http://www.phpunit.de/
  32693. * @since Class available since Release 1.0.0
  32694. */
  32695. class PHPUnit_Extensions_Database_Constraint_TableIsEqual extends PHPUnit_Framework_Constraint
  32696. {
  32697. /**
  32698. * @var PHPUnit_Extensions_Database_DataSet_ITable
  32699. */
  32700. protected $value;
  32701. /**
  32702. * @var string
  32703. */
  32704. protected $failure_reason;
  32705. /**
  32706. * Creates a new constraint.
  32707. *
  32708. * @param PHPUnit_Extensions_Database_DataSet_ITable $value
  32709. */
  32710. public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $value)
  32711. {
  32712. parent::__construct();
  32713. $this->value = $value;
  32714. }
  32715. /**
  32716. * Evaluates the constraint for parameter $other. Returns TRUE if the
  32717. * constraint is met, FALSE otherwise.
  32718. *
  32719. * This method can be overridden to implement the evaluation algorithm.
  32720. *
  32721. * @param mixed $other Value or object to evaluate.
  32722. * @return bool
  32723. */
  32724. protected function matches($other)
  32725. {
  32726. if (!$other instanceof PHPUnit_Extensions_Database_DataSet_ITable) {
  32727. throw new InvalidArgumentException(
  32728. 'PHPUnit_Extensions_Database_DataSet_ITable expected'
  32729. );
  32730. }
  32731. return $this->value->matches($other);
  32732. }
  32733. /**
  32734. * Returns the description of the failure
  32735. *
  32736. * The beginning of failure messages is "Failed asserting that" in most
  32737. * cases. This method should return the second part of that sentence.
  32738. *
  32739. * @param mixed $other Evaluated value or object.
  32740. * @return string
  32741. */
  32742. protected function failureDescription($other)
  32743. {
  32744. return $other->__toString() . ' ' . $this->toString();
  32745. }
  32746. /**
  32747. * Returns a string representation of the constraint.
  32748. *
  32749. * @return string
  32750. */
  32751. public function toString()
  32752. {
  32753. return sprintf(
  32754. 'is equal to expected %s', $this->value->__toString()
  32755. );
  32756. }
  32757. }
  32758. <?php
  32759. /*
  32760. * This file is part of DBUnit.
  32761. *
  32762. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32763. *
  32764. * For the full copyright and license information, please view the LICENSE
  32765. * file that was distributed with this source code.
  32766. */
  32767. /**
  32768. * Asserts whether or not two dbunit datasets are equal.
  32769. *
  32770. * @package DbUnit
  32771. * @author Mike Lively <m@digitalsandwich.com>
  32772. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32773. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32774. * @version Release: @package_version@
  32775. * @link http://www.phpunit.de/
  32776. * @since Class available since Release 1.0.0
  32777. */
  32778. class PHPUnit_Extensions_Database_Constraint_DataSetIsEqual extends PHPUnit_Framework_Constraint
  32779. {
  32780. /**
  32781. * @var PHPUnit_Extensions_Database_DataSet_IDataSet
  32782. */
  32783. protected $value;
  32784. /**
  32785. * @var string
  32786. */
  32787. protected $failure_reason;
  32788. /**
  32789. * Creates a new constraint.
  32790. *
  32791. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $value
  32792. */
  32793. public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $value)
  32794. {
  32795. parent::__construct();
  32796. $this->value = $value;
  32797. }
  32798. /**
  32799. * Evaluates the constraint for parameter $other. Returns TRUE if the
  32800. * constraint is met, FALSE otherwise.
  32801. *
  32802. * This method can be overridden to implement the evaluation algorithm.
  32803. *
  32804. * @param mixed $other Value or object to evaluate.
  32805. * @return bool
  32806. */
  32807. protected function matches($other)
  32808. {
  32809. if (!$other instanceof PHPUnit_Extensions_Database_DataSet_IDataSet) {
  32810. throw new InvalidArgumentException(
  32811. 'PHPUnit_Extensions_Database_DataSet_IDataSet expected'
  32812. );
  32813. }
  32814. return $this->value->matches($other);
  32815. }
  32816. /**
  32817. * Returns the description of the failure
  32818. *
  32819. * The beginning of failure messages is "Failed asserting that" in most
  32820. * cases. This method should return the second part of that sentence.
  32821. *
  32822. * @param mixed $other Evaluated value or object.
  32823. * @return string
  32824. */
  32825. protected function failureDescription($other)
  32826. {
  32827. return $other->__toString() . ' ' . $this->toString();
  32828. }
  32829. /**
  32830. * Returns a string representation of the constraint.
  32831. *
  32832. * @return string
  32833. */
  32834. public function toString()
  32835. {
  32836. return sprintf(
  32837. 'is equal to expected %s', $this->value->__toString()
  32838. );
  32839. }
  32840. }
  32841. <?php
  32842. /*
  32843. * This file is part of DBUnit.
  32844. *
  32845. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32846. *
  32847. * For the full copyright and license information, please view the LICENSE
  32848. * file that was distributed with this source code.
  32849. */
  32850. /**
  32851. * Asserts the row count in a table
  32852. *
  32853. * @package DbUnit
  32854. * @author Mike Lively <m@digitalsandwich.com>
  32855. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32856. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32857. * @version Release: @package_version@
  32858. * @link http://www.phpunit.de/
  32859. * @since Class available since Release 1.0.0
  32860. */
  32861. class PHPUnit_Extensions_Database_Constraint_TableRowCount extends PHPUnit_Framework_Constraint
  32862. {
  32863. /**
  32864. * @var int
  32865. */
  32866. protected $value;
  32867. /**
  32868. * @var string
  32869. */
  32870. protected $tableName;
  32871. /**
  32872. * Creates a new constraint.
  32873. *
  32874. * @param $tableName
  32875. * @param $value
  32876. */
  32877. public function __construct($tableName, $value)
  32878. {
  32879. parent::__construct();
  32880. $this->tableName = $tableName;
  32881. $this->value = $value;
  32882. }
  32883. /**
  32884. * Evaluates the constraint for parameter $other. Returns TRUE if the
  32885. * constraint is met, FALSE otherwise.
  32886. *
  32887. * This method can be overridden to implement the evaluation algorithm.
  32888. *
  32889. * @param mixed $other Value or object to evaluate.
  32890. * @return bool
  32891. */
  32892. protected function matches($other)
  32893. {
  32894. return $other == $this->value;
  32895. }
  32896. /**
  32897. * Returns a string representation of the constraint.
  32898. *
  32899. * @return string
  32900. */
  32901. public function toString()
  32902. {
  32903. return sprintf('is equal to expected row count %d', $this->value);
  32904. }
  32905. }
  32906. <?php
  32907. /*
  32908. * This file is part of DBUnit.
  32909. *
  32910. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32911. *
  32912. * For the full copyright and license information, please view the LICENSE
  32913. * file that was distributed with this source code.
  32914. */
  32915. /**
  32916. * This is the interface for DatabaseTester objects. These objects are used to
  32917. * add database testing to existing test cases using composition instead of
  32918. * extension.
  32919. *
  32920. * @package DbUnit
  32921. * @author Mike Lively <m@digitalsandwich.com>
  32922. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32923. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32924. * @version Release: @package_version@
  32925. * @link http://www.phpunit.de/
  32926. * @since Class available since Release 1.0.0
  32927. */
  32928. interface PHPUnit_Extensions_Database_ITester
  32929. {
  32930. /**
  32931. * Closes the specified connection.
  32932. *
  32933. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  32934. */
  32935. public function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection);
  32936. /**
  32937. * Returns the test database connection.
  32938. *
  32939. * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
  32940. */
  32941. public function getConnection();
  32942. /**
  32943. * Returns the test dataset.
  32944. *
  32945. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  32946. */
  32947. public function getDataSet();
  32948. /**
  32949. * TestCases must call this method inside setUp().
  32950. */
  32951. public function onSetUp();
  32952. /**
  32953. * TestCases must call this method inside tearDown().
  32954. */
  32955. public function onTearDown();
  32956. /**
  32957. * Sets the test dataset to use.
  32958. *
  32959. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  32960. */
  32961. public function setDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet);
  32962. /**
  32963. * Sets the schema value.
  32964. *
  32965. * @param string $schema
  32966. */
  32967. public function setSchema($schema);
  32968. /**
  32969. * Sets the DatabaseOperation to call when starting the test.
  32970. *
  32971. * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $setUpOperation
  32972. */
  32973. public function setSetUpOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $setUpOperation);
  32974. /**
  32975. * Sets the DatabaseOperation to call when stopping the test.
  32976. *
  32977. * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $tearDownOperation
  32978. */
  32979. public function setTearDownOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $tearDownOperation);
  32980. }
  32981. <?php
  32982. /*
  32983. * This file is part of DBUnit.
  32984. *
  32985. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32986. *
  32987. * For the full copyright and license information, please view the LICENSE
  32988. * file that was distributed with this source code.
  32989. */
  32990. /**
  32991. * Data set implementation for the output of mysqldump --xml.
  32992. *
  32993. * @package DbUnit
  32994. * @author Matthew Turland <tobias382@gmail.com>
  32995. * @copyright 2010-2014 Matthew Turland <tobias382@gmail.com>
  32996. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32997. * @version Release: @package_version@
  32998. * @link http://www.phpunit.de/
  32999. * @since Class available since Release 1.0.0
  33000. */
  33001. class PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet
  33002. {
  33003. protected function getTableInfo(array &$tableColumns, array &$tableValues)
  33004. {
  33005. if ($this->xmlFileContents->getName() != 'mysqldump') {
  33006. throw new PHPUnit_Extensions_Database_Exception('The root element of a MySQL XML data set file must be called <mysqldump>');
  33007. }
  33008. foreach ($this->xmlFileContents->xpath('./database/table_data') as $tableElement) {
  33009. if (empty($tableElement['name'])) {
  33010. throw new PHPUnit_Extensions_Database_Exception('<table_data> elements must include a name attribute');
  33011. }
  33012. $tableName = (string)$tableElement['name'];
  33013. if (!isset($tableColumns[$tableName])) {
  33014. $tableColumns[$tableName] = array();
  33015. }
  33016. if (!isset($tableValues[$tableName])) {
  33017. $tableValues[$tableName] = array();
  33018. }
  33019. foreach ($tableElement->xpath('./row') as $rowElement) {
  33020. $rowValues = array();
  33021. foreach ($rowElement->xpath('./field') as $columnElement) {
  33022. if (empty($columnElement['name'])) {
  33023. throw new PHPUnit_Extensions_Database_Exception('<field> element name attributes cannot be empty');
  33024. }
  33025. $columnName = (string)$columnElement['name'];
  33026. if (!in_array($columnName, $tableColumns[$tableName])) {
  33027. $tableColumns[$tableName][] = $columnName;
  33028. }
  33029. }
  33030. foreach ($tableColumns[$tableName] as $columnName) {
  33031. $fields = $rowElement->xpath('./field[@name="' . $columnName . '"]');
  33032. $column = $fields[0];
  33033. $attr = $column->attributes('http://www.w3.org/2001/XMLSchema-instance');
  33034. if (isset($attr['type']) && (string) $attr['type'] === 'xs:hexBinary') {
  33035. $columnValue = pack('H*',(string)$column);
  33036. } else {
  33037. $null = isset($column['nil']) || isset($attr[0]);
  33038. $columnValue = $null ? NULL : (string)$column;
  33039. }
  33040. $rowValues[$columnName] = $columnValue;
  33041. }
  33042. $tableValues[$tableName][] = $rowValues;
  33043. }
  33044. }
  33045. foreach ($this->xmlFileContents->xpath('./database/table_structure') as $tableElement) {
  33046. if (empty($tableElement['name'])) {
  33047. throw new PHPUnit_Extensions_Database_Exception('<table_structure> elements must include a name attribute');
  33048. }
  33049. $tableName = (string) $tableElement['name'];
  33050. foreach ($tableElement->xpath('./field') as $fieldElement) {
  33051. if (empty($fieldElement['Field'])) {
  33052. throw new PHPUnit_Extensions_Database_Exception('<field> elements must include a Field attribute');
  33053. }
  33054. $columnName = (string) $fieldElement['Field'];
  33055. if (!in_array($columnName, $tableColumns[$tableName])) {
  33056. $tableColumns[$tableName][] = $columnName;
  33057. }
  33058. }
  33059. }
  33060. }
  33061. public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename)
  33062. {
  33063. $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml;
  33064. $pers->setFileName($filename);
  33065. try {
  33066. $pers->write($dataset);
  33067. }
  33068. catch (RuntimeException $e) {
  33069. throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.');
  33070. }
  33071. }
  33072. }
  33073. <?php
  33074. /*
  33075. * This file is part of DBUnit.
  33076. *
  33077. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33078. *
  33079. * For the full copyright and license information, please view the LICENSE
  33080. * file that was distributed with this source code.
  33081. */
  33082. /**
  33083. * Provides access to a database instance as a data set.
  33084. *
  33085. * @package DbUnit
  33086. * @author Mike Lively <m@digitalsandwich.com>
  33087. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33088. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33089. * @version Release: @package_version@
  33090. * @link http://www.phpunit.de/
  33091. * @since Class available since Release 1.0.0
  33092. */
  33093. class PHPUnit_Extensions_Database_DataSet_QueryDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  33094. {
  33095. /**
  33096. * An array of ITable objects.
  33097. *
  33098. * @var array
  33099. */
  33100. protected $tables = array();
  33101. /**
  33102. * The database connection this dataset is using.
  33103. *
  33104. * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection
  33105. */
  33106. protected $databaseConnection;
  33107. /**
  33108. * Creates a new dataset using the given database connection.
  33109. *
  33110. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection
  33111. */
  33112. public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection)
  33113. {
  33114. $this->databaseConnection = $databaseConnection;
  33115. }
  33116. public function addTable($tableName, $query = NULL)
  33117. {
  33118. if ($query === NULL) {
  33119. $query = 'SELECT * FROM ' . $tableName;
  33120. }
  33121. $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_QueryTable($tableName, $query, $this->databaseConnection);
  33122. }
  33123. /**
  33124. * Creates an iterator over the tables in the data set. If $reverse is
  33125. * true a reverse iterator will be returned.
  33126. *
  33127. * @param bool $reverse
  33128. * @return PHPUnit_Extensions_Database_DB_TableIterator
  33129. */
  33130. protected function createIterator($reverse = FALSE)
  33131. {
  33132. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
  33133. }
  33134. /**
  33135. * Returns a table object for the given table.
  33136. *
  33137. * @param string $tableName
  33138. * @return PHPUnit_Extensions_Database_DB_Table
  33139. */
  33140. public function getTable($tableName)
  33141. {
  33142. if (!isset($this->tables[$tableName])) {
  33143. throw new InvalidArgumentException("$tableName is not a table in the current database.");
  33144. }
  33145. return $this->tables[$tableName];
  33146. }
  33147. /**
  33148. * Returns a list of table names for the database
  33149. *
  33150. * @return Array
  33151. */
  33152. public function getTableNames()
  33153. {
  33154. return array_keys($this->tables);
  33155. }
  33156. }
  33157. <?php
  33158. /*
  33159. * This file is part of DBUnit.
  33160. *
  33161. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33162. *
  33163. * For the full copyright and license information, please view the LICENSE
  33164. * file that was distributed with this source code.
  33165. */
  33166. /**
  33167. * Creates YamlDataSets.
  33168. *
  33169. * You can incrementally add YAML files as tables to your datasets
  33170. *
  33171. * @package DbUnit
  33172. * @author Mike Lively <m@digitalsandwich.com>
  33173. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33174. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33175. * @version Release: @package_version@
  33176. * @link http://www.phpunit.de/
  33177. * @since Class available since Release 1.0.0
  33178. */
  33179. class PHPUnit_Extensions_Database_DataSet_YamlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  33180. {
  33181. /**
  33182. * @var array
  33183. */
  33184. protected $tables = array();
  33185. /**
  33186. * @var PHPUnit_Extensions_Database_DataSet_IYamlParser
  33187. */
  33188. protected $parser;
  33189. /**
  33190. * Creates a new YAML dataset
  33191. *
  33192. * @param string $yamlFile
  33193. * @param PHPUnit_Extensions_Database_DataSet_IYamlParser $parser
  33194. */
  33195. public function __construct($yamlFile, $parser = NULL)
  33196. {
  33197. if ($parser == NULL) {
  33198. $parser = new PHPUnit_Extensions_Database_DataSet_SymfonyYamlParser();
  33199. }
  33200. $this->parser = $parser;
  33201. $this->addYamlFile($yamlFile);
  33202. }
  33203. /**
  33204. * Adds a new yaml file to the dataset.
  33205. * @param string $yamlFile
  33206. */
  33207. public function addYamlFile($yamlFile)
  33208. {
  33209. $data = $this->parser->parseYaml($yamlFile);
  33210. foreach ($data as $tableName => $rows) {
  33211. if (!isset($rows)) {
  33212. $rows = array();
  33213. }
  33214. if (!is_array($rows)) {
  33215. continue;
  33216. }
  33217. if (!array_key_exists($tableName, $this->tables)) {
  33218. $columns = $this->getColumns($rows);
  33219. $tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData(
  33220. $tableName, $columns
  33221. );
  33222. $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_DefaultTable(
  33223. $tableMetaData
  33224. );
  33225. }
  33226. foreach ($rows as $row) {
  33227. $this->tables[$tableName]->addRow($row);
  33228. }
  33229. }
  33230. }
  33231. /**
  33232. * Creates a unique list of columns from all the rows in a table.
  33233. * If the table is defined another time in the Yaml, and if the Yaml
  33234. * parser could return the multiple occerrences, then this would be
  33235. * insufficient unless we grouped all the occurences of the table
  33236. * into onwe row set. sfYaml, however, does not provide multiple tables
  33237. * with the same name, it only supplies the last table.
  33238. *
  33239. * @params all the rows in a table.
  33240. */
  33241. private function getColumns($rows) {
  33242. $columns = array();
  33243. foreach ($rows as $row) {
  33244. $columns = array_merge($columns, array_keys($row));
  33245. }
  33246. return array_values(array_unique($columns));
  33247. }
  33248. /**
  33249. * Creates an iterator over the tables in the data set. If $reverse is
  33250. * true a reverse iterator will be returned.
  33251. *
  33252. * @param bool $reverse
  33253. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33254. */
  33255. protected function createIterator($reverse = FALSE)
  33256. {
  33257. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator(
  33258. $this->tables, $reverse
  33259. );
  33260. }
  33261. /**
  33262. * Saves a given $dataset to $filename in YAML format
  33263. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  33264. * @param string $filename
  33265. */
  33266. public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename)
  33267. {
  33268. $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_Yaml();
  33269. $pers->setFileName($filename);
  33270. try {
  33271. $pers->write($dataset);
  33272. }
  33273. catch (RuntimeException $e) {
  33274. throw new PHPUnit_Framework_Exception(
  33275. __METHOD__ . ' called with an unwritable file.'
  33276. );
  33277. }
  33278. }
  33279. }
  33280. <?php
  33281. /*
  33282. * This file is part of DBUnit.
  33283. *
  33284. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33285. *
  33286. * For the full copyright and license information, please view the LICENSE
  33287. * file that was distributed with this source code.
  33288. */
  33289. /**
  33290. * Implements the basic functionality of data sets.
  33291. *
  33292. * @package DbUnit
  33293. * @author Mike Lively <m@digitalsandwich.com>
  33294. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33295. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33296. * @version Release: @package_version@
  33297. * @link http://www.phpunit.de/
  33298. * @since Class available since Release 1.0.0
  33299. */
  33300. abstract class PHPUnit_Extensions_Database_DataSet_AbstractDataSet implements PHPUnit_Extensions_Database_DataSet_IDataSet
  33301. {
  33302. /**
  33303. * Creates an iterator over the tables in the data set. If $reverse is
  33304. * true a reverse iterator will be returned.
  33305. *
  33306. * @param bool $reverse
  33307. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33308. */
  33309. protected abstract function createIterator($reverse = FALSE);
  33310. /**
  33311. * Returns an array of table names contained in the dataset.
  33312. *
  33313. * @return array
  33314. */
  33315. public function getTableNames()
  33316. {
  33317. $tableNames = array();
  33318. foreach ($this->getIterator() as $table) {
  33319. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  33320. $tableNames[] = $table->getTableMetaData()->getTableName();
  33321. }
  33322. return $tableNames;
  33323. }
  33324. /**
  33325. * Returns a table meta data object for the given table.
  33326. *
  33327. * @param string $tableName
  33328. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  33329. */
  33330. public function getTableMetaData($tableName)
  33331. {
  33332. return $this->getTable($tableName)->getTableMetaData();
  33333. }
  33334. /**
  33335. * Returns a table object for the given table.
  33336. *
  33337. * @param string $tableName
  33338. * @return PHPUnit_Extensions_Database_DataSet_ITable
  33339. */
  33340. public function getTable($tableName)
  33341. {
  33342. foreach ($this->getIterator() as $table) {
  33343. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  33344. if ($table->getTableMetaData()->getTableName() == $tableName) {
  33345. return $table;
  33346. }
  33347. }
  33348. }
  33349. /**
  33350. * Returns an iterator for all table objects in the given dataset.
  33351. *
  33352. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33353. */
  33354. public function getIterator()
  33355. {
  33356. return $this->createIterator();
  33357. }
  33358. /**
  33359. * Returns a reverse iterator for all table objects in the given dataset.
  33360. *
  33361. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33362. */
  33363. public function getReverseIterator()
  33364. {
  33365. return $this->createIterator(TRUE);
  33366. }
  33367. /**
  33368. * Asserts that the given data set matches this data set.
  33369. *
  33370. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $other
  33371. */
  33372. public function matches(PHPUnit_Extensions_Database_DataSet_IDataSet $other)
  33373. {
  33374. $thisTableNames = $this->getTableNames();
  33375. $otherTableNames = $other->getTableNames();
  33376. sort($thisTableNames);
  33377. sort($otherTableNames);
  33378. if ($thisTableNames != $otherTableNames) {
  33379. return FALSE;
  33380. }
  33381. foreach ($thisTableNames as $tableName) {
  33382. $table = $this->getTable($tableName);
  33383. if (!$table->matches($other->getTable($tableName))) {
  33384. return FALSE;
  33385. }
  33386. }
  33387. return TRUE;
  33388. }
  33389. public function __toString()
  33390. {
  33391. $iterator = $this->getIterator();
  33392. $dataSetString = '';
  33393. foreach ($iterator as $table) {
  33394. $dataSetString .= $table->__toString();
  33395. }
  33396. return $dataSetString;
  33397. }
  33398. }
  33399. <?php
  33400. /*
  33401. * This file is part of DBUnit.
  33402. *
  33403. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33404. *
  33405. * For the full copyright and license information, please view the LICENSE
  33406. * file that was distributed with this source code.
  33407. */
  33408. /**
  33409. * Provides an interface for creating data sets from data set spec strings.
  33410. *
  33411. * @package DbUnit
  33412. * @author Mike Lively <m@digitalsandwich.com>
  33413. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33414. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33415. * @version Release: @package_version@
  33416. * @link http://www.phpunit.de//**
  33417. * @since Class available since Release 1.0.0
  33418. */
  33419. interface PHPUnit_Extensions_Database_DataSet_ISpec
  33420. {
  33421. /**
  33422. * Creates a data set from a data set spec string.
  33423. *
  33424. * @param string $dataSetSpec
  33425. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  33426. */
  33427. public function getDataSet($dataSetSpec);
  33428. }
  33429. <?php
  33430. /*
  33431. * This file is part of DBUnit.
  33432. *
  33433. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33434. *
  33435. * For the full copyright and license information, please view the LICENSE
  33436. * file that was distributed with this source code.
  33437. */
  33438. /**
  33439. * A table decorator that allows filtering out table columns from results.
  33440. *
  33441. * @package DbUnit
  33442. * @author Mike Lively <m@digitalsandwich.com>
  33443. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33444. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33445. * @version Release: @package_version@
  33446. * @link http://www.phpunit.de/
  33447. * @since Class available since Release 1.0.0
  33448. */
  33449. class PHPUnit_Extensions_Database_DataSet_TableFilter extends PHPUnit_Extensions_Database_DataSet_AbstractTable
  33450. {
  33451. /**
  33452. * The table meta data being decorated.
  33453. * @var PHPUnit_Extensions_Database_DataSet_ITable
  33454. */
  33455. protected $originalTable;
  33456. /**
  33457. * Creates a new table filter using the original table
  33458. *
  33459. * @param $originalTable PHPUnit_Extensions_Database_DataSet_ITable
  33460. * @param $excludeColumns Array @deprecated, use the set* methods instead.
  33461. */
  33462. public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $originalTable, Array $excludeColumns = array())
  33463. {
  33464. $this->originalTable = $originalTable;
  33465. $this->setTableMetaData(new PHPUnit_Extensions_Database_DataSet_TableMetaDataFilter($originalTable->getTableMetaData()));
  33466. $this->addExcludeColumns($excludeColumns);
  33467. }
  33468. /**
  33469. * Returns the number of rows in this table.
  33470. *
  33471. * @return int
  33472. */
  33473. public function getRowCount()
  33474. {
  33475. return $this->originalTable->getRowCount();
  33476. }
  33477. /**
  33478. * Returns the value for the given column on the given row.
  33479. *
  33480. * @param int $row
  33481. * @param int $column
  33482. */
  33483. public function getValue($row, $column)
  33484. {
  33485. if (in_array($column, $this->getTableMetaData()->getColumns())) {
  33486. return $this->originalTable->getValue($row, $column);
  33487. } else {
  33488. throw new InvalidArgumentException("The given row ({$row}) and column ({$column}) do not exist in table {$this->getTableMetaData()->getTableName()}");
  33489. }
  33490. }
  33491. /**
  33492. * Sets the columns to include in the table.
  33493. * @param Array $includeColumns
  33494. */
  33495. public function addIncludeColumns(Array $includeColumns)
  33496. {
  33497. $this->tableMetaData->addIncludeColumns($includeColumns);
  33498. }
  33499. /**
  33500. * Clears the included columns.
  33501. */
  33502. public function clearIncludeColumns()
  33503. {
  33504. $this->tableMetaData->clearIncludeColumns();
  33505. }
  33506. /**
  33507. * Sets the columns to exclude from the table.
  33508. * @param Array $excludeColumns
  33509. */
  33510. public function addExcludeColumns(Array $excludeColumns)
  33511. {
  33512. $this->tableMetaData->addExcludeColumns($excludeColumns);
  33513. }
  33514. /**
  33515. * Clears the included columns.
  33516. */
  33517. public function clearExcludeColumns()
  33518. {
  33519. $this->tableMetaData->clearExcludeColumns();
  33520. }
  33521. /**
  33522. * Checks if a given row is in the table
  33523. *
  33524. * @param array $row
  33525. *
  33526. * @return bool
  33527. */
  33528. public function assertContainsRow(Array $row)
  33529. {
  33530. $this->loadData();
  33531. return parent::assertContainsRow($row);
  33532. }
  33533. /**
  33534. * Loads data into local data table if it's not already loaded
  33535. */
  33536. protected function loadData()
  33537. {
  33538. if ($this->data === NULL) {
  33539. $data = array();
  33540. for($row = 0;$row < $this->originalTable->getRowCount();$row++) {
  33541. $tRow = array();
  33542. foreach($this->getTableMetaData()->getColumns() as $col) {
  33543. $tRow[$col] = $this->getValue($row, $col);
  33544. }
  33545. $data[$row] = $tRow;
  33546. }
  33547. $this->data = $data;
  33548. }
  33549. }
  33550. }
  33551. <?php
  33552. /*
  33553. * This file is part of DBUnit.
  33554. *
  33555. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33556. *
  33557. * For the full copyright and license information, please view the LICENSE
  33558. * file that was distributed with this source code.
  33559. */
  33560. /**
  33561. * Provides basic functionality for table meta data.
  33562. *
  33563. * @package DbUnit
  33564. * @author Mike Lively <m@digitalsandwich.com>
  33565. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33566. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33567. * @version Release: @package_version@
  33568. * @link http://www.phpunit.de/
  33569. * @since Class available since Release 1.0.0
  33570. */
  33571. abstract class PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData implements PHPUnit_Extensions_Database_DataSet_ITableMetaData
  33572. {
  33573. /**
  33574. * The names of all columns in the table.
  33575. *
  33576. * @var Array
  33577. */
  33578. protected $columns;
  33579. /**
  33580. * The names of all the primary keys in the table.
  33581. *
  33582. * @var Array
  33583. */
  33584. protected $primaryKeys;
  33585. /**
  33586. * @var string
  33587. */
  33588. protected $tableName;
  33589. /**
  33590. * Returns the names of the columns in the table.
  33591. *
  33592. * @return array
  33593. */
  33594. public function getColumns()
  33595. {
  33596. return $this->columns;
  33597. }
  33598. /**
  33599. * Returns the names of the primary key columns in the table.
  33600. *
  33601. * @return array
  33602. */
  33603. public function getPrimaryKeys()
  33604. {
  33605. return $this->primaryKeys;
  33606. }
  33607. /**
  33608. * Returns the name of the table.
  33609. *
  33610. * @return string
  33611. */
  33612. public function getTableName()
  33613. {
  33614. return $this->tableName;
  33615. }
  33616. /**
  33617. * Asserts that the given tableMetaData matches this tableMetaData.
  33618. *
  33619. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $other
  33620. */
  33621. public function matches(PHPUnit_Extensions_Database_DataSet_ITableMetaData $other)
  33622. {
  33623. if ($this->getTableName() != $other->getTableName() ||
  33624. $this->getColumns() != $other->getColumns()) {
  33625. return FALSE;
  33626. }
  33627. return TRUE;
  33628. }
  33629. }
  33630. <?php
  33631. /*
  33632. * This file is part of DBUnit.
  33633. *
  33634. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33635. *
  33636. * For the full copyright and license information, please view the LICENSE
  33637. * file that was distributed with this source code.
  33638. */
  33639. /**
  33640. * Creates Composite Datasets
  33641. *
  33642. * Allows for creating datasets from multiple sources (csv, query, xml, etc.)
  33643. *
  33644. * @package DbUnit
  33645. * @author Mike Lively <m@digitalsandwich.com>
  33646. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33647. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33648. * @version Release: @package_version@
  33649. * @link http://www.phpunit.de/
  33650. * @since Class available since Release 1.0.0
  33651. */
  33652. class PHPUnit_Extensions_Database_DataSet_CompositeDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  33653. {
  33654. protected $motherDataSet;
  33655. /**
  33656. * Creates a new Composite dataset
  33657. *
  33658. * You can pass in any data set that implements PHPUnit_Extensions_Database_DataSet_IDataSet
  33659. *
  33660. * @param string $delimiter
  33661. * @param string $enclosure
  33662. * @param string $escape
  33663. */
  33664. public function __construct(Array $dataSets = array())
  33665. {
  33666. $this->motherDataset = new PHPUnit_Extensions_Database_DataSet_DefaultDataSet();
  33667. foreach ($dataSets as $dataSet)
  33668. {
  33669. $this->addDataSet($dataSet);
  33670. }
  33671. }
  33672. /**
  33673. * Adds a new data set to the composite.
  33674. *
  33675. * The dataset may not define tables that already exist in the composite.
  33676. *
  33677. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  33678. */
  33679. public function addDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  33680. {
  33681. foreach ($dataSet->getTableNames() as $tableName)
  33682. {
  33683. if (!in_array($tableName, $this->getTableNames())) {
  33684. $this->motherDataset->addTable($dataSet->getTable($tableName));
  33685. } else {
  33686. $other = $dataSet->getTable($tableName);
  33687. $table = $this->getTable($tableName);
  33688. if (!$table->getTableMetaData()->matches($other->getTableMetaData()))
  33689. {
  33690. throw new InvalidArgumentException("There is already a table named $tableName with different table definition");
  33691. }
  33692. $table->addTableRows($dataSet->getTable($tableName));
  33693. }
  33694. }
  33695. }
  33696. /**
  33697. * Creates an iterator over the tables in the data set. If $reverse is
  33698. * true a reverse iterator will be returned.
  33699. *
  33700. * @param bool $reverse
  33701. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33702. */
  33703. protected function createIterator($reverse = FALSE)
  33704. {
  33705. if ($reverse) {
  33706. return $this->motherDataset->getReverseIterator();
  33707. } else {
  33708. return $this->motherDataset->getIterator();
  33709. }
  33710. }
  33711. }
  33712. <?php
  33713. /*
  33714. * This file is part of DBUnit.
  33715. *
  33716. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33717. *
  33718. * For the full copyright and license information, please view the LICENSE
  33719. * file that was distributed with this source code.
  33720. */
  33721. /**
  33722. * The default table iterator
  33723. *
  33724. * @package DbUnit
  33725. * @author Mike Lively <m@digitalsandwich.com>
  33726. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33727. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33728. * @version Release: @package_version@
  33729. * @link http://www.phpunit.de/
  33730. * @since Class available since Release 1.0.0
  33731. */
  33732. class PHPUnit_Extensions_Database_DataSet_DefaultTableIterator implements PHPUnit_Extensions_Database_DataSet_ITableIterator
  33733. {
  33734. /**
  33735. * An array of tables in the iterator.
  33736. *
  33737. * @var Array
  33738. */
  33739. protected $tables;
  33740. /**
  33741. * If this property is true then the tables will be iterated in reverse
  33742. * order.
  33743. *
  33744. * @var bool
  33745. */
  33746. protected $reverse;
  33747. /**
  33748. * Creates a new default table iterator object.
  33749. *
  33750. * @param array $tables
  33751. * @param bool $reverse
  33752. */
  33753. public function __construct(Array $tables, $reverse = FALSE)
  33754. {
  33755. $this->tables = $tables;
  33756. $this->reverse = $reverse;
  33757. $this->rewind();
  33758. }
  33759. /**
  33760. * Returns the current table.
  33761. *
  33762. * @return PHPUnit_Extensions_Database_DataSet_ITable
  33763. */
  33764. public function getTable()
  33765. {
  33766. return $this->current();
  33767. }
  33768. /**
  33769. * Returns the current table's meta data.
  33770. *
  33771. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  33772. */
  33773. public function getTableMetaData()
  33774. {
  33775. return $this->current()->getTableMetaData();
  33776. }
  33777. /**
  33778. * Returns the current table.
  33779. *
  33780. * @return PHPUnit_Extensions_Database_DataSet_ITable
  33781. */
  33782. public function current()
  33783. {
  33784. return current($this->tables);
  33785. }
  33786. /**
  33787. * Returns the name of the current table.
  33788. *
  33789. * @return string
  33790. */
  33791. public function key()
  33792. {
  33793. return $this->current()->getTableMetaData()->getTableName();
  33794. }
  33795. /**
  33796. * advances to the next element.
  33797. *
  33798. */
  33799. public function next()
  33800. {
  33801. if ($this->reverse) {
  33802. prev($this->tables);
  33803. } else {
  33804. next($this->tables);
  33805. }
  33806. }
  33807. /**
  33808. * Rewinds to the first element
  33809. */
  33810. public function rewind()
  33811. {
  33812. if ($this->reverse) {
  33813. end($this->tables);
  33814. } else {
  33815. reset($this->tables);
  33816. }
  33817. }
  33818. /**
  33819. * Returns true if the current index is valid
  33820. *
  33821. * @return bool
  33822. */
  33823. public function valid()
  33824. {
  33825. return ($this->current() !== FALSE);
  33826. }
  33827. }
  33828. <?php
  33829. /*
  33830. * This file is part of DBUnit.
  33831. *
  33832. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33833. *
  33834. * For the full copyright and license information, please view the LICENSE
  33835. * file that was distributed with this source code.
  33836. */
  33837. /**
  33838. * A dataset decorator that allows filtering out tables and table columns from
  33839. * results.
  33840. *
  33841. * @package DbUnit
  33842. * @author Mike Lively <m@digitalsandwich.com>
  33843. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33844. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33845. * @version Release: @package_version@
  33846. * @link http://www.phpunit.de/
  33847. * @since Class available since Release 1.0.0
  33848. */
  33849. class PHPUnit_Extensions_Database_DataSet_DataSetFilter extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  33850. {
  33851. /**
  33852. * The dataset being decorated.
  33853. * @var PHPUnit_Extensions_Database_DataSet_IDataSet
  33854. */
  33855. protected $originalDataSet;
  33856. /**
  33857. * The tables to exclude from the data set.
  33858. * @var Array
  33859. */
  33860. protected $excludeTables = array();
  33861. /**
  33862. * The tables to exclude from the data set.
  33863. * @var Array
  33864. */
  33865. protected $includeTables = array();
  33866. /**
  33867. * The columns to exclude from the data set.
  33868. * @var Array
  33869. */
  33870. protected $excludeColumns = array();
  33871. /**
  33872. * The columns to exclude from the data set.
  33873. * @var Array
  33874. */
  33875. protected $includeColumns = array();
  33876. /**
  33877. * Creates a new filtered data set.
  33878. *
  33879. * The $exclude tables should be an associative array using table names as
  33880. * the key and an array of column names to exclude for the value. If you
  33881. * would like to exclude a full table set the value of the table's entry
  33882. * to the special string '*'.
  33883. *
  33884. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $originalDataSet
  33885. * @param Array $excludeTables @deprecated use set* methods instead.
  33886. */
  33887. public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $originalDataSet, array $excludeTables = array())
  33888. {
  33889. $this->originalDataSet = $originalDataSet;
  33890. $tables = array();
  33891. foreach ($excludeTables as $tableName => $values) {
  33892. if (is_array($values)) {
  33893. $this->setExcludeColumnsForTable($tableName, $values);
  33894. } elseif ($values == '*') {
  33895. $tables[] = $tableName;
  33896. } else {
  33897. $this->setExcludeColumnsForTable($tableName, (array)$values);
  33898. }
  33899. }
  33900. $this->addExcludeTables($tables);
  33901. }
  33902. /**
  33903. * Creates an iterator over the tables in the data set. If $reverse is
  33904. * true a reverse iterator will be returned.
  33905. *
  33906. * @param bool $reverse
  33907. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33908. */
  33909. protected function createIterator($reverse = FALSE)
  33910. {
  33911. $original_tables = $this->originalDataSet->getIterator($reverse);
  33912. $new_tables = array();
  33913. foreach ($original_tables as $table) {
  33914. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  33915. $tableName = $table->getTableMetaData()->getTableName();
  33916. if ((!in_array($tableName, $this->includeTables) && !empty($this->includeTables)) ||
  33917. in_array($tableName, $this->excludeTables)
  33918. ) {
  33919. continue;
  33920. } elseif (!empty($this->excludeColumns[$tableName]) || !empty($this->includeColumns[$tableName])) {
  33921. $new_table = new PHPUnit_Extensions_Database_DataSet_TableFilter($table);
  33922. if (!empty($this->includeColumns[$tableName])) {
  33923. $new_table->addIncludeColumns($this->includeColumns[$tableName]);
  33924. }
  33925. if (!empty($this->excludeColumns[$tableName])) {
  33926. $new_table->addExcludeColumns($this->excludeColumns[$tableName]);
  33927. }
  33928. $new_tables[] = $new_table;
  33929. } else {
  33930. $new_tables[] = $table;
  33931. }
  33932. }
  33933. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($new_tables);
  33934. }
  33935. /**
  33936. * Adds tables to be included in the data set.
  33937. * @param array $tables
  33938. */
  33939. public function addIncludeTables(Array $tables)
  33940. {
  33941. $this->includeTables = array_unique(array_merge($this->includeTables, $tables));
  33942. }
  33943. /**
  33944. * Adds tables to be included in the data set.
  33945. * @param array $tables
  33946. */
  33947. public function addExcludeTables(Array $tables)
  33948. {
  33949. $this->excludeTables = array_unique(array_merge($this->excludeTables, $tables));
  33950. }
  33951. /**
  33952. * Adds columns to include in the data set for the given table.
  33953. * @param string $table
  33954. * @param Array $columns
  33955. */
  33956. public function setIncludeColumnsForTable($table, Array $columns)
  33957. {
  33958. $this->includeColumns[$table] = $columns;
  33959. }
  33960. /**
  33961. * Adds columns to include in the data set for the given table.
  33962. * @param string $table
  33963. * @param Array $columns
  33964. */
  33965. public function setExcludeColumnsForTable($table, Array $columns)
  33966. {
  33967. $this->excludeColumns[$table] = $columns;
  33968. }
  33969. }
  33970. <?php
  33971. /*
  33972. * This file is part of DBUnit.
  33973. *
  33974. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33975. *
  33976. * For the full copyright and license information, please view the LICENSE
  33977. * file that was distributed with this source code.
  33978. */
  33979. /**
  33980. * An interface for parsing YAML files.
  33981. *
  33982. * @package DbUnit
  33983. * @author Yash Parghi <yash@yashparghi.com>
  33984. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  33985. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33986. * @link http://www.phpunit.de/
  33987. * @since Class available since Release 1.3.1
  33988. */
  33989. interface PHPUnit_Extensions_Database_DataSet_IYamlParser {
  33990. /**
  33991. * @param string $yamlFile
  33992. * @return array parsed YAML
  33993. */
  33994. public function parseYaml($yamlFile);
  33995. }
  33996. <?php
  33997. /*
  33998. * This file is part of DBUnit.
  33999. *
  34000. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34001. *
  34002. * For the full copyright and license information, please view the LICENSE
  34003. * file that was distributed with this source code.
  34004. */
  34005. /**
  34006. * The default implementation of a data set.
  34007. *
  34008. * @package DbUnit
  34009. * @author Mike Lively <m@digitalsandwich.com>
  34010. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34011. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34012. * @version Release: @package_version@
  34013. * @link http://www.phpunit.de/
  34014. * @since Class available since Release 1.0.0
  34015. */
  34016. class PHPUnit_Extensions_Database_DataSet_XmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet
  34017. {
  34018. protected function getTableInfo(Array &$tableColumns, Array &$tableValues)
  34019. {
  34020. if ($this->xmlFileContents->getName() != 'dataset') {
  34021. throw new PHPUnit_Extensions_Database_Exception("The root element of an xml data set file must be called <dataset>");
  34022. }
  34023. foreach ($this->xmlFileContents->xpath('/dataset/table') as $tableElement) {
  34024. if (empty($tableElement['name'])) {
  34025. throw new PHPUnit_Extensions_Database_Exception("Table elements must include a name attribute specifying the table name.");
  34026. }
  34027. $tableName = (string)$tableElement['name'];
  34028. if (!isset($tableColumns[$tableName])) {
  34029. $tableColumns[$tableName] = array();
  34030. }
  34031. if (!isset($tableValues[$tableName])) {
  34032. $tableValues[$tableName] = array();
  34033. }
  34034. $tableInstanceColumns = array();
  34035. foreach ($tableElement->xpath('./column') as $columnElement) {
  34036. $columnName = (string)$columnElement;
  34037. if (empty($columnName)) {
  34038. throw new PHPUnit_Extensions_Database_Exception("Missing <column> elements for table $tableName. Add one or more <column> elements to the <table> element.");
  34039. }
  34040. if (!in_array($columnName, $tableColumns[$tableName])) {
  34041. $tableColumns[$tableName][] = $columnName;
  34042. }
  34043. $tableInstanceColumns[] = $columnName;
  34044. }
  34045. foreach ($tableElement->xpath('./row') as $rowElement) {
  34046. $rowValues = array();
  34047. $index = 0;
  34048. $numOfTableInstanceColumns = count($tableInstanceColumns);
  34049. foreach ($rowElement->children() as $columnValue) {
  34050. if ($index >= $numOfTableInstanceColumns) {
  34051. throw new PHPUnit_Extensions_Database_Exception("Row contains more values than the number of columns defined for table $tableName.");
  34052. }
  34053. switch ($columnValue->getName()) {
  34054. case 'value':
  34055. $rowValues[$tableInstanceColumns[$index]] = (string)$columnValue;
  34056. $index++;
  34057. break;
  34058. case 'null':
  34059. $rowValues[$tableInstanceColumns[$index]] = NULL;
  34060. $index++;
  34061. break;
  34062. default:
  34063. throw new PHPUnit_Extensions_Database_Exception("Unknown element ".$columnValue->getName()." in a row element.");
  34064. }
  34065. }
  34066. $tableValues[$tableName][] = $rowValues;
  34067. }
  34068. }
  34069. }
  34070. public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename)
  34071. {
  34072. $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_Xml();
  34073. $pers->setFileName($filename);
  34074. try {
  34075. $pers->write($dataset);
  34076. }
  34077. catch (RuntimeException $e) {
  34078. throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.');
  34079. }
  34080. }
  34081. }
  34082. <?php
  34083. /*
  34084. * This file is part of DBUnit.
  34085. *
  34086. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34087. *
  34088. * For the full copyright and license information, please view the LICENSE
  34089. * file that was distributed with this source code.
  34090. */
  34091. /**
  34092. * The default implementation of a data set.
  34093. *
  34094. * @package DbUnit
  34095. * @author Mike Lively <m@digitalsandwich.com>
  34096. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34097. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34098. * @version Release: @package_version@
  34099. * @link http://www.phpunit.de/
  34100. * @since Class available since Release 1.0.0
  34101. */
  34102. class PHPUnit_Extensions_Database_DataSet_DefaultDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  34103. {
  34104. /**
  34105. * An array of ITable objects.
  34106. *
  34107. * @var array
  34108. */
  34109. protected $tables;
  34110. /**
  34111. * Creates a new dataset using the given tables.
  34112. *
  34113. * @param array $tables
  34114. */
  34115. public function __construct(Array $tables = array())
  34116. {
  34117. $this->tables = $tables;
  34118. }
  34119. /**
  34120. * Adds a table to the dataset.
  34121. *
  34122. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34123. */
  34124. public function addTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34125. {
  34126. $this->tables[] = $table;
  34127. }
  34128. /**
  34129. * Creates an iterator over the tables in the data set. If $reverse is
  34130. * true a reverse iterator will be returned.
  34131. *
  34132. * @param bool $reverse
  34133. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  34134. */
  34135. protected function createIterator($reverse = FALSE)
  34136. {
  34137. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
  34138. }
  34139. }
  34140. <?php
  34141. /*
  34142. * This file is part of DBUnit.
  34143. *
  34144. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34145. *
  34146. * For the full copyright and license information, please view the LICENSE
  34147. * file that was distributed with this source code.
  34148. */
  34149. /**
  34150. * The default YAML parser, using Symfony/Yaml.
  34151. *
  34152. * @package DbUnit
  34153. * @author Yash Parghi <yash@yashparghi.com>
  34154. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  34155. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34156. * @link http://www.phpunit.de/
  34157. * @since Class available since Release 1.3.1
  34158. */
  34159. class PHPUnit_Extensions_Database_DataSet_SymfonyYamlParser implements PHPUnit_Extensions_Database_DataSet_IYamlParser {
  34160. public function parseYaml($yamlFile) {
  34161. return Symfony\Component\Yaml\Yaml::parse($yamlFile);
  34162. }
  34163. }
  34164. <?php
  34165. /*
  34166. * This file is part of DBUnit.
  34167. *
  34168. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34169. *
  34170. * For the full copyright and license information, please view the LICENSE
  34171. * file that was distributed with this source code.
  34172. */
  34173. /**
  34174. * Provides a basic interface for creating and reading data from data sets.
  34175. *
  34176. * @package DbUnit
  34177. * @author Mike Lively <m@digitalsandwich.com>
  34178. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34179. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34180. * @version Release: @package_version@
  34181. * @link http://www.phpunit.de/
  34182. * @since Class available since Release 1.0.0
  34183. */
  34184. interface PHPUnit_Extensions_Database_DataSet_IDataSet extends IteratorAggregate
  34185. {
  34186. /**
  34187. * Returns an array of table names contained in the dataset.
  34188. *
  34189. * @return array
  34190. */
  34191. public function getTableNames();
  34192. /**
  34193. * Returns a table meta data object for the given table.
  34194. *
  34195. * @param string $tableName
  34196. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  34197. */
  34198. public function getTableMetaData($tableName);
  34199. /**
  34200. * Returns a table object for the given table.
  34201. *
  34202. * @param string $tableName
  34203. * @return PHPUnit_Extensions_Database_DataSet_ITable
  34204. */
  34205. public function getTable($tableName);
  34206. /**
  34207. * Returns a reverse iterator for all table objects in the given dataset.
  34208. *
  34209. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  34210. */
  34211. public function getReverseIterator();
  34212. /**
  34213. * Asserts that the given data set matches this data set.
  34214. *
  34215. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $other
  34216. */
  34217. public function matches(PHPUnit_Extensions_Database_DataSet_IDataSet $other);
  34218. }
  34219. <?php
  34220. /*
  34221. * This file is part of DBUnit.
  34222. *
  34223. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34224. *
  34225. * For the full copyright and license information, please view the LICENSE
  34226. * file that was distributed with this source code.
  34227. */
  34228. /**
  34229. * Provides a basic interface for returning table meta data.
  34230. *
  34231. * @package DbUnit
  34232. * @author Mike Lively <m@digitalsandwich.com>
  34233. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34234. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34235. * @version Release: @package_version@
  34236. * @link http://www.phpunit.de/
  34237. * @since Class available since Release 1.0.0
  34238. */
  34239. interface PHPUnit_Extensions_Database_DataSet_ITableMetaData
  34240. {
  34241. /**
  34242. * Returns the names of the columns in the table.
  34243. *
  34244. * @return array
  34245. */
  34246. public function getColumns();
  34247. /**
  34248. * Returns the names of the primary key columns in the table.
  34249. *
  34250. * @return array
  34251. */
  34252. public function getPrimaryKeys();
  34253. /**
  34254. * Returns the name of the table.
  34255. *
  34256. * @return string
  34257. */
  34258. public function getTableName();
  34259. /**
  34260. * Asserts that the given tableMetaData matches this tableMetaData.
  34261. *
  34262. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $other
  34263. */
  34264. public function matches(PHPUnit_Extensions_Database_DataSet_ITableMetaData $other);
  34265. }
  34266. <?php
  34267. /*
  34268. * This file is part of DBUnit.
  34269. *
  34270. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34271. *
  34272. * For the full copyright and license information, please view the LICENSE
  34273. * file that was distributed with this source code.
  34274. */
  34275. /**
  34276. * An abstract implementation of a dataset persistor.
  34277. *
  34278. * @package DbUnit
  34279. * @author Mike Lively <m@digitalsandwich.com>
  34280. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34281. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34282. * @version Release: @package_version@
  34283. * @link http://www.phpunit.de/
  34284. * @since Class available since Release 1.0.0
  34285. */
  34286. abstract class PHPUnit_Extensions_Database_DataSet_Persistors_Abstract implements PHPUnit_Extensions_Database_DataSet_IPersistable
  34287. {
  34288. public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34289. {
  34290. $this->saveDataSet($dataset);
  34291. }
  34292. /**
  34293. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34294. */
  34295. protected function saveDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34296. {
  34297. $this->startDataSet($dataset);
  34298. foreach ($dataset as $table) {
  34299. $this->saveTable($table);
  34300. }
  34301. $this->endDataSet($dataset);
  34302. }
  34303. /**
  34304. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34305. */
  34306. protected function saveTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34307. {
  34308. $rowCount = $table->getRowCount();
  34309. $this->startTable($table);
  34310. for ($i = 0; $i < $rowCount; $i++) {
  34311. $this->row($table->getRow($i), $table);
  34312. }
  34313. $this->endTable($table);
  34314. }
  34315. /**
  34316. * Override to save the start of a dataset.
  34317. *
  34318. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34319. */
  34320. abstract protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset);
  34321. /**
  34322. * Override to save the end of a dataset.
  34323. *
  34324. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34325. */
  34326. abstract protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset);
  34327. /**
  34328. * Override to save the start of a table.
  34329. *
  34330. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34331. */
  34332. abstract protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table);
  34333. /**
  34334. * Override to save the end of a table.
  34335. *
  34336. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34337. */
  34338. abstract protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table);
  34339. /**
  34340. * Override to save a table row.
  34341. *
  34342. * @param array $row
  34343. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34344. */
  34345. abstract protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table);
  34346. }
  34347. <?php
  34348. /*
  34349. * This file is part of DBUnit.
  34350. *
  34351. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34352. *
  34353. * For the full copyright and license information, please view the LICENSE
  34354. * file that was distributed with this source code.
  34355. */
  34356. /**
  34357. * A XML dataset persistor.
  34358. *
  34359. * @package DbUnit
  34360. * @author Mike Lively <m@digitalsandwich.com>
  34361. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34362. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34363. * @version Release: @package_version@
  34364. * @link http://www.phpunit.de/
  34365. * @since Class available since Release 1.0.0
  34366. */
  34367. class PHPUnit_Extensions_Database_DataSet_Persistors_Xml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract
  34368. {
  34369. /**
  34370. * @var string
  34371. */
  34372. protected $filename;
  34373. /**
  34374. * @var resource
  34375. */
  34376. protected $fh;
  34377. /**
  34378. * Sets the filename that this persistor will save to.
  34379. *
  34380. * @param string $filename
  34381. */
  34382. public function setFileName($filename)
  34383. {
  34384. $this->filename = $filename;
  34385. }
  34386. /**
  34387. * Override to save the start of a dataset.
  34388. *
  34389. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34390. */
  34391. protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34392. {
  34393. $this->fh = fopen($this->filename, 'w');
  34394. if ($this->fh === FALSE) {
  34395. throw new PHPUnit_Framework_Exception(
  34396. "Could not open {$this->filename} for writing see " . __CLASS__ . "::setFileName()"
  34397. );
  34398. }
  34399. fwrite($this->fh, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
  34400. fwrite($this->fh, "<dataset>\n");
  34401. }
  34402. /**
  34403. * Override to save the end of a dataset.
  34404. *
  34405. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34406. */
  34407. protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34408. {
  34409. fwrite($this->fh, "</dataset>\n");
  34410. }
  34411. /**
  34412. * Override to save the start of a table.
  34413. *
  34414. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34415. */
  34416. protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34417. {
  34418. fwrite($this->fh, "\t<table name=\"{$table->getTableMetaData()->getTableName()}\">\n");
  34419. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  34420. fwrite($this->fh, "\t\t<column>{$columnName}</column>\n");
  34421. }
  34422. }
  34423. /**
  34424. * Override to save the end of a table.
  34425. *
  34426. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34427. */
  34428. protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34429. {
  34430. fwrite($this->fh, "\t</table>\n");
  34431. }
  34432. /**
  34433. * Override to save a table row.
  34434. *
  34435. * @param array $row
  34436. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34437. */
  34438. protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table)
  34439. {
  34440. fwrite($this->fh, "\t\t<row>\n");
  34441. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  34442. if (isset($row[$columnName])) {
  34443. fwrite($this->fh, "\t\t\t<value>" . htmlspecialchars($row[$columnName]) . "</value>\n");
  34444. } else {
  34445. fwrite($this->fh, "\t\t\t<null />\n");
  34446. }
  34447. }
  34448. fwrite($this->fh, "\t\t</row>\n");
  34449. }
  34450. }
  34451. <?php
  34452. /*
  34453. * This file is part of DBUnit.
  34454. *
  34455. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34456. *
  34457. * For the full copyright and license information, please view the LICENSE
  34458. * file that was distributed with this source code.
  34459. */
  34460. /**
  34461. * A Flat XML dataset persistor.
  34462. *
  34463. * @package DbUnit
  34464. * @author Mike Lively <m@digitalsandwich.com>
  34465. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34466. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34467. * @version Release: @package_version@
  34468. * @link http://www.phpunit.de/
  34469. * @since Class available since Release 1.0.0
  34470. */
  34471. class PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract
  34472. {
  34473. /**
  34474. * @var string
  34475. */
  34476. protected $filename;
  34477. /**
  34478. * @var resource
  34479. */
  34480. protected $fh;
  34481. /**
  34482. * Sets the filename that this persistor will save to.
  34483. *
  34484. * @param string $filename
  34485. */
  34486. public function setFileName($filename)
  34487. {
  34488. $this->filename = $filename;
  34489. }
  34490. /**
  34491. * Override to save the start of a dataset.
  34492. *
  34493. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34494. */
  34495. protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34496. {
  34497. $this->fh = fopen($this->filename, 'w');
  34498. if ($this->fh === FALSE) {
  34499. throw new PHPUnit_Framework_Exception(
  34500. "Could not open {$this->filename} for writing see " . __CLASS__ . "::setFileName()"
  34501. );
  34502. }
  34503. fwrite($this->fh, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
  34504. fwrite($this->fh, "<dataset>\n");
  34505. }
  34506. /**
  34507. * Override to save the end of a dataset.
  34508. *
  34509. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34510. */
  34511. protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34512. {
  34513. fwrite($this->fh, "</dataset>\n");
  34514. }
  34515. /**
  34516. * Override to save the start of a table.
  34517. *
  34518. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34519. */
  34520. protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34521. {
  34522. if ($table->getRowCount() == 0) {
  34523. fwrite($this->fh, "\t<{$table->getTableMetaData()->getTableName()} />\n");
  34524. }
  34525. }
  34526. /**
  34527. * Override to save the end of a table.
  34528. *
  34529. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34530. */
  34531. protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34532. {
  34533. //do nothing
  34534. }
  34535. /**
  34536. * Override to save a table row.
  34537. *
  34538. * @param array $row
  34539. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34540. */
  34541. protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table)
  34542. {
  34543. fwrite($this->fh, "\t<{$table->getTableMetaData()->getTableName()}\n");
  34544. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  34545. if (isset($row[$columnName])) {
  34546. fwrite($this->fh, "\t\t{$columnName}=\"". htmlspecialchars($row[$columnName]) . "\"\n");
  34547. }
  34548. }
  34549. fwrite($this->fh, "\t/>\n");
  34550. }
  34551. }
  34552. <?php
  34553. /*
  34554. * This file is part of DBUnit.
  34555. *
  34556. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34557. *
  34558. * For the full copyright and license information, please view the LICENSE
  34559. * file that was distributed with this source code.
  34560. */
  34561. /**
  34562. * A yaml dataset persistor
  34563. *
  34564. * @package DbUnit
  34565. * @author Mike Lively <m@digitalsandwich.com>
  34566. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34567. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34568. * @version Release: @package_version@
  34569. * @link http://www.phpunit.de/
  34570. * @since Class available since Release 1.0.0
  34571. */
  34572. class PHPUnit_Extensions_Database_DataSet_Persistors_Yaml implements PHPUnit_Extensions_Database_DataSet_IPersistable
  34573. {
  34574. /**
  34575. * @var string
  34576. */
  34577. protected $filename;
  34578. /**
  34579. * Sets the filename that this persistor will save to.
  34580. *
  34581. * @param string $filename
  34582. */
  34583. public function setFileName($filename)
  34584. {
  34585. $this->filename = $filename;
  34586. }
  34587. /**
  34588. * Writes the dataset to a yaml file
  34589. *
  34590. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34591. */
  34592. public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34593. {
  34594. $phpArr = array();
  34595. $emptyTables = array();
  34596. foreach ($dataset as $table) {
  34597. $tableName = $table->getTableMetaData()->getTableName();
  34598. $rowCount = $table->getRowCount();
  34599. if (!$rowCount) {
  34600. $emptyTables[] = $tableName;
  34601. continue;
  34602. }
  34603. $phpArr[$tableName] = array();
  34604. for ($i = 0; $i < $rowCount; $i++) {
  34605. $phpArr[$tableName][] = $table->getRow($i);
  34606. }
  34607. }
  34608. $emptyTablesAsString = '';
  34609. if (count($emptyTables)) {
  34610. $emptyTablesAsString = implode(":\n", $emptyTables) . ":\n\n";
  34611. }
  34612. file_put_contents(
  34613. $this->filename,
  34614. Symfony\Component\Yaml\Yaml::dump($phpArr, 3) . $emptyTablesAsString
  34615. );
  34616. }
  34617. }
  34618. <?php
  34619. /*
  34620. * This file is part of DBUnit.
  34621. *
  34622. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34623. *
  34624. * For the full copyright and license information, please view the LICENSE
  34625. * file that was distributed with this source code.
  34626. */
  34627. /**
  34628. * A MySQL XML dataset persistor.
  34629. *
  34630. * @package DbUnit
  34631. * @author Matthew Turland <tobias382@gmail.com>
  34632. * @copyright 2010-2014 Matthew Turland <tobias382@gmail.com>
  34633. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34634. * @version Release: @package_version@
  34635. * @link http://www.phpunit.de/
  34636. * @since Class available since Release 1.0.0
  34637. */
  34638. class PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract
  34639. {
  34640. /**
  34641. * @var string
  34642. */
  34643. protected $filename;
  34644. /**
  34645. * @var string
  34646. */
  34647. protected $database;
  34648. /**
  34649. * @var resource
  34650. */
  34651. protected $fh;
  34652. /**
  34653. * Sets the filename that this persistor will save to.
  34654. *
  34655. * @param string $filename
  34656. */
  34657. public function setFileName($filename)
  34658. {
  34659. $this->filename = $filename;
  34660. }
  34661. /**
  34662. * Sets the name of the database.
  34663. *
  34664. * @param string $database
  34665. */
  34666. public function setDatabase($database)
  34667. {
  34668. $this->database = $database;
  34669. }
  34670. /**
  34671. * Override to save the start of a dataset.
  34672. *
  34673. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34674. */
  34675. protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34676. {
  34677. $this->fh = fopen($this->filename, 'w');
  34678. if ($this->fh === FALSE) {
  34679. throw new PHPUnit_Framework_Exception(
  34680. "Could not open {$this->filename} for writing see " . __CLASS__ . "::setFileName()"
  34681. );
  34682. }
  34683. fwrite($this->fh, '<?xml version="1.0" encoding="UTF-8"?>' . "\n");
  34684. fwrite($this->fh, '<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . "\n");
  34685. fwrite($this->fh, '<database name="' . $this->database . '">' . "\n");
  34686. }
  34687. /**
  34688. * Override to save the end of a dataset.
  34689. *
  34690. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34691. */
  34692. protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34693. {
  34694. fwrite($this->fh, '</database>' . "\n");
  34695. fwrite($this->fh, '</mysqldump>' . "\n");
  34696. }
  34697. /**
  34698. * Override to save the start of a table.
  34699. *
  34700. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34701. */
  34702. protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34703. {
  34704. fwrite($this->fh, "\t" . '<table_data name="' . $table->getTableMetaData()->getTableName() . '">' . "\n");
  34705. }
  34706. /**
  34707. * Override to save the end of a table.
  34708. *
  34709. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34710. */
  34711. protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34712. {
  34713. fwrite($this->fh, "\t" . '</table_data>' . "\n");
  34714. }
  34715. /**
  34716. * Override to save a table row.
  34717. *
  34718. * @param array $row
  34719. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34720. */
  34721. protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table)
  34722. {
  34723. fwrite($this->fh, "\t" . '<row>' . "\n");
  34724. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  34725. fwrite($this->fh, "\t\t" . '<field name="' . $columnName . '"');
  34726. if (isset($row[$columnName])) {
  34727. fwrite($this->fh, '>' . htmlspecialchars($row[$columnName]) . '</field>' . "\n");
  34728. } else {
  34729. fwrite($this->fh, ' xsi:nil="true" />' . "\n");
  34730. }
  34731. }
  34732. fwrite($this->fh, "\t" . '</row>' . "\n");
  34733. }
  34734. }
  34735. <?php
  34736. /*
  34737. * This file is part of DBUnit.
  34738. *
  34739. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34740. *
  34741. * For the full copyright and license information, please view the LICENSE
  34742. * file that was distributed with this source code.
  34743. */
  34744. /**
  34745. * Creates the appropriate Persistor based on a given type and spec.
  34746. *
  34747. * @package DbUnit
  34748. * @author Mike Lively <m@digitalsandwich.com>
  34749. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34750. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34751. * @version Release: @package_version@
  34752. * @link http://www.phpunit.de//**
  34753. * @since Class available since Release 1.0.0
  34754. */
  34755. class PHPUnit_Extensions_Database_DataSet_Persistors_Factory
  34756. {
  34757. /**
  34758. * Returns the persistor.
  34759. *
  34760. * @param string $type
  34761. * @param string $spec
  34762. * @return PHPUnit_Extensions_Database_DataSet_IPersistable
  34763. */
  34764. public function getPersistorBySpec($type, $spec)
  34765. {
  34766. switch (strtolower($type)) {
  34767. case 'xml':
  34768. $xmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_Xml();
  34769. $xmlPersistor->setFileName($spec);
  34770. return $xmlPersistor;
  34771. case 'flatxml':
  34772. $flatXmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml();
  34773. $flatXmlPersistor->setFileName($spec);
  34774. return $flatXmlPersistor;
  34775. case 'yaml':
  34776. $yamlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_Yaml();
  34777. $yamlPersistor->setFileName($spec);
  34778. return $yamlPersistor;
  34779. case 'mysqlxml':
  34780. $mysqlXmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml();
  34781. $mysqlXmlPersistor->setFileName($spec);
  34782. return $mysqlXmlPersistor;
  34783. default:
  34784. throw new PHPUnit_Extensions_Database_Exception("I don't know what you want from me. PERSISTOR");
  34785. }
  34786. }
  34787. }
  34788. <?php
  34789. /*
  34790. * This file is part of DBUnit.
  34791. *
  34792. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34793. *
  34794. * For the full copyright and license information, please view the LICENSE
  34795. * file that was distributed with this source code.
  34796. */
  34797. /**
  34798. * Creates CsvDataSets.
  34799. *
  34800. * You can incrementally add CSV files as tables to your datasets
  34801. *
  34802. * @package DbUnit
  34803. * @author Mike Lively <m@digitalsandwich.com>
  34804. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34805. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34806. * @version Release: @package_version@
  34807. * @link http://www.phpunit.de/
  34808. * @since Class available since Release 1.0.0
  34809. */
  34810. class PHPUnit_Extensions_Database_DataSet_CsvDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  34811. {
  34812. /**
  34813. * @var array
  34814. */
  34815. protected $tables = array();
  34816. /**
  34817. * @var string
  34818. */
  34819. protected $delimiter = ',';
  34820. /**
  34821. * @var string
  34822. */
  34823. protected $enclosure = '"';
  34824. /**
  34825. * @var string
  34826. */
  34827. protected $escape = '"';
  34828. /**
  34829. * Creates a new CSV dataset
  34830. *
  34831. * You can pass in the parameters for how csv files will be read.
  34832. *
  34833. * @param string $delimiter
  34834. * @param string $enclosure
  34835. * @param string $escape
  34836. */
  34837. public function __construct($delimiter = ',', $enclosure = '"', $escape = '"')
  34838. {
  34839. $this->delimiter = $delimiter;
  34840. $this->enclosure = $enclosure;
  34841. $this->escape = $escape;
  34842. }
  34843. /**
  34844. * Adds a table to the dataset
  34845. *
  34846. * The table will be given the passed name. $csvFile should be a path to
  34847. * a valid csv file (based on the arguments passed to the constructor.)
  34848. *
  34849. * @param string $tableName
  34850. * @param string $csvFile
  34851. */
  34852. public function addTable($tableName, $csvFile)
  34853. {
  34854. if (!is_file($csvFile)) {
  34855. throw new InvalidArgumentException("Could not find csv file: {$csvFile}");
  34856. }
  34857. if (!is_readable($csvFile)) {
  34858. throw new InvalidArgumentException("Could not read csv file: {$csvFile}");
  34859. }
  34860. $fh = fopen($csvFile, 'r');
  34861. $columns = $this->getCsvRow($fh);
  34862. if ($columns === FALSE)
  34863. {
  34864. throw new InvalidArgumentException("Could not determine the headers from the given file {$csvFile}");
  34865. }
  34866. $metaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns);
  34867. $table = new PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData);
  34868. while (($row = $this->getCsvRow($fh)) !== FALSE)
  34869. {
  34870. $table->addRow(array_combine($columns, $row));
  34871. }
  34872. $this->tables[$tableName] = $table;
  34873. }
  34874. /**
  34875. * Creates an iterator over the tables in the data set. If $reverse is
  34876. * true a reverse iterator will be returned.
  34877. *
  34878. * @param bool $reverse
  34879. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  34880. */
  34881. protected function createIterator($reverse = FALSE)
  34882. {
  34883. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
  34884. }
  34885. /**
  34886. * Returns a row from the csv file in an indexed array.
  34887. *
  34888. * @param resource $fh
  34889. * @return array
  34890. */
  34891. protected function getCsvRow($fh)
  34892. {
  34893. if (version_compare(PHP_VERSION, '5.3.0', '>')) {
  34894. return fgetcsv($fh, NULL, $this->delimiter, $this->enclosure, $this->escape);
  34895. } else {
  34896. return fgetcsv($fh, NULL, $this->delimiter, $this->enclosure);
  34897. }
  34898. }
  34899. }
  34900. <?php
  34901. /*
  34902. * This file is part of DBUnit.
  34903. *
  34904. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34905. *
  34906. * For the full copyright and license information, please view the LICENSE
  34907. * file that was distributed with this source code.
  34908. */
  34909. /**
  34910. * The default table iterator
  34911. *
  34912. * @package DbUnit
  34913. * @author Mike Lively <m@digitalsandwich.com>
  34914. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34915. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34916. * @version Release: @package_version@
  34917. * @link http://www.phpunit.de/
  34918. * @since Class available since Release 1.0.0
  34919. */
  34920. class PHPUnit_Extensions_Database_DataSet_ReplacementTableIterator implements OuterIterator, PHPUnit_Extensions_Database_DataSet_ITableIterator
  34921. {
  34922. /**
  34923. * @var PHPUnit_Extensions_Database_DataSet_ITableIterator
  34924. */
  34925. protected $innerIterator;
  34926. /**
  34927. * @var array
  34928. */
  34929. protected $fullReplacements;
  34930. /**
  34931. * @var array
  34932. */
  34933. protected $subStrReplacements;
  34934. /**
  34935. * Creates a new replacement table iterator object.
  34936. *
  34937. * @param PHPUnit_Extensions_Database_DataSet_ITableIterator $innerIterator
  34938. * @param array $fullReplacements
  34939. * @param array $subStrReplacements
  34940. */
  34941. public function __construct(PHPUnit_Extensions_Database_DataSet_ITableIterator $innerIterator, Array $fullReplacements = array(), Array $subStrReplacements = array())
  34942. {
  34943. $this->innerIterator = $innerIterator;
  34944. $this->fullReplacements = $fullReplacements;
  34945. $this->subStrReplacements = $subStrReplacements;
  34946. }
  34947. /**
  34948. * Adds a new full replacement
  34949. *
  34950. * Full replacements will only replace values if the FULL value is a match
  34951. *
  34952. * @param string $value
  34953. * @param string $replacement
  34954. */
  34955. public function addFullReplacement($value, $replacement)
  34956. {
  34957. $this->fullReplacements[$value] = $replacement;
  34958. }
  34959. /**
  34960. * Adds a new substr replacement
  34961. *
  34962. * Substr replacements will replace all occurances of the substr in every column
  34963. *
  34964. * @param string $value
  34965. * @param string $replacement
  34966. */
  34967. public function addSubStrReplacement($value, $replacement)
  34968. {
  34969. $this->subStrReplacements[$value] = $replacement;
  34970. }
  34971. /**
  34972. * Returns the current table.
  34973. *
  34974. * @return PHPUnit_Extensions_Database_DataSet_ITable
  34975. */
  34976. public function getTable()
  34977. {
  34978. return $this->current();
  34979. }
  34980. /**
  34981. * Returns the current table's meta data.
  34982. *
  34983. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  34984. */
  34985. public function getTableMetaData()
  34986. {
  34987. $this->current()->getTableMetaData();
  34988. }
  34989. /**
  34990. * Returns the current table.
  34991. *
  34992. * @return PHPUnit_Extensions_Database_DataSet_ITable
  34993. */
  34994. public function current()
  34995. {
  34996. return new PHPUnit_Extensions_Database_DataSet_ReplacementTable($this->innerIterator->current(), $this->fullReplacements, $this->subStrReplacements);
  34997. }
  34998. /**
  34999. * Returns the name of the current table.
  35000. *
  35001. * @return string
  35002. */
  35003. public function key()
  35004. {
  35005. return $this->current()->getTableMetaData()->getTableName();
  35006. }
  35007. /**
  35008. * advances to the next element.
  35009. *
  35010. */
  35011. public function next()
  35012. {
  35013. $this->innerIterator->next();
  35014. }
  35015. /**
  35016. * Rewinds to the first element
  35017. */
  35018. public function rewind()
  35019. {
  35020. $this->innerIterator->rewind();
  35021. }
  35022. /**
  35023. * Returns true if the current index is valid
  35024. *
  35025. * @return bool
  35026. */
  35027. public function valid()
  35028. {
  35029. return $this->innerIterator->valid();
  35030. }
  35031. public function getInnerIterator()
  35032. {
  35033. return $this->innerIterator;
  35034. }
  35035. }
  35036. <?php
  35037. /*
  35038. * This file is part of DBUnit.
  35039. *
  35040. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35041. *
  35042. * For the full copyright and license information, please view the LICENSE
  35043. * file that was distributed with this source code.
  35044. */
  35045. /**
  35046. * Allows for replacing arbitrary values or portions of values with new data.
  35047. *
  35048. * A usage for this is replacing all values == '[NULL'] with a true NULL value
  35049. *
  35050. * @package DbUnit
  35051. * @author Mike Lively <m@digitalsandwich.com>
  35052. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35053. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35054. * @version Release: @package_version@
  35055. * @link http://www.phpunit.de/
  35056. * @since Class available since Release 1.0.0
  35057. */
  35058. class PHPUnit_Extensions_Database_DataSet_ReplacementDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  35059. {
  35060. /**
  35061. * @var PHPUnit_Extensions_Database_DataSet_IDataSet
  35062. */
  35063. protected $dataSet;
  35064. /**
  35065. * @var array
  35066. */
  35067. protected $fullReplacements;
  35068. /**
  35069. * @var array
  35070. */
  35071. protected $subStrReplacements;
  35072. /**
  35073. * Creates a new replacement dataset
  35074. *
  35075. * You can pass in any data set that implements PHPUnit_Extensions_Database_DataSet_IDataSet
  35076. *
  35077. * @param string $delimiter
  35078. * @param string $enclosure
  35079. * @param string $escape
  35080. */
  35081. public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet, Array $fullReplacements = array(), Array $subStrReplacements = array())
  35082. {
  35083. $this->dataSet = $dataSet;
  35084. $this->fullReplacements = $fullReplacements;
  35085. $this->subStrReplacements = $subStrReplacements;
  35086. }
  35087. /**
  35088. * Adds a new full replacement
  35089. *
  35090. * Full replacements will only replace values if the FULL value is a match
  35091. *
  35092. * @param string $value
  35093. * @param string $replacement
  35094. */
  35095. public function addFullReplacement($value, $replacement)
  35096. {
  35097. $this->fullReplacements[$value] = $replacement;
  35098. }
  35099. /**
  35100. * Adds a new substr replacement
  35101. *
  35102. * Substr replacements will replace all occurances of the substr in every column
  35103. *
  35104. * @param string $value
  35105. * @param string $replacement
  35106. */
  35107. public function addSubStrReplacement($value, $replacement)
  35108. {
  35109. $this->subStrReplacements[$value] = $replacement;
  35110. }
  35111. /**
  35112. * Creates an iterator over the tables in the data set. If $reverse is
  35113. * true a reverse iterator will be returned.
  35114. *
  35115. * @param bool $reverse
  35116. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  35117. */
  35118. protected function createIterator($reverse = FALSE)
  35119. {
  35120. $innerIterator = $reverse ? $this->dataSet->getReverseIterator() : $this->dataSet->getIterator();
  35121. return new PHPUnit_Extensions_Database_DataSet_ReplacementTableIterator($innerIterator, $this->fullReplacements, $this->subStrReplacements);
  35122. }
  35123. }
  35124. <?php
  35125. /*
  35126. * This file is part of DBUnit.
  35127. *
  35128. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35129. *
  35130. * For the full copyright and license information, please view the LICENSE
  35131. * file that was distributed with this source code.
  35132. */
  35133. /**
  35134. * Implements the basic functionality of data sets using a PHP array.
  35135. *
  35136. * @package DbUnit
  35137. * @author Richard Brinkman <richardbrinkman@hotmail.com>
  35138. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35139. * @version Release: @package_version@
  35140. * @link http://www.phpunit.de/
  35141. * @since Class available since Release 1.3.2
  35142. */
  35143. class PHPUnit_Extensions_Database_DataSet_ArrayDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  35144. {
  35145. /**
  35146. * @var array
  35147. */
  35148. protected $tables = array();
  35149. /**
  35150. * Constructor to build a new ArrayDataSet with the given array.
  35151. * The array parameter is an associative array of tables where the key is
  35152. * the table name and the value an array of rows. Each row is an associative
  35153. * array by itself with keys representing the field names and the values the
  35154. * actual data.
  35155. * For example:
  35156. * array(
  35157. * "addressbook" => array(
  35158. * array("id" => 1, "name" => "...", "address" => "..."),
  35159. * array("id" => 2, "name" => "...", "address" => "...")
  35160. * )
  35161. * )
  35162. *
  35163. * @param array $data
  35164. */
  35165. public function __construct(array $data)
  35166. {
  35167. foreach ($data AS $tableName => $rows) {
  35168. $columns = array();
  35169. if (isset($rows[0])) {
  35170. $columns = array_keys($rows[0]);
  35171. }
  35172. $metaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns);
  35173. $table = new PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData);
  35174. foreach ($rows AS $row) {
  35175. $table->addRow($row);
  35176. }
  35177. $this->tables[$tableName] = $table;
  35178. }
  35179. }
  35180. protected function createIterator($reverse = FALSE)
  35181. {
  35182. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
  35183. }
  35184. public function getTable($tableName)
  35185. {
  35186. if (!isset($this->tables[$tableName])) {
  35187. throw new InvalidArgumentException("$tableName is not a table in the current database.");
  35188. }
  35189. return $this->tables[$tableName];
  35190. }
  35191. }
  35192. ?><?php
  35193. /*
  35194. * This file is part of DBUnit.
  35195. *
  35196. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35197. *
  35198. * For the full copyright and license information, please view the LICENSE
  35199. * file that was distributed with this source code.
  35200. */
  35201. /**
  35202. * Provides default table functionality.
  35203. *
  35204. * @package DbUnit
  35205. * @author Mike Lively <m@digitalsandwich.com>
  35206. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35207. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35208. * @version Release: @package_version@
  35209. * @link http://www.phpunit.de/
  35210. * @since Class available since Release 1.0.0
  35211. */
  35212. class PHPUnit_Extensions_Database_DataSet_DefaultTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable
  35213. {
  35214. /**
  35215. * Creates a new table object using the given $tableMetaData
  35216. *
  35217. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData
  35218. */
  35219. public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData)
  35220. {
  35221. $this->setTableMetaData($tableMetaData);
  35222. $this->data = array();
  35223. }
  35224. /**
  35225. * Adds a row to the table with optional values.
  35226. *
  35227. * @param array $values
  35228. */
  35229. public function addRow($values = array())
  35230. {
  35231. $this->data[] = array_replace(
  35232. array_fill_keys($this->getTableMetaData()->getColumns(), NULL),
  35233. $values
  35234. );
  35235. }
  35236. /**
  35237. * Adds the rows in the passed table to the current table.
  35238. *
  35239. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  35240. */
  35241. public function addTableRows(PHPUnit_Extensions_Database_DataSet_ITable $table)
  35242. {
  35243. $tableColumns = $this->getTableMetaData()->getColumns();
  35244. $rowCount = $table->getRowCount();
  35245. for ($i = 0; $i < $rowCount; $i++) {
  35246. $newRow = array();
  35247. foreach ($tableColumns as $columnName) {
  35248. $newRow[$columnName] = $table->getValue($i, $columnName);
  35249. }
  35250. $this->addRow($newRow);
  35251. }
  35252. }
  35253. /**
  35254. * Sets the specified column of the specied row to the specified value.
  35255. *
  35256. * @param int $row
  35257. * @param string $column
  35258. * @param mixed $value
  35259. */
  35260. public function setValue($row, $column, $value)
  35261. {
  35262. if (isset($this->data[$row])) {
  35263. $this->data[$row][$column] = $value;
  35264. } else {
  35265. throw new InvalidArgumentException("The row given does not exist.");
  35266. }
  35267. }
  35268. }
  35269. <?php
  35270. /*
  35271. * This file is part of DBUnit.
  35272. *
  35273. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35274. *
  35275. * For the full copyright and license information, please view the LICENSE
  35276. * file that was distributed with this source code.
  35277. */
  35278. /**
  35279. * Provides a basic interface for creating and reading data from data sets.
  35280. *
  35281. * @package DbUnit
  35282. * @author Mike Lively <m@digitalsandwich.com>
  35283. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35284. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35285. * @version Release: @package_version@
  35286. * @link http://www.phpunit.de/
  35287. * @since Class available since Release 1.0.0
  35288. */
  35289. interface PHPUnit_Extensions_Database_DataSet_ITableIterator extends Iterator
  35290. {
  35291. /**
  35292. * Returns the current table.
  35293. *
  35294. * @return PHPUnit_Extensions_Database_DataSet_ITable
  35295. */
  35296. public function getTable();
  35297. /**
  35298. * Returns the current table's meta data.
  35299. *
  35300. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  35301. */
  35302. public function getTableMetaData();
  35303. }
  35304. <?php
  35305. /*
  35306. * This file is part of DBUnit.
  35307. *
  35308. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35309. *
  35310. * For the full copyright and license information, please view the LICENSE
  35311. * file that was distributed with this source code.
  35312. */
  35313. /**
  35314. * The default implementation of a data set.
  35315. *
  35316. * @package DbUnit
  35317. * @author Mike Lively <m@digitalsandwich.com>
  35318. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35319. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35320. * @version Release: @package_version@
  35321. * @link http://www.phpunit.de/
  35322. * @since Class available since Release 1.0.0
  35323. */
  35324. class PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet
  35325. {
  35326. protected function getTableInfo(Array &$tableColumns, Array &$tableValues)
  35327. {
  35328. if ($this->xmlFileContents->getName() != 'dataset') {
  35329. throw new PHPUnit_Extensions_Database_Exception("The root element of a flat xml data set file must be called <dataset>");
  35330. }
  35331. foreach ($this->xmlFileContents->children() as $row) {
  35332. $tableName = $row->getName();
  35333. if (!isset($tableColumns[$tableName])) {
  35334. $tableColumns[$tableName] = array();
  35335. $tableValues[$tableName] = array();
  35336. }
  35337. $values = array();
  35338. foreach ($row->attributes() as $name => $value) {
  35339. if (!in_array($name, $tableColumns[$tableName])) {
  35340. $tableColumns[$tableName][] = $name;
  35341. }
  35342. $values[$name] = $value;
  35343. }
  35344. if (count($values)) {
  35345. $tableValues[$tableName][] = $values;
  35346. }
  35347. }
  35348. }
  35349. public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename)
  35350. {
  35351. $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml();
  35352. $pers->setFileName($filename);
  35353. try {
  35354. $pers->write($dataset);
  35355. } catch (RuntimeException $e) {
  35356. throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.');
  35357. }
  35358. }
  35359. }
  35360. <?php
  35361. /*
  35362. * This file is part of DBUnit.
  35363. *
  35364. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35365. *
  35366. * For the full copyright and license information, please view the LICENSE
  35367. * file that was distributed with this source code.
  35368. */
  35369. /**
  35370. * An interface for persisting datasets
  35371. *
  35372. * @package DbUnit
  35373. * @author Mike Lively <m@digitalsandwich.com>
  35374. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35375. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35376. * @version Release: @package_version@
  35377. * @link http://www.phpunit.de/
  35378. * @since Class available since Release 1.0.0
  35379. */
  35380. interface PHPUnit_Extensions_Database_DataSet_IPersistable
  35381. {
  35382. /**
  35383. * Writes the given dataset
  35384. *
  35385. * The previous dataset will be overwritten.
  35386. *
  35387. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  35388. */
  35389. public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset);
  35390. }
  35391. <?php
  35392. /*
  35393. * This file is part of DBUnit.
  35394. *
  35395. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35396. *
  35397. * For the full copyright and license information, please view the LICENSE
  35398. * file that was distributed with this source code.
  35399. */
  35400. /**
  35401. * The default implementation of a data set.
  35402. *
  35403. * @package DbUnit
  35404. * @author Mike Lively <m@digitalsandwich.com>
  35405. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35406. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35407. * @version Release: @package_version@
  35408. * @link http://www.phpunit.de/
  35409. * @since Class available since Release 1.0.0
  35410. */
  35411. abstract class PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  35412. {
  35413. /**
  35414. * @var array
  35415. */
  35416. protected $tables;
  35417. /**
  35418. * @var SimpleXmlElement
  35419. */
  35420. protected $xmlFileContents;
  35421. /**
  35422. * Creates a new dataset using the given tables.
  35423. *
  35424. * @param array $tables
  35425. */
  35426. public function __construct($xmlFile)
  35427. {
  35428. if (!is_file($xmlFile)) {
  35429. throw new InvalidArgumentException(
  35430. "Could not find xml file: {$xmlFile}"
  35431. );
  35432. }
  35433. $libxmlErrorReporting = libxml_use_internal_errors(TRUE);
  35434. $this->xmlFileContents = simplexml_load_file($xmlFile);
  35435. if (!$this->xmlFileContents) {
  35436. $message = '';
  35437. foreach (libxml_get_errors() as $error) {
  35438. $message .= $error->message;
  35439. }
  35440. throw new RuntimeException($message);
  35441. }
  35442. libxml_clear_errors();
  35443. libxml_use_internal_errors($libxmlErrorReporting);
  35444. $tableColumns = array();
  35445. $tableValues = array();
  35446. $this->getTableInfo($tableColumns, $tableValues);
  35447. $this->createTables($tableColumns, $tableValues);
  35448. }
  35449. /**
  35450. * Reads the simple xml object and creates the appropriate tables and meta
  35451. * data for this dataset.
  35452. */
  35453. protected abstract function getTableInfo(Array &$tableColumns, Array &$tableValues);
  35454. protected function createTables(Array &$tableColumns, Array &$tableValues)
  35455. {
  35456. foreach ($tableValues as $tableName => $values) {
  35457. $table = $this->getOrCreateTable($tableName, $tableColumns[$tableName]);
  35458. foreach ($values as $value) {
  35459. $table->addRow($value);
  35460. }
  35461. }
  35462. }
  35463. /**
  35464. * Returns the table with the matching name. If the table does not exist
  35465. * an empty one is created.
  35466. *
  35467. * @param string $tableName
  35468. * @return PHPUnit_Extensions_Database_DataSet_ITable
  35469. */
  35470. protected function getOrCreateTable($tableName, $tableColumns)
  35471. {
  35472. if (empty($this->tables[$tableName])) {
  35473. $tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $tableColumns);
  35474. $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_DefaultTable($tableMetaData);
  35475. }
  35476. return $this->tables[$tableName];
  35477. }
  35478. /**
  35479. * Creates an iterator over the tables in the data set. If $reverse is
  35480. * true a reverse iterator will be returned.
  35481. *
  35482. * @param bool $reverse
  35483. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  35484. */
  35485. protected function createIterator($reverse = FALSE)
  35486. {
  35487. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
  35488. }
  35489. }
  35490. <?php
  35491. /*
  35492. * This file is part of DBUnit.
  35493. *
  35494. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35495. *
  35496. * For the full copyright and license information, please view the LICENSE
  35497. * file that was distributed with this source code.
  35498. */
  35499. /**
  35500. * A TableMetaData decorator that allows filtering columns from another
  35501. * metaData object.
  35502. *
  35503. * The if a whitelist (include) filter is specified, then only those columns
  35504. * will be included.
  35505. *
  35506. * @package DbUnit
  35507. * @author Mike Lively <m@digitalsandwich.com>
  35508. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35509. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35510. * @version Release: @package_version@
  35511. * @link http://www.phpunit.de/
  35512. * @since Class available since Release 1.0.0
  35513. */
  35514. class PHPUnit_Extensions_Database_DataSet_TableMetaDataFilter extends PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData
  35515. {
  35516. /**
  35517. * The table meta data being decorated.
  35518. * @var PHPUnit_Extensions_Database_DataSet_ITableMetaData
  35519. */
  35520. protected $originalMetaData;
  35521. /**
  35522. * The columns to exclude from the meta data.
  35523. * @var Array
  35524. */
  35525. protected $excludeColumns = array();
  35526. /**
  35527. * The columns to include from the meta data.
  35528. * @var Array
  35529. */
  35530. protected $includeColumns = array();
  35531. /**
  35532. * Creates a new filtered table meta data object filtering out
  35533. * $excludeColumns.
  35534. *
  35535. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $originalMetaData
  35536. * @param array $excludeColumns - Deprecated. Use the set* methods instead.
  35537. */
  35538. public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $originalMetaData, Array $excludeColumns = array())
  35539. {
  35540. $this->originalMetaData = $originalMetaData;
  35541. $this->addExcludeColumns($excludeColumns);
  35542. }
  35543. /**
  35544. * Returns the names of the columns in the table.
  35545. *
  35546. * @return array
  35547. */
  35548. public function getColumns()
  35549. {
  35550. if (!empty($this->includeColumns)) {
  35551. return array_values(array_intersect($this->originalMetaData->getColumns(), $this->includeColumns));
  35552. }
  35553. elseif (!empty($this->excludeColumns)) {
  35554. return array_values(array_diff($this->originalMetaData->getColumns(), $this->excludeColumns));
  35555. }
  35556. else {
  35557. return $this->originalMetaData->getColumns();
  35558. }
  35559. }
  35560. /**
  35561. * Returns the names of the primary key columns in the table.
  35562. *
  35563. * @return array
  35564. */
  35565. public function getPrimaryKeys()
  35566. {
  35567. return $this->originalMetaData->getPrimaryKeys();
  35568. }
  35569. /**
  35570. * Returns the name of the table.
  35571. *
  35572. * @return string
  35573. */
  35574. public function getTableName()
  35575. {
  35576. return $this->originalMetaData->getTableName();
  35577. }
  35578. /**
  35579. * Sets the columns to include in the table.
  35580. * @param Array $includeColumns
  35581. */
  35582. public function addIncludeColumns(Array $includeColumns)
  35583. {
  35584. $this->includeColumns = array_unique(array_merge($this->includeColumns, $includeColumns));
  35585. }
  35586. /**
  35587. * Clears the included columns.
  35588. */
  35589. public function clearIncludeColumns()
  35590. {
  35591. $this->includeColumns = array();
  35592. }
  35593. /**
  35594. * Sets the columns to exclude from the table.
  35595. * @param Array $excludeColumns
  35596. */
  35597. public function addExcludeColumns(Array $excludeColumns)
  35598. {
  35599. $this->excludeColumns = array_unique(array_merge($this->excludeColumns, $excludeColumns));
  35600. }
  35601. /**
  35602. * Clears the excluded columns.
  35603. */
  35604. public function clearExcludeColumns()
  35605. {
  35606. $this->excludeColumns = array();
  35607. }
  35608. }
  35609. <?php
  35610. /*
  35611. * This file is part of DBUnit.
  35612. *
  35613. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35614. *
  35615. * For the full copyright and license information, please view the LICENSE
  35616. * file that was distributed with this source code.
  35617. */
  35618. /**
  35619. * Allows for replacing arbitrary strings in your data sets with other values.
  35620. *
  35621. * @package DbUnit
  35622. * @author Mike Lively <m@digitalsandwich.com>
  35623. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35624. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35625. * @version Release: @package_version@
  35626. * @link http://www.phpunit.de/
  35627. * @since Class available since Release 1.0.0
  35628. * @todo When setTableMetaData() is taken out of the AbstractTable this class should extend AbstractTable.
  35629. */
  35630. class PHPUnit_Extensions_Database_DataSet_ReplacementTable implements PHPUnit_Extensions_Database_DataSet_ITable
  35631. {
  35632. /**
  35633. * @var PHPUnit_Extensions_Database_DataSet_ITable
  35634. */
  35635. protected $table;
  35636. /**
  35637. * @var array
  35638. */
  35639. protected $fullReplacements;
  35640. /**
  35641. * @var array
  35642. */
  35643. protected $subStrReplacements;
  35644. /**
  35645. * Creates a new replacement table
  35646. *
  35647. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  35648. * @param array $fullReplacements
  35649. * @param array $subStrReplacements
  35650. */
  35651. public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $table, Array $fullReplacements = array(), Array $subStrReplacements = array())
  35652. {
  35653. $this->table = $table;
  35654. $this->fullReplacements = $fullReplacements;
  35655. $this->subStrReplacements = $subStrReplacements;
  35656. }
  35657. /**
  35658. * Adds a new full replacement
  35659. *
  35660. * Full replacements will only replace values if the FULL value is a match
  35661. *
  35662. * @param string $value
  35663. * @param string $replacement
  35664. */
  35665. public function addFullReplacement($value, $replacement)
  35666. {
  35667. $this->fullReplacements[$value] = $replacement;
  35668. }
  35669. /**
  35670. * Adds a new substr replacement
  35671. *
  35672. * Substr replacements will replace all occurances of the substr in every column
  35673. *
  35674. * @param string $value
  35675. * @param string $replacement
  35676. */
  35677. public function addSubStrReplacement($value, $replacement)
  35678. {
  35679. $this->subStrReplacements[$value] = $replacement;
  35680. }
  35681. /**
  35682. * Returns the table's meta data.
  35683. *
  35684. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  35685. */
  35686. public function getTableMetaData()
  35687. {
  35688. return $this->table->getTableMetaData();
  35689. }
  35690. /**
  35691. * Returns the number of rows in this table.
  35692. *
  35693. * @return int
  35694. */
  35695. public function getRowCount()
  35696. {
  35697. return $this->table->getRowCount();
  35698. }
  35699. /**
  35700. * Returns the value for the given column on the given row.
  35701. *
  35702. * @param int $row
  35703. * @param int $column
  35704. */
  35705. public function getValue($row, $column)
  35706. {
  35707. return $this->getReplacedValue($this->table->getValue($row, $column));
  35708. }
  35709. /**
  35710. * Returns the an associative array keyed by columns for the given row.
  35711. *
  35712. * @param int $row
  35713. * @return array
  35714. */
  35715. public function getRow($row)
  35716. {
  35717. $row = $this->table->getRow($row);
  35718. return array_map(array($this, 'getReplacedValue'), $row);
  35719. }
  35720. /**
  35721. * Asserts that the given table matches this table.
  35722. *
  35723. * @param PHPUnit_Extensions_Database_DataSet_ITable $other
  35724. */
  35725. public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other)
  35726. {
  35727. $thisMetaData = $this->getTableMetaData();
  35728. $otherMetaData = $other->getTableMetaData();
  35729. if (!$thisMetaData->matches($otherMetaData) ||
  35730. $this->getRowCount() != $other->getRowCount()) {
  35731. return FALSE;
  35732. }
  35733. $columns = $thisMetaData->getColumns();
  35734. $rowCount = $this->getRowCount();
  35735. for ($i = 0; $i < $rowCount; $i++) {
  35736. foreach ($columns as $columnName) {
  35737. $thisValue = $this->getValue($i, $columnName);
  35738. $otherValue = $other->getValue($i, $columnName);
  35739. if (is_numeric($thisValue) && is_numeric($otherValue)) {
  35740. if ($thisValue != $otherValue) {
  35741. return FALSE;
  35742. }
  35743. } elseif ($thisValue !== $otherValue) {
  35744. return FALSE;
  35745. }
  35746. }
  35747. }
  35748. return TRUE;
  35749. }
  35750. public function __toString()
  35751. {
  35752. $columns = $this->getTableMetaData()->getColumns();
  35753. $lineSeperator = str_repeat('+----------------------', count($columns)) . "+\n";
  35754. $lineLength = strlen($lineSeperator) - 1;
  35755. $tableString = $lineSeperator;
  35756. $tableString .= '| ' . str_pad($this->getTableMetaData()->getTableName(), $lineLength - 4, ' ', STR_PAD_RIGHT) . " |\n";
  35757. $tableString .= $lineSeperator;
  35758. $tableString .= $this->rowToString($columns);
  35759. $tableString .= $lineSeperator;
  35760. $rowCount = $this->getRowCount();
  35761. for ($i = 0; $i < $rowCount; $i++) {
  35762. $values = array();
  35763. foreach ($columns as $columnName) {
  35764. $values[] = $this->getValue($i, $columnName);
  35765. }
  35766. $tableString .= $this->rowToString($values);
  35767. $tableString .= $lineSeperator;
  35768. }
  35769. return "\n" . $tableString . "\n";
  35770. }
  35771. protected function rowToString(Array $row)
  35772. {
  35773. $rowString = '';
  35774. foreach ($row as $value) {
  35775. if (is_null($value)) {
  35776. $value = 'NULL';
  35777. }
  35778. $rowString .= '| ' . str_pad(substr($value, 0, 20), 20, ' ', STR_PAD_BOTH) . ' ';
  35779. }
  35780. return $rowString . "|\n";
  35781. }
  35782. protected function getReplacedValue($value)
  35783. {
  35784. if (is_scalar($value) && array_key_exists((string)$value, $this->fullReplacements)) {
  35785. return $this->fullReplacements[$value];
  35786. }
  35787. else if (count($this->subStrReplacements) && isset($value)) {
  35788. return str_replace(array_keys($this->subStrReplacements), array_values($this->subStrReplacements), $value);
  35789. }
  35790. else {
  35791. return $value;
  35792. }
  35793. }
  35794. }
  35795. <?php
  35796. /*
  35797. * This file is part of DBUnit.
  35798. *
  35799. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35800. *
  35801. * For the full copyright and license information, please view the LICENSE
  35802. * file that was distributed with this source code.
  35803. */
  35804. /**
  35805. * Creates DefaultDataSets based off of a spec string.
  35806. *
  35807. * This spec class requires a list of databases to be set to the object before
  35808. * it can return a list of databases.
  35809. *
  35810. * The format of the spec string is as follows:
  35811. *
  35812. * <db label>:<schema>:<table name>:<sql>
  35813. *
  35814. * The db label should be equal to one of the keys in the array of databases
  35815. * passed to setDatabases().
  35816. *
  35817. * The schema should be the primary schema you will be running the sql query
  35818. * against.
  35819. *
  35820. * The table name should be set to what you would like the table name in the
  35821. * dataset to be.
  35822. *
  35823. * The sql is the query you want to use to generate the table columns and data.
  35824. * The column names in the table will be identical to the column aliases in the
  35825. * query.
  35826. *
  35827. * @package DbUnit
  35828. * @author Mike Lively <m@digitalsandwich.com>
  35829. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35830. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35831. * @version Release: @package_version@
  35832. * @link http://www.phpunit.de/
  35833. * @since Class available since Release 1.0.0
  35834. */
  35835. class PHPUnit_Extensions_Database_DataSet_Specs_DbQuery implements PHPUnit_Extensions_Database_DataSet_ISpec, PHPUnit_Extensions_Database_IDatabaseListConsumer
  35836. {
  35837. /**
  35838. * @var array
  35839. */
  35840. protected $databases = array();
  35841. /**
  35842. * Sets the database for the spec
  35843. *
  35844. * @param array $databases
  35845. */
  35846. public function setDatabases(array $databases)
  35847. {
  35848. $this->databases = $databases;
  35849. }
  35850. /**
  35851. * Creates a Default Data Set with a query table from a data set spec.
  35852. *
  35853. * @param string $dataSetSpec
  35854. * @return PHPUnit_Extensions_Database_DataSet_DefaultDataSet
  35855. */
  35856. public function getDataSet($dataSetSpec)
  35857. {
  35858. list($dbLabel, $schema, $table, $sql) = explode(':', $dataSetSpec, 4);
  35859. $databaseInfo = $this->databases[$dbLabel];
  35860. $pdoRflc = new ReflectionClass('PDO');
  35861. $pdo = $pdoRflc->newInstanceArgs(explode('|', $databaseInfo));
  35862. $dbConnection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, $schema);
  35863. $table = $dbConnection->createQueryTable($table, $sql);
  35864. return new PHPUnit_Extensions_Database_DataSet_DefaultDataSet(array($table));
  35865. }
  35866. }
  35867. <?php
  35868. /*
  35869. * This file is part of DBUnit.
  35870. *
  35871. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35872. *
  35873. * For the full copyright and license information, please view the LICENSE
  35874. * file that was distributed with this source code.
  35875. */
  35876. /**
  35877. * Creates a XML dataset based off of a spec string.
  35878. *
  35879. * The format of the spec string is as follows:
  35880. *
  35881. * <filename>
  35882. *
  35883. * The filename should be the location of a xml file relative to the
  35884. * current working directory.
  35885. *
  35886. * @package DbUnit
  35887. * @author Mike Lively <m@digitalsandwich.com>
  35888. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35889. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35890. * @version Release: @package_version@
  35891. * @link http://www.phpunit.de//**
  35892. * @since Class available since Release 1.0.0
  35893. */
  35894. class PHPUnit_Extensions_Database_DataSet_Specs_Xml implements PHPUnit_Extensions_Database_DataSet_ISpec
  35895. {
  35896. /**
  35897. * Creates XML Data Set from a data set spec.
  35898. *
  35899. * @param string $dataSetSpec
  35900. * @return PHPUnit_Extensions_Database_DataSet_XmlDataSet
  35901. */
  35902. public function getDataSet($dataSetSpec)
  35903. {
  35904. return new PHPUnit_Extensions_Database_DataSet_XmlDataSet($dataSetSpec);
  35905. }
  35906. }
  35907. <?php
  35908. /*
  35909. * This file is part of DBUnit.
  35910. *
  35911. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35912. *
  35913. * For the full copyright and license information, please view the LICENSE
  35914. * file that was distributed with this source code.
  35915. */
  35916. /**
  35917. * Creates a FlatXML dataset based off of a spec string.
  35918. *
  35919. * The format of the spec string is as follows:
  35920. *
  35921. * <filename>
  35922. *
  35923. * The filename should be the location of a flat xml file relative to the
  35924. * current working directory.
  35925. *
  35926. * @package DbUnit
  35927. * @author Mike Lively <m@digitalsandwich.com>
  35928. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35929. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35930. * @version Release: @package_version@
  35931. * @link http://www.phpunit.de//**
  35932. * @since Class available since Release 1.0.0
  35933. */
  35934. class PHPUnit_Extensions_Database_DataSet_Specs_FlatXml implements PHPUnit_Extensions_Database_DataSet_ISpec
  35935. {
  35936. /**
  35937. * Creates Flat XML Data Set from a data set spec.
  35938. *
  35939. * @param string $dataSetSpec
  35940. * @return PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet
  35941. */
  35942. public function getDataSet($dataSetSpec)
  35943. {
  35944. return new PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet($dataSetSpec);
  35945. }
  35946. }
  35947. <?php
  35948. /*
  35949. * This file is part of DBUnit.
  35950. *
  35951. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35952. *
  35953. * For the full copyright and license information, please view the LICENSE
  35954. * file that was distributed with this source code.
  35955. */
  35956. /**
  35957. * Creates a YAML dataset based off of a spec string.
  35958. *
  35959. * The format of the spec string is as follows:
  35960. *
  35961. * <filename>
  35962. *
  35963. * The filename should be the location of a yaml file relative to the
  35964. * current working directory.
  35965. *
  35966. * @package DbUnit
  35967. * @author Mike Lively <m@digitalsandwich.com>
  35968. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35969. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35970. * @version Release: @package_version@
  35971. * @link http://www.phpunit.de//**
  35972. * @since Class available since Release 1.0.0
  35973. */
  35974. class PHPUnit_Extensions_Database_DataSet_Specs_Yaml implements PHPUnit_Extensions_Database_DataSet_ISpec
  35975. {
  35976. /**
  35977. * Creates YAML Data Set from a data set spec.
  35978. *
  35979. * @param string $dataSetSpec
  35980. * @return PHPUnit_Extensions_Database_DataSet_YamlDataSet
  35981. */
  35982. public function getDataSet($dataSetSpec)
  35983. {
  35984. return new PHPUnit_Extensions_Database_DataSet_YamlDataSet($dataSetSpec);
  35985. }
  35986. }
  35987. <?php
  35988. /*
  35989. * This file is part of DBUnit.
  35990. *
  35991. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35992. *
  35993. * For the full copyright and license information, please view the LICENSE
  35994. * file that was distributed with this source code.
  35995. */
  35996. /**
  35997. * An interface for data set spec factories.
  35998. *
  35999. * @package DbUnit
  36000. * @author Mike Lively <m@digitalsandwich.com>
  36001. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36002. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36003. * @version Release: @package_version@
  36004. * @link http://www.phpunit.de//**
  36005. * @since Class available since Release 1.0.0
  36006. */
  36007. interface PHPUnit_Extensions_Database_DataSet_Specs_IFactory
  36008. {
  36009. /**
  36010. * Returns the data set
  36011. *
  36012. * @param string $type
  36013. * @return PHPUnit_Extensions_Database_DataSet_ISpec
  36014. */
  36015. public function getDataSetSpecByType($type);
  36016. }
  36017. <?php
  36018. /*
  36019. * This file is part of DBUnit.
  36020. *
  36021. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36022. *
  36023. * For the full copyright and license information, please view the LICENSE
  36024. * file that was distributed with this source code.
  36025. */
  36026. /**
  36027. * Creates CsvDataSets based off of a spec string.
  36028. *
  36029. * The format of the spec string is as follows:
  36030. *
  36031. * <csv options>|table1:filename.csv,table2:filename2.csv
  36032. *
  36033. * The first portion of the spec including the pipe symbol '|' is optional.
  36034. * If the pipe option is included than it may be preceded by up to four
  36035. * characters specifying values for the following arguments in order:
  36036. * delimiter (defaults to ',',) enclosure (defaults to '"',) escape (defaults to '"',).
  36037. *
  36038. * Any additional characters in the csv options will be discarded.
  36039. *
  36040. * @package DbUnit
  36041. * @author Mike Lively <m@digitalsandwich.com>
  36042. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36043. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36044. * @version Release: @package_version@
  36045. * @link http://www.phpunit.de/
  36046. * @since Class available since Release 1.0.0
  36047. */
  36048. class PHPUnit_Extensions_Database_DataSet_Specs_Csv implements PHPUnit_Extensions_Database_DataSet_ISpec
  36049. {
  36050. /**
  36051. * Creates CSV Data Set from a data set spec.
  36052. *
  36053. * @param string $dataSetSpec
  36054. * @return PHPUnit_Extensions_Database_DataSet_CsvDataSet
  36055. */
  36056. public function getDataSet($dataSetSpec)
  36057. {
  36058. $csvDataSetArgs = $this->getCsvOptions($dataSetSpec);
  36059. $csvDataSetRfl = new ReflectionClass('PHPUnit_Extensions_Database_DataSet_CsvDataSet');
  36060. $csvDataSet = $csvDataSetRfl->newInstanceArgs($csvDataSetArgs);
  36061. foreach ($this->getTableFileMap($dataSetSpec) as $tableName => $file) {
  36062. $csvDataSet->addTable($tableName, $file);
  36063. }
  36064. return $csvDataSet;
  36065. }
  36066. /**
  36067. * Returns CSV options.
  36068. *
  36069. * Returns an array containing the options that will be passed to the
  36070. * PHPUnit_Extensions_Database_DataSet_CsvDataSet constructor. The options
  36071. * are determined by the given $dataSetSpec.
  36072. *
  36073. * @param string $dataSetSpec
  36074. * @return array
  36075. */
  36076. protected function getCsvOptions($dataSetSpec)
  36077. {
  36078. list($csvOptStr, ) = explode('|', $dataSetSpec, 2);
  36079. return str_split($csvOptStr);
  36080. }
  36081. /**
  36082. * Returns map of tables to files.
  36083. *
  36084. * Returns an associative array containing a mapping of tables (the key)
  36085. * to files (the values.) The tables and files are determined by the given
  36086. * $dataSetSpec
  36087. *
  36088. * @param string $dataSetSpec
  36089. * @return array
  36090. */
  36091. protected function getTableFileMap($dataSetSpec)
  36092. {
  36093. $tables = array();
  36094. foreach (explode(',', $dataSetSpec) as $csvfile) {
  36095. list($tableName, $file) = explode(':', $csvfile, 2);
  36096. $tables[$tableName] = $file;
  36097. }
  36098. return $tables;
  36099. }
  36100. }
  36101. <?php
  36102. /*
  36103. * This file is part of DBUnit.
  36104. *
  36105. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36106. *
  36107. * For the full copyright and license information, please view the LICENSE
  36108. * file that was distributed with this source code.
  36109. */
  36110. /**
  36111. * Creates a database dataset based off of a spec string.
  36112. *
  36113. * This spec class requires a list of databases to be set to the object before
  36114. * it can return a list of databases.
  36115. *
  36116. * The format of the spec string is as follows:
  36117. *
  36118. * <db label>:<schema>:<tables>
  36119. *
  36120. * The db label should be equal to one of the keys in the array of databases
  36121. * passed to setDatabases().
  36122. *
  36123. * The schema should be the primary schema you will be choosing tables from.
  36124. *
  36125. * The tables should be a comma delimited list of all tables you would like to
  36126. * pull data from.
  36127. *
  36128. * The sql is the query you want to use to generate the table columns and data.
  36129. * The column names in the table will be identical to the column aliases in the
  36130. * query.
  36131. *
  36132. * @package DbUnit
  36133. * @author Mike Lively <m@digitalsandwich.com>
  36134. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36135. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36136. * @version Release: @package_version@
  36137. * @link http://www.phpunit.de//**
  36138. * @since Class available since Release 1.0.0
  36139. */
  36140. class PHPUnit_Extensions_Database_DataSet_Specs_DbTable implements PHPUnit_Extensions_Database_DataSet_ISpec, PHPUnit_Extensions_Database_IDatabaseListConsumer
  36141. {
  36142. /**
  36143. * @var array
  36144. */
  36145. protected $databases = array();
  36146. /**
  36147. * Sets the database for the spec
  36148. *
  36149. * @param array $databases
  36150. */
  36151. public function setDatabases(array $databases)
  36152. {
  36153. $this->databases = $databases;
  36154. }
  36155. /**
  36156. * Creates a DB Data Set from a data set spec.
  36157. *
  36158. * @param string $dataSetSpec
  36159. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  36160. */
  36161. public function getDataSet($dataSetSpec)
  36162. {
  36163. list($dbLabel, $schema, $tables) = explode(':', $dataSetSpec, 3);
  36164. $databaseInfo = $this->databases[$dbLabel];
  36165. $pdoRflc = new ReflectionClass('PDO');
  36166. $pdo = $pdoRflc->newInstanceArgs(explode('|', $databaseInfo));
  36167. $dbConnection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, $schema);
  36168. return !empty($tables) ? $dbConnection->createDataSet(explode(',', $tables)) : $dbConnection->createDataSet();
  36169. }
  36170. }
  36171. <?php
  36172. /*
  36173. * This file is part of DBUnit.
  36174. *
  36175. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36176. *
  36177. * For the full copyright and license information, please view the LICENSE
  36178. * file that was distributed with this source code.
  36179. */
  36180. /**
  36181. * Creates the appropriate DataSet Spec based on a given type.
  36182. *
  36183. * @package DbUnit
  36184. * @author Mike Lively <m@digitalsandwich.com>
  36185. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36186. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36187. * @version Release: @package_version@
  36188. * @link http://www.phpunit.de//**
  36189. * @since Class available since Release 1.0.0
  36190. */
  36191. class PHPUnit_Extensions_Database_DataSet_Specs_Factory implements PHPUnit_Extensions_Database_DataSet_Specs_IFactory
  36192. {
  36193. /**
  36194. * Returns the data set
  36195. *
  36196. * @param string $type
  36197. * @return PHPUnit_Extensions_Database_DataSet_ISpec
  36198. */
  36199. public function getDataSetSpecByType($type)
  36200. {
  36201. switch ($type) {
  36202. case 'xml':
  36203. return new PHPUnit_Extensions_Database_DataSet_Specs_Xml();
  36204. case 'flatxml':
  36205. return new PHPUnit_Extensions_Database_DataSet_Specs_FlatXml();
  36206. case 'csv':
  36207. return new PHPUnit_Extensions_Database_DataSet_Specs_Csv();
  36208. case 'yaml':
  36209. return new PHPUnit_Extensions_Database_DataSet_Specs_Yaml();
  36210. case 'dbtable':
  36211. return new PHPUnit_Extensions_Database_DataSet_Specs_DbTable();
  36212. case 'dbquery':
  36213. return new PHPUnit_Extensions_Database_DataSet_Specs_DbQuery();
  36214. default:
  36215. throw new PHPUnit_Extensions_Database_Exception("I don't know what you want from me.");
  36216. }
  36217. }
  36218. }
  36219. <?php
  36220. /*
  36221. * This file is part of DBUnit.
  36222. *
  36223. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36224. *
  36225. * For the full copyright and license information, please view the LICENSE
  36226. * file that was distributed with this source code.
  36227. */
  36228. /**
  36229. * Provides the functionality to represent a database table.
  36230. *
  36231. * @package DbUnit
  36232. * @author Mike Lively <m@digitalsandwich.com>
  36233. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36234. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36235. * @version Release: @package_version@
  36236. * @link http://www.phpunit.de/
  36237. * @since Class available since Release 1.0.0
  36238. */
  36239. class PHPUnit_Extensions_Database_DataSet_QueryTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable
  36240. {
  36241. /**
  36242. * @var string
  36243. */
  36244. protected $query;
  36245. /**
  36246. * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection
  36247. */
  36248. protected $databaseConnection;
  36249. /**
  36250. * @var string
  36251. */
  36252. protected $tableName;
  36253. /**
  36254. * Creates a new database query table object.
  36255. *
  36256. * @param string $table_name
  36257. * @param string $query
  36258. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection
  36259. */
  36260. public function __construct($tableName, $query, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection)
  36261. {
  36262. $this->query = $query;
  36263. $this->databaseConnection = $databaseConnection;
  36264. $this->tableName = $tableName;
  36265. }
  36266. /**
  36267. * Returns the table's meta data.
  36268. *
  36269. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  36270. */
  36271. public function getTableMetaData()
  36272. {
  36273. $this->createTableMetaData();
  36274. return parent::getTableMetaData();
  36275. }
  36276. /**
  36277. * Checks if a given row is in the table
  36278. *
  36279. * @param array $row
  36280. *
  36281. * @return bool
  36282. */
  36283. public function assertContainsRow(Array $row)
  36284. {
  36285. $this->loadData();
  36286. return parent::assertContainsRow($row);
  36287. }
  36288. /**
  36289. * Returns the number of rows in this table.
  36290. *
  36291. * @return int
  36292. */
  36293. public function getRowCount()
  36294. {
  36295. $this->loadData();
  36296. return parent::getRowCount();
  36297. }
  36298. /**
  36299. * Returns the value for the given column on the given row.
  36300. *
  36301. * @param int $row
  36302. * @param int $column
  36303. */
  36304. public function getValue($row, $column)
  36305. {
  36306. $this->loadData();
  36307. return parent::getValue($row, $column);
  36308. }
  36309. /**
  36310. * Returns the an associative array keyed by columns for the given row.
  36311. *
  36312. * @param int $row
  36313. * @return array
  36314. */
  36315. public function getRow($row)
  36316. {
  36317. $this->loadData();
  36318. return parent::getRow($row);
  36319. }
  36320. /**
  36321. * Asserts that the given table matches this table.
  36322. *
  36323. * @param PHPUnit_Extensions_Database_DataSet_ITable $other
  36324. */
  36325. public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other)
  36326. {
  36327. $this->loadData();
  36328. return parent::matches($other);
  36329. }
  36330. protected function loadData()
  36331. {
  36332. if ($this->data === NULL) {
  36333. $pdoStatement = $this->databaseConnection->getConnection()->query($this->query);
  36334. $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC);
  36335. }
  36336. }
  36337. protected function createTableMetaData()
  36338. {
  36339. if ($this->tableMetaData === NULL)
  36340. {
  36341. $this->loadData();
  36342. // if some rows are in the table
  36343. $columns = array();
  36344. if (isset($this->data[0]))
  36345. // get column names from data
  36346. $columns = array_keys($this->data[0]);
  36347. else {
  36348. // if no rows found, get column names from database
  36349. $pdoStatement = $this->databaseConnection->getConnection()->prepare("SELECT column_name FROM information_schema.COLUMNS WHERE table_schema=:schema AND table_name=:table");
  36350. $pdoStatement->execute(array(
  36351. "table" => $this->tableName,
  36352. "schema" => $this->databaseConnection->getSchema()
  36353. ));
  36354. $columns = $pdoStatement->fetchAll(PDO::FETCH_COLUMN, 0);
  36355. }
  36356. // create metadata
  36357. $this->tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($this->tableName, $columns);
  36358. }
  36359. }
  36360. }
  36361. <?php
  36362. /*
  36363. * This file is part of DBUnit.
  36364. *
  36365. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36366. *
  36367. * For the full copyright and license information, please view the LICENSE
  36368. * file that was distributed with this source code.
  36369. */
  36370. /**
  36371. * Provides a basic functionality for dbunit tables
  36372. *
  36373. * @package DbUnit
  36374. * @author Mike Lively <m@digitalsandwich.com>
  36375. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36376. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36377. * @version Release: @package_version@
  36378. * @link http://www.phpunit.de/
  36379. * @since Class available since Release 1.0.0
  36380. */
  36381. class PHPUnit_Extensions_Database_DataSet_AbstractTable implements PHPUnit_Extensions_Database_DataSet_ITable
  36382. {
  36383. /**
  36384. * @var PHPUnit_Extensions_Database_DataSet_ITableMetaData
  36385. */
  36386. protected $tableMetaData;
  36387. /**
  36388. * A 2-dimensional array containing the data for this table.
  36389. *
  36390. * @var array
  36391. */
  36392. protected $data;
  36393. /**
  36394. * @var PHPUnit_Extensions_Database_DataSet_ITable|null
  36395. */
  36396. private $other;
  36397. /**
  36398. * Sets the metadata for this table.
  36399. *
  36400. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData
  36401. * @deprecated
  36402. */
  36403. protected function setTableMetaData(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData)
  36404. {
  36405. $this->tableMetaData = $tableMetaData;
  36406. }
  36407. /**
  36408. * Returns the table's meta data.
  36409. *
  36410. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  36411. */
  36412. public function getTableMetaData()
  36413. {
  36414. return $this->tableMetaData;
  36415. }
  36416. /**
  36417. * Returns the number of rows in this table.
  36418. *
  36419. * @return int
  36420. */
  36421. public function getRowCount()
  36422. {
  36423. return count($this->data);
  36424. }
  36425. /**
  36426. * Returns the value for the given column on the given row.
  36427. *
  36428. * @param int $row
  36429. * @param int $column
  36430. * @todo reorganize this function to throw the exception first.
  36431. */
  36432. public function getValue($row, $column)
  36433. {
  36434. if (isset($this->data[$row][$column])) {
  36435. $value = $this->data[$row][$column];
  36436. return ($value instanceof SimpleXMLElement) ? (string) $value : $value;
  36437. } else {
  36438. if (!in_array($column, $this->getTableMetaData()->getColumns()) || $this->getRowCount() <= $row) {
  36439. throw new InvalidArgumentException("The given row ({$row}) and column ({$column}) do not exist in table {$this->getTableMetaData()->getTableName()}");
  36440. } else {
  36441. return NULL;
  36442. }
  36443. }
  36444. }
  36445. /**
  36446. * Returns the an associative array keyed by columns for the given row.
  36447. *
  36448. * @param int $row
  36449. * @return array
  36450. */
  36451. public function getRow($row)
  36452. {
  36453. if (isset($this->data[$row])) {
  36454. return $this->data[$row];
  36455. } else {
  36456. if ($this->getRowCount() <= $row) {
  36457. throw new InvalidArgumentException("The given row ({$row}) does not exist in table {$this->getTableMetaData()->getTableName()}");
  36458. } else {
  36459. return NULL;
  36460. }
  36461. }
  36462. }
  36463. /**
  36464. * Asserts that the given table matches this table.
  36465. *
  36466. * @param PHPUnit_Extensions_Database_DataSet_ITable $other
  36467. */
  36468. public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other)
  36469. {
  36470. $thisMetaData = $this->getTableMetaData();
  36471. $otherMetaData = $other->getTableMetaData();
  36472. if (!$thisMetaData->matches($otherMetaData) ||
  36473. $this->getRowCount() != $other->getRowCount()) {
  36474. return FALSE;
  36475. }
  36476. $columns = $thisMetaData->getColumns();
  36477. $rowCount = $this->getRowCount();
  36478. for ($i = 0; $i < $rowCount; $i++) {
  36479. foreach ($columns as $columnName) {
  36480. $thisValue = $this->getValue($i, $columnName);
  36481. $otherValue = $other->getValue($i, $columnName);
  36482. if (is_numeric($thisValue) && is_numeric($otherValue)) {
  36483. if ($thisValue != $otherValue) {
  36484. $this->other = $other;
  36485. return FALSE;
  36486. }
  36487. } elseif ($thisValue !== $otherValue) {
  36488. $this->other = $other;
  36489. return FALSE;
  36490. }
  36491. }
  36492. }
  36493. return TRUE;
  36494. }
  36495. /**
  36496. * Checks if a given row is in the table
  36497. *
  36498. * @param array $row
  36499. *
  36500. * @return bool
  36501. */
  36502. public function assertContainsRow(array $row)
  36503. {
  36504. return in_array($row, $this->data);
  36505. }
  36506. public function __toString()
  36507. {
  36508. $columns = $this->getTableMetaData()->getColumns();
  36509. $lineSeperator = str_repeat('+----------------------', count($columns)) . "+\n";
  36510. $lineLength = strlen($lineSeperator) - 1;
  36511. $tableString = $lineSeperator;
  36512. $tableString .= '| ' . str_pad($this->getTableMetaData()->getTableName(), $lineLength - 4, ' ', STR_PAD_RIGHT) . " |\n";
  36513. $tableString .= $lineSeperator;
  36514. $tableString .= $this->rowToString($columns);
  36515. $tableString .= $lineSeperator;
  36516. $rowCount = $this->getRowCount();
  36517. for ($i = 0; $i < $rowCount; $i++) {
  36518. $values = array();
  36519. foreach ($columns as $columnName) {
  36520. if ($this->other) {
  36521. try {
  36522. if ($this->getValue($i, $columnName) != $this->other->getValue($i, $columnName)) {
  36523. $values[] = sprintf(
  36524. '%s != actual %s',
  36525. var_export($this->getValue($i, $columnName), TRUE),
  36526. var_export($this->other->getValue($i, $columnName), TRUE)
  36527. );
  36528. } else {
  36529. $values[] = $this->getValue($i, $columnName);
  36530. }
  36531. } catch (\InvalidArgumentException $ex) {
  36532. $values[] = $this->getValue($i, $columnName) . ': no row';
  36533. }
  36534. } else {
  36535. $values[] = $this->getValue($i, $columnName);
  36536. }
  36537. }
  36538. $tableString .= $this->rowToString($values) . $lineSeperator;
  36539. }
  36540. return ($this->other ? '(table diff enabled)' : '') . "\n" . $tableString . "\n";
  36541. }
  36542. protected function rowToString(Array $row)
  36543. {
  36544. $rowString = '';
  36545. foreach ($row as $value) {
  36546. if (is_null($value)) {
  36547. $value = 'NULL';
  36548. }
  36549. $rowString .= '| ' . str_pad(substr($value, 0, 20), 20, ' ', STR_PAD_BOTH) . ' ';
  36550. }
  36551. return $rowString . "|\n";
  36552. }
  36553. }
  36554. <?php
  36555. /*
  36556. * This file is part of DBUnit.
  36557. *
  36558. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36559. *
  36560. * For the full copyright and license information, please view the LICENSE
  36561. * file that was distributed with this source code.
  36562. */
  36563. /**
  36564. * Provides a basic interface for creating and reading data from data sets.
  36565. *
  36566. * @package DbUnit
  36567. * @author Mike Lively <m@digitalsandwich.com>
  36568. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36569. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36570. * @version Release: @package_version@
  36571. * @link http://www.phpunit.de/
  36572. * @since Class available since Release 1.0.0
  36573. */
  36574. interface PHPUnit_Extensions_Database_DataSet_ITable
  36575. {
  36576. /**
  36577. * Returns the table's meta data.
  36578. *
  36579. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  36580. */
  36581. public function getTableMetaData();
  36582. /**
  36583. * Returns the number of rows in this table.
  36584. *
  36585. * @return int
  36586. */
  36587. public function getRowCount();
  36588. /**
  36589. * Returns the value for the given column on the given row.
  36590. *
  36591. * @param int $row
  36592. * @param int $column
  36593. */
  36594. public function getValue($row, $column);
  36595. /**
  36596. * Returns the an associative array keyed by columns for the given row.
  36597. *
  36598. * @param int $row
  36599. * @return array
  36600. */
  36601. public function getRow($row);
  36602. /**
  36603. * Asserts that the given table matches this table.
  36604. *
  36605. * @param PHPUnit_Extensions_Database_DataSet_ITable $other
  36606. */
  36607. public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other);
  36608. }
  36609. <?php
  36610. /*
  36611. * This file is part of DBUnit.
  36612. *
  36613. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36614. *
  36615. * For the full copyright and license information, please view the LICENSE
  36616. * file that was distributed with this source code.
  36617. */
  36618. /**
  36619. * The default implementation of table meta data
  36620. *
  36621. * @package DbUnit
  36622. * @author Mike Lively <m@digitalsandwich.com>
  36623. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36624. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36625. * @version Release: @package_version@
  36626. * @link http://www.phpunit.de/
  36627. * @since Class available since Release 1.0.0
  36628. */
  36629. class PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData extends PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData
  36630. {
  36631. /**
  36632. * Creates a new default table meta data object.
  36633. *
  36634. * @param string $tableName
  36635. * @param array $columns
  36636. * @param array $primaryKeys
  36637. */
  36638. public function __construct($tableName, Array $columns, Array $primaryKeys = array())
  36639. {
  36640. $this->tableName = $tableName;
  36641. $this->columns = $columns;
  36642. $this->primaryKeys = array();
  36643. foreach ($primaryKeys as $columnName) {
  36644. if (!in_array($columnName, $this->columns)) {
  36645. throw new InvalidArgumentException("Primary key column passed that is not in the column list.");
  36646. } else {
  36647. $this->primaryKeys[] = $columnName;
  36648. }
  36649. }
  36650. }
  36651. }
  36652. <?php
  36653. declare(ticks = 1);
  36654. /**
  36655. * PHP_Invoker
  36656. *
  36657. * Copyright (c) 2011-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  36658. * All rights reserved.
  36659. *
  36660. * Redistribution and use in source and binary forms, with or without
  36661. * modification, are permitted provided that the following conditions
  36662. * are met:
  36663. *
  36664. * * Redistributions of source code must retain the above copyright
  36665. * notice, this list of conditions and the following disclaimer.
  36666. *
  36667. * * Redistributions in binary form must reproduce the above copyright
  36668. * notice, this list of conditions and the following disclaimer in
  36669. * the documentation and/or other materials provided with the
  36670. * distribution.
  36671. *
  36672. * * Neither the name of Sebastian Bergmann nor the names of his
  36673. * contributors may be used to endorse or promote products derived
  36674. * from this software without specific prior written permission.
  36675. *
  36676. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  36677. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  36678. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  36679. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  36680. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  36681. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  36682. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36683. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  36684. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36685. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  36686. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36687. * POSSIBILITY OF SUCH DAMAGE.
  36688. *
  36689. * @package PHP
  36690. * @subpackage Invoker
  36691. * @author Sebastian Bergmann <sebastian@phpunit.de>
  36692. * @copyright 2011-2013 Sebastian Bergmann <sebastian@phpunit.de>
  36693. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36694. * @link http://github.com/sebastianbergmann/php-invoker
  36695. * @since File available since Release 1.0.0
  36696. */
  36697. /**
  36698. * Utility class for invoking callables with a timeout.
  36699. *
  36700. * @package PHP
  36701. * @subpackage Invoker
  36702. * @author Sebastian Bergmann <sebastian@phpunit.de>
  36703. * @copyright 2011-2013 Sebastian Bergmann <sebastian@phpunit.de>
  36704. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36705. * @version Release: @package_version@
  36706. * @link http://github.com/sebastianbergmann/php-invoker
  36707. * @since Class available since Release 1.0.0
  36708. */
  36709. class PHP_Invoker
  36710. {
  36711. /**
  36712. * @var integer
  36713. */
  36714. protected $timeout;
  36715. /**
  36716. * Invokes a callable and raises an exception when the execution does not
  36717. * finish before the specified timeout.
  36718. *
  36719. * @param callable $callable
  36720. * @param array $arguments
  36721. * @param integer $timeout in seconds
  36722. * @return mixed
  36723. * @throws InvalidArgumentException
  36724. */
  36725. public function invoke($callable, array $arguments, $timeout)
  36726. {
  36727. if (!is_callable($callable)) {
  36728. throw new InvalidArgumentException;
  36729. }
  36730. if (!is_integer($timeout)) {
  36731. throw new InvalidArgumentException;
  36732. }
  36733. pcntl_signal(SIGALRM, array($this, 'callback'), TRUE);
  36734. pcntl_alarm($timeout);
  36735. $this->timeout = $timeout;
  36736. try {
  36737. $result = call_user_func_array($callable, $arguments);
  36738. }
  36739. catch (Exception $e) {
  36740. pcntl_alarm(0);
  36741. throw $e;
  36742. }
  36743. pcntl_alarm(0);
  36744. return $result;
  36745. }
  36746. /**
  36747. * Invoked by pcntl_signal() when a SIGALRM occurs.
  36748. */
  36749. public function callback()
  36750. {
  36751. throw new PHP_Invoker_TimeoutException(
  36752. sprintf(
  36753. 'Execution aborted after %s',
  36754. PHP_Timer::secondsToTimeString($this->timeout)
  36755. )
  36756. );
  36757. }
  36758. }
  36759. <?php
  36760. /**
  36761. * PHP_Invoker
  36762. *
  36763. * Copyright (c) 2011-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  36764. * All rights reserved.
  36765. *
  36766. * Redistribution and use in source and binary forms, with or without
  36767. * modification, are permitted provided that the following conditions
  36768. * are met:
  36769. *
  36770. * * Redistributions of source code must retain the above copyright
  36771. * notice, this list of conditions and the following disclaimer.
  36772. *
  36773. * * Redistributions in binary form must reproduce the above copyright
  36774. * notice, this list of conditions and the following disclaimer in
  36775. * the documentation and/or other materials provided with the
  36776. * distribution.
  36777. *
  36778. * * Neither the name of Sebastian Bergmann nor the names of his
  36779. * contributors may be used to endorse or promote products derived
  36780. * from this software without specific prior written permission.
  36781. *
  36782. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  36783. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  36784. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  36785. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  36786. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  36787. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  36788. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36789. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  36790. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36791. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  36792. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36793. * POSSIBILITY OF SUCH DAMAGE.
  36794. *
  36795. * @package PHP
  36796. * @subpackage Invoker
  36797. * @author Sebastian Bergmann <sebastian@phpunit.de>
  36798. * @copyright 2011-2013 Sebastian Bergmann <sebastian@phpunit.de>
  36799. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36800. * @link http://github.com/sebastianbergmann/php-invoker
  36801. * @since File available since Release 1.0.0
  36802. */
  36803. /**
  36804. * @package PHP
  36805. * @subpackage Invoker
  36806. * @author Sebastian Bergmann <sebastian@phpunit.de>
  36807. * @copyright 2011-2013 Sebastian Bergmann <sebastian@phpunit.de>
  36808. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36809. * @version Release: @package_version@
  36810. * @link http://github.com/sebastianbergmann/php-invoker
  36811. * @since Class available since Release 1.0.0
  36812. */
  36813. class PHP_Invoker_TimeoutException extends RuntimeException
  36814. {
  36815. }
  36816. PHPUnit_MockObject
  36817. Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  36818. All rights reserved.
  36819. Redistribution and use in source and binary forms, with or without
  36820. modification, are permitted provided that the following conditions
  36821. are met:
  36822. * Redistributions of source code must retain the above copyright
  36823. notice, this list of conditions and the following disclaimer.
  36824. * Redistributions in binary form must reproduce the above copyright
  36825. notice, this list of conditions and the following disclaimer in
  36826. the documentation and/or other materials provided with the
  36827. distribution.
  36828. * Neither the name of Sebastian Bergmann nor the names of his
  36829. contributors may be used to endorse or promote products derived
  36830. from this software without specific prior written permission.
  36831. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  36832. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  36833. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  36834. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  36835. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  36836. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  36837. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36838. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  36839. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36840. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  36841. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36842. POSSIBILITY OF SUCH DAMAGE.
  36843. <?php
  36844. /*
  36845. * This file is part of the PHPUnit_MockObject package.
  36846. *
  36847. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36848. *
  36849. * For the full copyright and license information, please view the LICENSE
  36850. * file that was distributed with this source code.
  36851. */
  36852. /**
  36853. * Main matcher which defines a full expectation using method, parameter and
  36854. * invocation matchers.
  36855. * This matcher encapsulates all the other matchers and allows the builder to
  36856. * set the specific matchers when the appropriate methods are called (once(),
  36857. * where() etc.).
  36858. *
  36859. * All properties are public so that they can easily be accessed by the builder.
  36860. *
  36861. * @package PHPUnit_MockObject
  36862. * @author Sebastian Bergmann <sebastian@phpunit.de>
  36863. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  36864. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36865. * @version Release: @package_version@
  36866. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  36867. * @since Class available since Release 1.0.0
  36868. */
  36869. class PHPUnit_Framework_MockObject_Matcher implements PHPUnit_Framework_MockObject_Matcher_Invocation
  36870. {
  36871. /**
  36872. * @var PHPUnit_Framework_MockObject_Matcher_Invocation
  36873. */
  36874. public $invocationMatcher;
  36875. /**
  36876. * @var mixed
  36877. */
  36878. public $afterMatchBuilderId = null;
  36879. /**
  36880. * @var boolean
  36881. */
  36882. public $afterMatchBuilderIsInvoked = false;
  36883. /**
  36884. * @var PHPUnit_Framework_MockObject_Matcher_MethodName
  36885. */
  36886. public $methodNameMatcher = null;
  36887. /**
  36888. * @var PHPUnit_Framework_MockObject_Matcher_Parameters
  36889. */
  36890. public $parametersMatcher = null;
  36891. /**
  36892. * @var PHPUnit_Framework_MockObject_Stub
  36893. */
  36894. public $stub = null;
  36895. /**
  36896. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher
  36897. */
  36898. public function __construct(PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher)
  36899. {
  36900. $this->invocationMatcher = $invocationMatcher;
  36901. }
  36902. /**
  36903. * @return string
  36904. */
  36905. public function toString()
  36906. {
  36907. $list = array();
  36908. if ($this->invocationMatcher !== null) {
  36909. $list[] = $this->invocationMatcher->toString();
  36910. }
  36911. if ($this->methodNameMatcher !== null) {
  36912. $list[] = 'where ' . $this->methodNameMatcher->toString();
  36913. }
  36914. if ($this->parametersMatcher !== null) {
  36915. $list[] = 'and ' . $this->parametersMatcher->toString();
  36916. }
  36917. if ($this->afterMatchBuilderId !== null) {
  36918. $list[] = 'after ' . $this->afterMatchBuilderId;
  36919. }
  36920. if ($this->stub !== null) {
  36921. $list[] = 'will ' . $this->stub->toString();
  36922. }
  36923. return join(' ', $list);
  36924. }
  36925. /**
  36926. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  36927. * @return mixed
  36928. */
  36929. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
  36930. {
  36931. if ($this->invocationMatcher === null) {
  36932. throw new PHPUnit_Framework_Exception(
  36933. 'No invocation matcher is set'
  36934. );
  36935. }
  36936. if ($this->methodNameMatcher === null) {
  36937. throw new PHPUnit_Framework_Exception('No method matcher is set');
  36938. }
  36939. if ($this->afterMatchBuilderId !== null) {
  36940. $builder = $invocation->object
  36941. ->__phpunit_getInvocationMocker()
  36942. ->lookupId($this->afterMatchBuilderId);
  36943. if (!$builder) {
  36944. throw new PHPUnit_Framework_Exception(
  36945. sprintf(
  36946. 'No builder found for match builder identification <%s>',
  36947. $this->afterMatchBuilderId
  36948. )
  36949. );
  36950. }
  36951. $matcher = $builder->getMatcher();
  36952. if ($matcher && $matcher->invocationMatcher->hasBeenInvoked()) {
  36953. $this->afterMatchBuilderIsInvoked = true;
  36954. }
  36955. }
  36956. $this->invocationMatcher->invoked($invocation);
  36957. try {
  36958. if ($this->parametersMatcher !== null &&
  36959. !$this->parametersMatcher->matches($invocation)) {
  36960. $this->parametersMatcher->verify();
  36961. }
  36962. } catch (PHPUnit_Framework_ExpectationFailedException $e) {
  36963. throw new PHPUnit_Framework_ExpectationFailedException(
  36964. sprintf(
  36965. "Expectation failed for %s when %s\n%s",
  36966. $this->methodNameMatcher->toString(),
  36967. $this->invocationMatcher->toString(),
  36968. $e->getMessage()
  36969. ),
  36970. $e->getComparisonFailure()
  36971. );
  36972. }
  36973. if ($this->stub) {
  36974. return $this->stub->invoke($invocation);
  36975. }
  36976. return null;
  36977. }
  36978. /**
  36979. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  36980. * @return boolean
  36981. */
  36982. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  36983. {
  36984. if ($this->afterMatchBuilderId !== null) {
  36985. $builder = $invocation->object
  36986. ->__phpunit_getInvocationMocker()
  36987. ->lookupId($this->afterMatchBuilderId);
  36988. if (!$builder) {
  36989. throw new PHPUnit_Framework_Exception(
  36990. sprintf(
  36991. 'No builder found for match builder identification <%s>',
  36992. $this->afterMatchBuilderId
  36993. )
  36994. );
  36995. }
  36996. $matcher = $builder->getMatcher();
  36997. if (!$matcher) {
  36998. return false;
  36999. }
  37000. if (!$matcher->invocationMatcher->hasBeenInvoked()) {
  37001. return false;
  37002. }
  37003. }
  37004. if ($this->invocationMatcher === null) {
  37005. throw new PHPUnit_Framework_Exception(
  37006. 'No invocation matcher is set'
  37007. );
  37008. }
  37009. if ($this->methodNameMatcher === null) {
  37010. throw new PHPUnit_Framework_Exception('No method matcher is set');
  37011. }
  37012. if (!$this->invocationMatcher->matches($invocation)) {
  37013. return false;
  37014. }
  37015. try {
  37016. if (!$this->methodNameMatcher->matches($invocation)) {
  37017. return false;
  37018. }
  37019. } catch (PHPUnit_Framework_ExpectationFailedException $e) {
  37020. throw new PHPUnit_Framework_ExpectationFailedException(
  37021. sprintf(
  37022. "Expectation failed for %s when %s\n%s",
  37023. $this->methodNameMatcher->toString(),
  37024. $this->invocationMatcher->toString(),
  37025. $e->getMessage()
  37026. ),
  37027. $e->getComparisonFailure()
  37028. );
  37029. }
  37030. return true;
  37031. }
  37032. /**
  37033. * @throws PHPUnit_Framework_Exception
  37034. * @throws PHPUnit_Framework_ExpectationFailedException
  37035. */
  37036. public function verify()
  37037. {
  37038. if ($this->invocationMatcher === null) {
  37039. throw new PHPUnit_Framework_Exception(
  37040. 'No invocation matcher is set'
  37041. );
  37042. }
  37043. if ($this->methodNameMatcher === null) {
  37044. throw new PHPUnit_Framework_Exception('No method matcher is set');
  37045. }
  37046. try {
  37047. $this->invocationMatcher->verify();
  37048. if ($this->parametersMatcher === null) {
  37049. $this->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_AnyParameters;
  37050. }
  37051. $invocationIsAny = get_class($this->invocationMatcher) === 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount';
  37052. $invocationIsNever = get_class($this->invocationMatcher) === 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' && $this->invocationMatcher->isNever();
  37053. if (!$invocationIsAny && !$invocationIsNever) {
  37054. $this->parametersMatcher->verify();
  37055. }
  37056. } catch (PHPUnit_Framework_ExpectationFailedException $e) {
  37057. throw new PHPUnit_Framework_ExpectationFailedException(
  37058. sprintf(
  37059. "Expectation failed for %s when %s.\n%s",
  37060. $this->methodNameMatcher->toString(),
  37061. $this->invocationMatcher->toString(),
  37062. PHPUnit_Framework_TestFailure::exceptionToString($e)
  37063. )
  37064. );
  37065. }
  37066. }
  37067. /**
  37068. * @since Method available since Release 1.2.4
  37069. */
  37070. public function hasMatchers()
  37071. {
  37072. if ($this->invocationMatcher !== null &&
  37073. !$this->invocationMatcher instanceof PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount) {
  37074. return true;
  37075. }
  37076. return false;
  37077. }
  37078. }
  37079. <?php
  37080. /*
  37081. * This file is part of the PHPUnit_MockObject package.
  37082. *
  37083. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37084. *
  37085. * For the full copyright and license information, please view the LICENSE
  37086. * file that was distributed with this source code.
  37087. */
  37088. /**
  37089. * Interface for classes which must verify a given expectation.
  37090. *
  37091. * @package PHPUnit_MockObject
  37092. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37093. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37094. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37095. * @version Release: @package_version@
  37096. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37097. * @since Interface available since Release 1.0.0
  37098. */
  37099. interface PHPUnit_Framework_MockObject_Verifiable
  37100. {
  37101. /**
  37102. * Verifies that the current expectation is valid. If everything is OK the
  37103. * code should just return, if not it must throw an exception.
  37104. *
  37105. * @throws PHPUnit_Framework_ExpectationFailedException
  37106. */
  37107. public function verify();
  37108. }
  37109. <?php
  37110. /*
  37111. * This file is part of the PHPUnit_MockObject package.
  37112. *
  37113. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37114. *
  37115. * For the full copyright and license information, please view the LICENSE
  37116. * file that was distributed with this source code.
  37117. */
  37118. /**
  37119. * Interface for classes which can be invoked.
  37120. *
  37121. * The invocation will be taken from a mock object and passed to an object
  37122. * of this class.
  37123. *
  37124. * @package PHPUnit_MockObject
  37125. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37126. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37127. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37128. * @version Release: @package_version@
  37129. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37130. * @since Interface available since Release 1.0.0
  37131. */
  37132. interface PHPUnit_Framework_MockObject_Invokable extends PHPUnit_Framework_MockObject_Verifiable
  37133. {
  37134. /**
  37135. * Invokes the invocation object $invocation so that it can be checked for
  37136. * expectations or matched against stubs.
  37137. *
  37138. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37139. * The invocation object passed from mock object.
  37140. * @return object
  37141. */
  37142. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation);
  37143. /**
  37144. * Checks if the invocation matches.
  37145. *
  37146. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37147. * The invocation object passed from mock object.
  37148. * @return boolean
  37149. */
  37150. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation);
  37151. }
  37152. <?php
  37153. /*
  37154. * This file is part of the PHPUnit_MockObject package.
  37155. *
  37156. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37157. *
  37158. * For the full copyright and license information, please view the LICENSE
  37159. * file that was distributed with this source code.
  37160. */
  37161. /**
  37162. * Implementation of the Builder pattern for Mock objects.
  37163. *
  37164. * @package PHPUnit_MockObject
  37165. * @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
  37166. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37167. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37168. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37169. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37170. * @since File available since Release 1.0.0
  37171. */
  37172. class PHPUnit_Framework_MockObject_MockBuilder
  37173. {
  37174. /**
  37175. * @var PHPUnit_Framework_TestCase
  37176. */
  37177. private $testCase;
  37178. /**
  37179. * @var string
  37180. */
  37181. private $type;
  37182. /**
  37183. * @var array
  37184. */
  37185. private $methods = array();
  37186. /**
  37187. * @var string
  37188. */
  37189. private $mockClassName = '';
  37190. /**
  37191. * @var array
  37192. */
  37193. private $constructorArgs = array();
  37194. /**
  37195. * @var boolean
  37196. */
  37197. private $originalConstructor = true;
  37198. /**
  37199. * @var boolean
  37200. */
  37201. private $originalClone = true;
  37202. /**
  37203. * @var boolean
  37204. */
  37205. private $autoload = true;
  37206. /**
  37207. * @var boolean
  37208. */
  37209. private $cloneArguments = false;
  37210. /**
  37211. * @var boolean
  37212. */
  37213. private $callOriginalMethods = false;
  37214. /**
  37215. * @var object
  37216. */
  37217. private $proxyTarget = null;
  37218. /**
  37219. * @param PHPUnit_Framework_TestCase $testCase
  37220. * @param array|string $type
  37221. */
  37222. public function __construct(PHPUnit_Framework_TestCase $testCase, $type)
  37223. {
  37224. $this->testCase = $testCase;
  37225. $this->type = $type;
  37226. }
  37227. /**
  37228. * Creates a mock object using a fluent interface.
  37229. *
  37230. * @return PHPUnit_Framework_MockObject_MockObject
  37231. */
  37232. public function getMock()
  37233. {
  37234. return $this->testCase->getMock(
  37235. $this->type,
  37236. $this->methods,
  37237. $this->constructorArgs,
  37238. $this->mockClassName,
  37239. $this->originalConstructor,
  37240. $this->originalClone,
  37241. $this->autoload,
  37242. $this->cloneArguments,
  37243. $this->callOriginalMethods,
  37244. $this->proxyTarget
  37245. );
  37246. }
  37247. /**
  37248. * Creates a mock object for an abstract class using a fluent interface.
  37249. *
  37250. * @return PHPUnit_Framework_MockObject_MockObject
  37251. */
  37252. public function getMockForAbstractClass()
  37253. {
  37254. return $this->testCase->getMockForAbstractClass(
  37255. $this->type,
  37256. $this->constructorArgs,
  37257. $this->mockClassName,
  37258. $this->originalConstructor,
  37259. $this->originalClone,
  37260. $this->autoload,
  37261. $this->methods,
  37262. $this->cloneArguments
  37263. );
  37264. }
  37265. /**
  37266. * Creates a mock object for a trait using a fluent interface.
  37267. *
  37268. * @return PHPUnit_Framework_MockObject_MockObject
  37269. */
  37270. public function getMockForTrait()
  37271. {
  37272. return $this->testCase->getMockForTrait(
  37273. $this->type,
  37274. $this->constructorArgs,
  37275. $this->mockClassName,
  37276. $this->originalConstructor,
  37277. $this->originalClone,
  37278. $this->autoload,
  37279. $this->methods,
  37280. $this->cloneArguments
  37281. );
  37282. }
  37283. /**
  37284. * Specifies the subset of methods to mock. Default is to mock all of them.
  37285. *
  37286. * @param array|null $methods
  37287. * @return PHPUnit_Framework_MockObject_MockBuilder
  37288. */
  37289. public function setMethods($methods)
  37290. {
  37291. $this->methods = $methods;
  37292. return $this;
  37293. }
  37294. /**
  37295. * Specifies the arguments for the constructor.
  37296. *
  37297. * @param array $args
  37298. * @return PHPUnit_Framework_MockObject_MockBuilder
  37299. */
  37300. public function setConstructorArgs(array $args)
  37301. {
  37302. $this->constructorArgs = $args;
  37303. return $this;
  37304. }
  37305. /**
  37306. * Specifies the name for the mock class.
  37307. *
  37308. * @param string $name
  37309. * @return PHPUnit_Framework_MockObject_MockBuilder
  37310. */
  37311. public function setMockClassName($name)
  37312. {
  37313. $this->mockClassName = $name;
  37314. return $this;
  37315. }
  37316. /**
  37317. * Disables the invocation of the original constructor.
  37318. *
  37319. * @return PHPUnit_Framework_MockObject_MockBuilder
  37320. */
  37321. public function disableOriginalConstructor()
  37322. {
  37323. $this->originalConstructor = false;
  37324. return $this;
  37325. }
  37326. /**
  37327. * Enables the invocation of the original constructor.
  37328. *
  37329. * @return PHPUnit_Framework_MockObject_MockBuilder
  37330. * @since Method available since Release 1.2.0
  37331. */
  37332. public function enableOriginalConstructor()
  37333. {
  37334. $this->originalConstructor = true;
  37335. return $this;
  37336. }
  37337. /**
  37338. * Disables the invocation of the original clone constructor.
  37339. *
  37340. * @return PHPUnit_Framework_MockObject_MockBuilder
  37341. */
  37342. public function disableOriginalClone()
  37343. {
  37344. $this->originalClone = false;
  37345. return $this;
  37346. }
  37347. /**
  37348. * Enables the invocation of the original clone constructor.
  37349. *
  37350. * @return PHPUnit_Framework_MockObject_MockBuilder
  37351. * @since Method available since Release 1.2.0
  37352. */
  37353. public function enableOriginalClone()
  37354. {
  37355. $this->originalClone = true;
  37356. return $this;
  37357. }
  37358. /**
  37359. * Disables the use of class autoloading while creating the mock object.
  37360. *
  37361. * @return PHPUnit_Framework_MockObject_MockBuilder
  37362. */
  37363. public function disableAutoload()
  37364. {
  37365. $this->autoload = false;
  37366. return $this;
  37367. }
  37368. /**
  37369. * Enables the use of class autoloading while creating the mock object.
  37370. *
  37371. * @return PHPUnit_Framework_MockObject_MockBuilder
  37372. * @since Method available since Release 1.2.0
  37373. */
  37374. public function enableAutoload()
  37375. {
  37376. $this->autoload = true;
  37377. return $this;
  37378. }
  37379. /**
  37380. * Disables the cloning of arguments passed to mocked methods.
  37381. *
  37382. * @return PHPUnit_Framework_MockObject_MockBuilder
  37383. * @since Method available since Release 1.2.0
  37384. */
  37385. public function disableArgumentCloning()
  37386. {
  37387. $this->cloneArguments = false;
  37388. return $this;
  37389. }
  37390. /**
  37391. * Enables the cloning of arguments passed to mocked methods.
  37392. *
  37393. * @return PHPUnit_Framework_MockObject_MockBuilder
  37394. * @since Method available since Release 1.2.0
  37395. */
  37396. public function enableArgumentCloning()
  37397. {
  37398. $this->cloneArguments = true;
  37399. return $this;
  37400. }
  37401. /**
  37402. * Enables the invocation of the original methods.
  37403. *
  37404. * @return PHPUnit_Framework_MockObject_MockBuilder
  37405. * @since Method available since Release 2.0.0
  37406. */
  37407. public function enableProxyingToOriginalMethods()
  37408. {
  37409. $this->callOriginalMethods = true;
  37410. return $this;
  37411. }
  37412. /**
  37413. * Disables the invocation of the original methods.
  37414. *
  37415. * @return PHPUnit_Framework_MockObject_MockBuilder
  37416. * @since Method available since Release 2.0.0
  37417. */
  37418. public function disableProxyingToOriginalMethods()
  37419. {
  37420. $this->callOriginalMethods = false;
  37421. $this->proxyTarget = null;
  37422. return $this;
  37423. }
  37424. /**
  37425. * Sets the proxy target.
  37426. *
  37427. * @param object $object
  37428. * @return PHPUnit_Framework_MockObject_MockBuilder
  37429. * @since Method available since Release 2.0.0
  37430. */
  37431. public function setProxyTarget($object)
  37432. {
  37433. $this->proxyTarget = $object;
  37434. return $this;
  37435. }
  37436. }
  37437. <?php
  37438. /*
  37439. * This file is part of the PHPUnit_MockObject package.
  37440. *
  37441. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37442. *
  37443. * For the full copyright and license information, please view the LICENSE
  37444. * file that was distributed with this source code.
  37445. */
  37446. /**
  37447. * Interface for exceptions used by PHPUnit_MockObject.
  37448. *
  37449. * @package PHPUnit_MockObject
  37450. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37451. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37452. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37453. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37454. * @since Interface available since Release 2.0.6
  37455. */
  37456. interface PHPUnit_Framework_MockObject_Exception
  37457. {
  37458. }
  37459. <?php
  37460. /*
  37461. * This file is part of the PHPUnit_MockObject package.
  37462. *
  37463. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37464. *
  37465. * For the full copyright and license information, please view the LICENSE
  37466. * file that was distributed with this source code.
  37467. */
  37468. /**
  37469. * @package PHPUnit_MockObject
  37470. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37471. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37472. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37473. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37474. * @since Class available since Release 2.0.6
  37475. */
  37476. class PHPUnit_Framework_MockObject_BadMethodCallException extends BadMethodCallException implements PHPUnit_Framework_MockObject_Exception
  37477. {
  37478. }
  37479. <?php
  37480. /*
  37481. * This file is part of the PHPUnit_MockObject package.
  37482. *
  37483. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37484. *
  37485. * For the full copyright and license information, please view the LICENSE
  37486. * file that was distributed with this source code.
  37487. */
  37488. /**
  37489. * @package PHPUnit_MockObject
  37490. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37491. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37492. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37493. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37494. * @since Class available since Release 2.0.6
  37495. */
  37496. class PHPUnit_Framework_MockObject_RuntimeException extends RuntimeException implements PHPUnit_Framework_MockObject_Exception
  37497. {
  37498. }
  37499. <?php
  37500. /*
  37501. * This file is part of the PHPUnit_MockObject package.
  37502. *
  37503. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37504. *
  37505. * For the full copyright and license information, please view the LICENSE
  37506. * file that was distributed with this source code.
  37507. */
  37508. /**
  37509. * Interface for invocations.
  37510. *
  37511. * @package PHPUnit_MockObject
  37512. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37513. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37514. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37515. * @version Release: @package_version@
  37516. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37517. * @since Interface available since Release 1.0.0
  37518. */
  37519. interface PHPUnit_Framework_MockObject_Invocation
  37520. {
  37521. }
  37522. <?php
  37523. /*
  37524. * This file is part of the PHPUnit_MockObject package.
  37525. *
  37526. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37527. *
  37528. * For the full copyright and license information, please view the LICENSE
  37529. * file that was distributed with this source code.
  37530. */
  37531. /**
  37532. * Interface for all mock objects which are generated by
  37533. * PHPUnit_Framework_MockObject_MockBuilder.
  37534. *
  37535. * @package PHPUnit_MockObject
  37536. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37537. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37538. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37539. * @version Release: @package_version@
  37540. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37541. * @since Interface available since Release 1.0.0
  37542. */
  37543. interface PHPUnit_Framework_MockObject_MockObject /*extends PHPUnit_Framework_MockObject_Verifiable*/
  37544. {
  37545. /**
  37546. * Registers a new expectation in the mock object and returns the match
  37547. * object which can be infused with further details.
  37548. *
  37549. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
  37550. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  37551. */
  37552. public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher);
  37553. /**
  37554. * @return PHPUnit_Framework_MockObject_InvocationMocker
  37555. * @since Method available since Release 2.0.0
  37556. */
  37557. public function __phpunit_setOriginalObject($originalObject);
  37558. /**
  37559. * @return PHPUnit_Framework_MockObject_InvocationMocker
  37560. */
  37561. public function __phpunit_getInvocationMocker();
  37562. /**
  37563. * Verifies that the current expectation is valid. If everything is OK the
  37564. * code should just return, if not it must throw an exception.
  37565. *
  37566. * @throws PHPUnit_Framework_ExpectationFailedException
  37567. */
  37568. public function __phpunit_verify();
  37569. }
  37570. <?php
  37571. /*
  37572. * This file is part of the PHPUnit_MockObject package.
  37573. *
  37574. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37575. *
  37576. * For the full copyright and license information, please view the LICENSE
  37577. * file that was distributed with this source code.
  37578. */
  37579. /**
  37580. * Mocker for invocations which are sent from
  37581. * PHPUnit_Framework_MockObject_MockObject objects.
  37582. *
  37583. * Keeps track of all expectations and stubs as well as registering
  37584. * identifications for builders.
  37585. *
  37586. * @package PHPUnit_MockObject
  37587. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37588. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37589. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37590. * @version Release: @package_version@
  37591. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37592. * @since Class available since Release 1.0.0
  37593. */
  37594. class PHPUnit_Framework_MockObject_InvocationMocker implements PHPUnit_Framework_MockObject_Stub_MatcherCollection, PHPUnit_Framework_MockObject_Invokable, PHPUnit_Framework_MockObject_Builder_Namespace
  37595. {
  37596. /**
  37597. * @var PHPUnit_Framework_MockObject_Matcher_Invocation[]
  37598. */
  37599. protected $matchers = array();
  37600. /**
  37601. * @var PHPUnit_Framework_MockObject_Builder_Match[]
  37602. */
  37603. protected $builderMap = array();
  37604. /**
  37605. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
  37606. */
  37607. public function addMatcher(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
  37608. {
  37609. $this->matchers[] = $matcher;
  37610. }
  37611. /**
  37612. * @since Method available since Release 1.1.0
  37613. */
  37614. public function hasMatchers()
  37615. {
  37616. foreach ($this->matchers as $matcher) {
  37617. if ($matcher->hasMatchers()) {
  37618. return true;
  37619. }
  37620. }
  37621. return false;
  37622. }
  37623. /**
  37624. * @param mixed $id
  37625. * @return boolean|null
  37626. */
  37627. public function lookupId($id)
  37628. {
  37629. if (isset($this->builderMap[$id])) {
  37630. return $this->builderMap[$id];
  37631. }
  37632. return null;
  37633. }
  37634. /**
  37635. * @param mixed $id
  37636. * @param PHPUnit_Framework_MockObject_Builder_Match $builder
  37637. * @throws PHPUnit_Framework_Exception
  37638. */
  37639. public function registerId($id, PHPUnit_Framework_MockObject_Builder_Match $builder)
  37640. {
  37641. if (isset($this->builderMap[$id])) {
  37642. throw new PHPUnit_Framework_Exception(
  37643. 'Match builder with id <' . $id . '> is already registered.'
  37644. );
  37645. }
  37646. $this->builderMap[$id] = $builder;
  37647. }
  37648. /**
  37649. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
  37650. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  37651. */
  37652. public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
  37653. {
  37654. return new PHPUnit_Framework_MockObject_Builder_InvocationMocker(
  37655. $this,
  37656. $matcher
  37657. );
  37658. }
  37659. /**
  37660. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37661. * @return mixed
  37662. */
  37663. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  37664. {
  37665. $exception = null;
  37666. $hasReturnValue = false;
  37667. if (strtolower($invocation->methodName) == '__tostring') {
  37668. $returnValue = '';
  37669. } else {
  37670. $returnValue = null;
  37671. }
  37672. foreach ($this->matchers as $match) {
  37673. try {
  37674. if ($match->matches($invocation)) {
  37675. $value = $match->invoked($invocation);
  37676. if (!$hasReturnValue) {
  37677. $returnValue = $value;
  37678. $hasReturnValue = true;
  37679. }
  37680. }
  37681. } catch (Exception $e) {
  37682. $exception = $e;
  37683. }
  37684. }
  37685. if ($exception !== null) {
  37686. throw $exception;
  37687. }
  37688. return $returnValue;
  37689. }
  37690. /**
  37691. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37692. * @return boolean
  37693. */
  37694. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  37695. {
  37696. foreach ($this->matchers as $matcher) {
  37697. if (!$matcher->matches($invocation)) {
  37698. return false;
  37699. }
  37700. }
  37701. return true;
  37702. }
  37703. /**
  37704. * @return boolean
  37705. */
  37706. public function verify()
  37707. {
  37708. foreach ($this->matchers as $matcher) {
  37709. $matcher->verify();
  37710. }
  37711. }
  37712. }
  37713. <?php
  37714. /*
  37715. * This file is part of the PHPUnit_MockObject package.
  37716. *
  37717. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37718. *
  37719. * For the full copyright and license information, please view the LICENSE
  37720. * file that was distributed with this source code.
  37721. */
  37722. /**
  37723. * Invocation matcher which looks for a specific method name in the invocations.
  37724. *
  37725. * Checks the method name all incoming invocations, the name is checked against
  37726. * the defined constraint $constraint. If the constraint is met it will return
  37727. * true in matches().
  37728. *
  37729. * @package PHPUnit_MockObject
  37730. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37731. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37732. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37733. * @version Release: @package_version@
  37734. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37735. * @since Class available since Release 1.0.0
  37736. */
  37737. class PHPUnit_Framework_MockObject_Matcher_MethodName extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
  37738. {
  37739. /**
  37740. * @var PHPUnit_Framework_Constraint
  37741. */
  37742. protected $constraint;
  37743. /**
  37744. * @param PHPUnit_Framework_Constraint|string
  37745. * @throws PHPUnit_Framework_Constraint
  37746. */
  37747. public function __construct($constraint)
  37748. {
  37749. if (!$constraint instanceof PHPUnit_Framework_Constraint) {
  37750. if (!is_string($constraint)) {
  37751. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  37752. }
  37753. $constraint = new PHPUnit_Framework_Constraint_IsEqual(
  37754. $constraint,
  37755. 0,
  37756. 10,
  37757. false,
  37758. true
  37759. );
  37760. }
  37761. $this->constraint = $constraint;
  37762. }
  37763. /**
  37764. * @return string
  37765. */
  37766. public function toString()
  37767. {
  37768. return 'method name ' . $this->constraint->toString();
  37769. }
  37770. /**
  37771. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37772. * @return boolean
  37773. */
  37774. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  37775. {
  37776. return $this->constraint->evaluate($invocation->methodName, '', true);
  37777. }
  37778. }
  37779. <?php
  37780. /*
  37781. * This file is part of the PHPUnit_MockObject package.
  37782. *
  37783. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37784. *
  37785. * For the full copyright and license information, please view the LICENSE
  37786. * file that was distributed with this source code.
  37787. */
  37788. /**
  37789. * Invocation matcher which checks if a method has been invoked at least one
  37790. * time.
  37791. *
  37792. * If the number of invocations is 0 it will throw an exception in verify.
  37793. *
  37794. * @package PHPUnit_MockObject
  37795. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37796. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37797. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37798. * @version Release: @package_version@
  37799. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37800. * @since Class available since Release 1.0.0
  37801. */
  37802. class PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
  37803. {
  37804. /**
  37805. * @return string
  37806. */
  37807. public function toString()
  37808. {
  37809. return 'invoked at least once';
  37810. }
  37811. /**
  37812. * Verifies that the current expectation is valid. If everything is OK the
  37813. * code should just return, if not it must throw an exception.
  37814. *
  37815. * @throws PHPUnit_Framework_ExpectationFailedException
  37816. */
  37817. public function verify()
  37818. {
  37819. $count = $this->getInvocationCount();
  37820. if ($count < 1) {
  37821. throw new PHPUnit_Framework_ExpectationFailedException(
  37822. 'Expected invocation at least once but it never occured.'
  37823. );
  37824. }
  37825. }
  37826. }
  37827. <?php
  37828. /*
  37829. * This file is part of the PHPUnit_MockObject package.
  37830. *
  37831. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37832. *
  37833. * For the full copyright and license information, please view the LICENSE
  37834. * file that was distributed with this source code.
  37835. */
  37836. /**
  37837. * Invocation matcher which allows any parameters to a method.
  37838. *
  37839. * @package PHPUnit_MockObject
  37840. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37841. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37842. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37843. * @version Release: @package_version@
  37844. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37845. * @since Class available since Release 1.0.0
  37846. */
  37847. class PHPUnit_Framework_MockObject_Matcher_AnyParameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
  37848. {
  37849. /**
  37850. * @return string
  37851. */
  37852. public function toString()
  37853. {
  37854. return 'with any parameters';
  37855. }
  37856. /**
  37857. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37858. * @return boolean
  37859. */
  37860. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  37861. {
  37862. return true;
  37863. }
  37864. }
  37865. <?php
  37866. /*
  37867. * This file is part of the PHPUnit_MockObject package.
  37868. *
  37869. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37870. *
  37871. * For the full copyright and license information, please view the LICENSE
  37872. * file that was distributed with this source code.
  37873. */
  37874. /**
  37875. * Invocation matcher which looks for specific parameters in the invocations.
  37876. *
  37877. * Checks the parameters of all incoming invocations, the parameter list is
  37878. * checked against the defined constraints in $parameters. If the constraint
  37879. * is met it will return true in matches().
  37880. *
  37881. * @package PHPUnit_MockObject
  37882. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37883. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37884. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37885. * @version Release: @package_version@
  37886. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  37887. * @since Class available since Release 1.0.0
  37888. */
  37889. class PHPUnit_Framework_MockObject_Matcher_Parameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
  37890. {
  37891. /**
  37892. * @var array
  37893. */
  37894. protected $parameters = array();
  37895. /**
  37896. * @var PHPUnit_Framework_MockObject_Invocation
  37897. */
  37898. protected $invocation;
  37899. /**
  37900. * @param array $parameters
  37901. */
  37902. public function __construct(array $parameters)
  37903. {
  37904. foreach ($parameters as $parameter) {
  37905. if (!($parameter instanceof PHPUnit_Framework_Constraint)) {
  37906. $parameter = new PHPUnit_Framework_Constraint_IsEqual(
  37907. $parameter
  37908. );
  37909. }
  37910. $this->parameters[] = $parameter;
  37911. }
  37912. }
  37913. /**
  37914. * @return string
  37915. */
  37916. public function toString()
  37917. {
  37918. $text = 'with parameter';
  37919. foreach ($this->parameters as $index => $parameter) {
  37920. if ($index > 0) {
  37921. $text .= ' and';
  37922. }
  37923. $text .= ' ' . $index . ' ' . $parameter->toString();
  37924. }
  37925. return $text;
  37926. }
  37927. /**
  37928. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37929. * @return boolean
  37930. */
  37931. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  37932. {
  37933. $this->invocation = $invocation;
  37934. return $this->verify();
  37935. }
  37936. /**
  37937. * Checks if the invocation $invocation matches the current rules. If it
  37938. * does the matcher will get the invoked() method called which should check
  37939. * if an expectation is met.
  37940. *
  37941. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37942. * Object containing information on a mocked or stubbed method which
  37943. * was invoked.
  37944. * @return bool
  37945. * @throws PHPUnit_Framework_ExpectationFailedException
  37946. */
  37947. public function verify()
  37948. {
  37949. if ($this->invocation === null) {
  37950. throw new PHPUnit_Framework_ExpectationFailedException(
  37951. 'Mocked method does not exist.'
  37952. );
  37953. }
  37954. if (count($this->invocation->parameters) < count($this->parameters)) {
  37955. $message = 'Parameter count for invocation %s is too low.';
  37956. // The user called `->with($this->anything())`, but may have meant
  37957. // `->withAnyParameters()`.
  37958. //
  37959. // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/199
  37960. if (count($this->parameters) === 1 &&
  37961. get_class($this->parameters[0]) === 'PHPUnit_Framework_Constraint_IsAnything') {
  37962. $message .= "\nTo allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead.";
  37963. }
  37964. throw new PHPUnit_Framework_ExpectationFailedException(
  37965. sprintf($message, $this->invocation->toString())
  37966. );
  37967. }
  37968. foreach ($this->parameters as $i => $parameter) {
  37969. $parameter->evaluate(
  37970. $this->invocation->parameters[$i],
  37971. sprintf(
  37972. 'Parameter %s for invocation %s does not match expected ' .
  37973. 'value.',
  37974. $i,
  37975. $this->invocation->toString()
  37976. )
  37977. );
  37978. }
  37979. return true;
  37980. }
  37981. }
  37982. <?php
  37983. /*
  37984. * This file is part of the PHPUnit_MockObject package.
  37985. *
  37986. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37987. *
  37988. * For the full copyright and license information, please view the LICENSE
  37989. * file that was distributed with this source code.
  37990. */
  37991. /**
  37992. * Invocation matcher which checks if a method has been invoked zero or more
  37993. * times. This matcher will always match.
  37994. *
  37995. * @package PHPUnit_MockObject
  37996. * @author Sebastian Bergmann <sebastian@phpunit.de>
  37997. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  37998. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  37999. * @version Release: @package_version@
  38000. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  38001. * @since Class available since Release 1.0.0
  38002. */
  38003. class PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
  38004. {
  38005. /**
  38006. * @return string
  38007. */
  38008. public function toString()
  38009. {
  38010. return 'invoked zero or more times';
  38011. }
  38012. /**
  38013. */
  38014. public function verify()
  38015. {
  38016. }
  38017. }
  38018. <?php
  38019. /*
  38020. * This file is part of the PHPUnit_MockObject package.
  38021. *
  38022. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38023. *
  38024. * For the full copyright and license information, please view the LICENSE
  38025. * file that was distributed with this source code.
  38026. */
  38027. /**
  38028. * Invocation matcher which checks if a method has been invoked at least
  38029. * N times.
  38030. *
  38031. * @package PHPUnit_MockObject
  38032. * @author Sebastian Bergmann <sebastian@phpunit.de>
  38033. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  38034. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  38035. * @version Release: @package_version@
  38036. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  38037. * @since Class available since Release 2.2.0
  38038. */
  38039. class PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
  38040. {
  38041. /**
  38042. * @var integer
  38043. */
  38044. private $requiredInvocations;
  38045. /**
  38046. * @param integer $requiredInvocations
  38047. */
  38048. public function __construct($requiredInvocations)
  38049. {
  38050. $this->requiredInvocations = $requiredInvocations;
  38051. }
  38052. /**
  38053. * @return string
  38054. */
  38055. public function toString()
  38056. {
  38057. return 'invoked at least ' . $this->requiredInvocations . ' times';
  38058. }
  38059. /**
  38060. * Verifies that the current expectation is valid. If everything is OK the
  38061. * code should just return, if not it must throw an exception.
  38062. *
  38063. * @throws PHPUnit_Framework_ExpectationFailedException
  38064. */
  38065. public function verify()
  38066. {
  38067. $count = $this->getInvocationCount();
  38068. if ($count < $this->requiredInvocations) {
  38069. throw new PHPUnit_Framework_ExpectationFailedException(
  38070. 'Expected invocation at least ' . $this->requiredInvocations .
  38071. ' times but it occured ' . $count . ' time(s).'
  38072. );
  38073. }
  38074. }
  38075. }
  38076. <?php
  38077. /*
  38078. * This file is part of the PHPUnit_MockObject package.
  38079. *
  38080. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38081. *
  38082. * For the full copyright and license information, please view the LICENSE
  38083. * file that was distributed with this source code.
  38084. */
  38085. /**
  38086. * Interface for classes which matches an invocation based on its
  38087. * method name, argument, order or call count.
  38088. *
  38089. * @package PHPUnit_MockObject
  38090. * @author Sebastian Bergmann <sebastian@phpunit.de>
  38091. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  38092. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  38093. * @version Release: @package_version@
  38094. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  38095. * @since Interface available since Release 1.0.0
  38096. */
  38097. interface PHPUnit_Framework_MockObject_Matcher_Invocation extends PHPUnit_Framework_SelfDescribing, PHPUnit_Framework_MockObject_Verifiable
  38098. {
  38099. /**
  38100. * Registers the invocation $invocation in the object as being invoked.
  38101. * This will only occur after matches() returns true which means the
  38102. * current invocation is the correct one.
  38103. *
  38104. * The matcher can store information from the invocation which can later
  38105. * be checked in verify(), or it can check the values directly and throw
  38106. * and exception if an expectation is not met.
  38107. *
  38108. * If the matcher is a stub it will also have a return value.
  38109. *
  38110. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38111. * Object containing information on a mocked or stubbed method which
  38112. * was invoked.
  38113. * @return mixed
  38114. */
  38115. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation);
  38116. /**
  38117. * Checks if the invocation $invocation matches the current rules. If it does
  38118. * the matcher will get the invoked() method called which should check if an
  38119. * expectation is met.
  38120. *
  38121. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38122. * Object containing information on a mocked or stubbed method which
  38123. * was invoked.
  38124. * @return bool
  38125. */
  38126. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation);
  38127. }
  38128. <?php
  38129. /*
  38130. * This file is part of the PHPUnit_MockObject package.
  38131. *
  38132. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38133. *
  38134. * For the full copyright and license information, please view the LICENSE
  38135. * file that was distributed with this source code.
  38136. */
  38137. /**
  38138. * Invocation matcher which looks for sets of specific parameters in the invocations.
  38139. *
  38140. * Checks the parameters of the incoming invocations, the parameter list is
  38141. * checked against the defined constraints in $parameters. If the constraint
  38142. * is met it will return true in matches().
  38143. *
  38144. * It takes a list of match groups and and increases a call index after each invocation.
  38145. * So the first invocation uses the first group of constraints, the second the next and so on.
  38146. *
  38147. * @package PHPUnit_MockObject
  38148. * @author Sebastian Bergmann <sebastian@phpunit.de>
  38149. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  38150. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  38151. * @version Release: @package_version@
  38152. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  38153. */
  38154. class PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
  38155. {
  38156. /**
  38157. * @var array
  38158. */
  38159. private $_parameterGroups = array();
  38160. /**
  38161. * @var array
  38162. */
  38163. private $_invocations = array();
  38164. /**
  38165. * @param array $parameterGroups
  38166. */
  38167. public function __construct(array $parameterGroups)
  38168. {
  38169. foreach ($parameterGroups as $index => $parameters) {
  38170. foreach ($parameters as $parameter) {
  38171. if (!($parameter instanceof \PHPUnit_Framework_Constraint)) {
  38172. $parameter = new \PHPUnit_Framework_Constraint_IsEqual($parameter);
  38173. }
  38174. $this->_parameterGroups[$index][] = $parameter;
  38175. }
  38176. }
  38177. }
  38178. /**
  38179. * @return string
  38180. */
  38181. public function toString()
  38182. {
  38183. $text = 'with consecutive parameters';
  38184. return $text;
  38185. }
  38186. /**
  38187. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38188. * @return bool
  38189. */
  38190. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  38191. {
  38192. $this->_invocations[] = $invocation;
  38193. $callIndex = count($this->_invocations) - 1;
  38194. $this->verifyInvocation($invocation, $callIndex);
  38195. return false;
  38196. }
  38197. public function verify()
  38198. {
  38199. foreach ($this->_invocations as $callIndex => $invocation) {
  38200. $this->verifyInvocation($invocation, $callIndex);
  38201. }
  38202. }
  38203. /**
  38204. * Verify a single invocation
  38205. *
  38206. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38207. * @param int $callIndex
  38208. * @throws PHPUnit_Framework_ExpectationFailedException
  38209. */
  38210. private function verifyInvocation(PHPUnit_Framework_MockObject_Invocation $invocation, $callIndex)
  38211. {
  38212. if (isset($this->_parameterGroups[$callIndex])) {
  38213. $parameters = $this->_parameterGroups[$callIndex];
  38214. } else {
  38215. // no parameter assertion for this call index
  38216. return;
  38217. }
  38218. if ($invocation === null) {
  38219. throw new PHPUnit_Framework_ExpectationFailedException(
  38220. 'Mocked method does not exist.'
  38221. );
  38222. }
  38223. if (count($invocation->parameters) < count($parameters)) {
  38224. throw new PHPUnit_Framework_ExpectationFailedException(
  38225. sprintf(
  38226. 'Parameter count for invocation %s is too low.',
  38227. $invocation->toString()
  38228. )
  38229. );
  38230. }
  38231. foreach ($parameters as $i => $parameter) {
  38232. $parameter->evaluate(
  38233. $invocation->parameters[$i],
  38234. sprintf(
  38235. 'Parameter %s for invocation #%d %s does not match expected ' .
  38236. 'value.',
  38237. $i,
  38238. $callIndex,
  38239. $invocation->toString()
  38240. )
  38241. );
  38242. }
  38243. }
  38244. }
  38245. <?php
  38246. /*
  38247. * This file is part of the PHPUnit_MockObject package.
  38248. *
  38249. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38250. *
  38251. * For the full copyright and license information, please view the LICENSE
  38252. * file that was distributed with this source code.
  38253. */
  38254. /**
  38255. * Invocation matcher which checks if a method was invoked at a certain index.
  38256. *
  38257. * If the expected index number does not match the current invocation index it
  38258. * will not match which means it skips all method and parameter matching. Only
  38259. * once the index is reached will the method and parameter start matching and
  38260. * verifying.
  38261. *
  38262. * If the index is never reached it will throw an exception in index.
  38263. *
  38264. * @package PHPUnit_MockObject
  38265. * @author Sebastian Bergmann <sebastian@phpunit.de>
  38266. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  38267. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  38268. * @version Release: @package_version@
  38269. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  38270. * @since Class available since Release 1.0.0
  38271. */
  38272. class PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex implements PHPUnit_Framework_MockObject_Matcher_Invocation
  38273. {
  38274. /**
  38275. * @var integer
  38276. */
  38277. protected $sequenceIndex;
  38278. /**
  38279. * @var integer
  38280. */
  38281. protected $currentIndex = -1;
  38282. /**
  38283. * @param integer $sequenceIndex
  38284. */
  38285. public function __construct($sequenceIndex)
  38286. {
  38287. $this->sequenceIndex = $sequenceIndex;
  38288. }
  38289. /**
  38290. * @return string
  38291. */
  38292. public function toString()
  38293. {
  38294. return 'invoked at sequence index ' . $this->sequenceIndex;
  38295. }
  38296. /**
  38297. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38298. * @return boolean
  38299. */
  38300. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  38301. {
  38302. $this->currentIndex++;
  38303. return $this->currentIndex == $this->sequenceIndex;
  38304. }
  38305. /**
  38306. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38307. */
  38308. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
  38309. {
  38310. }
  38311. /**
  38312. * Verifies that the current expectation is valid. If everything is OK the
  38313. * code should just return, if not it must throw an exception.
  38314. *
  38315. * @throws PHPUnit_Framework_ExpectationFailedException
  38316. */
  38317. public function verify()
  38318. {
  38319. if ($this->currentIndex < $this->sequenceIndex) {
  38320. throw new PHPUnit_Framework_ExpectationFailedException(
  38321. sprintf(
  38322. 'The expected invocation at index %s was never reached.',
  38323. $this->sequenceIndex
  38324. )
  38325. );
  38326. }
  38327. }
  38328. }
  38329. <?php
  38330. /*
  38331. * This file is part of the PHPUnit_MockObject package.
  38332. *
  38333. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38334. *
  38335. * For the full copyright and license information, please view the LICENSE
  38336. * file that was distributed with this source code.
  38337. */
  38338. /**
  38339. * Invocation matcher which checks if a method has been invoked a certain amount
  38340. * of times.
  38341. * If the number of invocations exceeds the value it will immediately throw an
  38342. * exception,
  38343. * If the number is less it will later be checked in verify() and also throw an
  38344. * exception.
  38345. *
  38346. * @package PHPUnit_MockObject
  38347. * @author Sebastian Bergmann <sebastian@phpunit.de>
  38348. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  38349. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  38350. * @version Release: @package_version@
  38351. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  38352. * @since Class available since Release 1.0.0
  38353. */
  38354. class PHPUnit_Framework_MockObject_Matcher_InvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
  38355. {
  38356. /**
  38357. * @var integer
  38358. */
  38359. protected $expectedCount;
  38360. /**
  38361. * @param integer $expectedCount
  38362. */
  38363. public function __construct($expectedCount)
  38364. {
  38365. $this->expectedCount = $expectedCount;
  38366. }
  38367. /**
  38368. * @return boolean
  38369. */
  38370. public function isNever()
  38371. {
  38372. return $this->expectedCount == 0;
  38373. }
  38374. /**
  38375. * @return string
  38376. */
  38377. public function toString()
  38378. {
  38379. return 'invoked ' . $this->expectedCount . ' time(s)';
  38380. }
  38381. /**
  38382. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38383. * @throws PHPUnit_Framework_ExpectationFailedException
  38384. */
  38385. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
  38386. {
  38387. parent::invoked($invocation);
  38388. $count = $this->getInvocationCount();
  38389. if ($count > $this->expectedCount) {
  38390. $message = $invocation->toString() . ' ';
  38391. switch ($this->expectedCount) {
  38392. case 0: {
  38393. $message .= 'was not expected to be called.';
  38394. }
  38395. break;
  38396. case 1: {
  38397. $message .= 'was not expected to be called more than once.';
  38398. }
  38399. break;
  38400. default: {
  38401. $message .= sprintf(
  38402. 'was not expected to be called more than %d times.',
  38403. $this->expectedCount
  38404. );
  38405. }
  38406. }
  38407. throw new PHPUnit_Framework_ExpectationFailedException($message);
  38408. }
  38409. }
  38410. /**
  38411. * Verifies that the current expectation is valid. If everything is OK the
  38412. * code should just return, if not it must throw an exception.
  38413. *
  38414. * @throws PHPUnit_Framework_ExpectationFailedException
  38415. */
  38416. public function verify()
  38417. {
  38418. $count = $this->getInvocationCount();
  38419. if ($count !== $this->expectedCount) {
  38420. throw new PHPUnit_Framework_ExpectationFailedException(
  38421. sprintf(
  38422. 'Method was expected to be called %d times, ' .
  38423. 'actually called %d times.',
  38424. $this->expectedCount,
  38425. $count
  38426. )
  38427. );
  38428. }
  38429. }
  38430. }
  38431. <?php
  38432. /*
  38433. * This file is part of the PHPUnit_MockObject package.
  38434. *
  38435. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38436. *
  38437. * For the full copyright and license information, please view the LICENSE
  38438. * file that was distributed with this source code.
  38439. */
  38440. /**
  38441. * Invocation matcher which checks if a method has been invoked at least
  38442. * N times.
  38443. *
  38444. * @package PHPUnit_MockObject
  38445. * @author Sebastian Bergmann <sebastian@phpunit.de>
  38446. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  38447. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  38448. * @version Release: @package_version@
  38449. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  38450. * @since Class available since Release 2.2.0
  38451. */
  38452. class PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
  38453. {
  38454. /**
  38455. * @var integer
  38456. */
  38457. private $allowedInvocations;
  38458. /**
  38459. * @param integer $allowedInvocations
  38460. */
  38461. public function __construct($allowedInvocations)
  38462. {
  38463. $this->allowedInvocations = $allowedInvocations;
  38464. }
  38465. /**
  38466. * @return string
  38467. */
  38468. public function toString()
  38469. {
  38470. return 'invoked at most ' . $this->allowedInvocations . ' times';
  38471. }
  38472. /**
  38473. * Verifies that the current expectation is valid. If everything is OK the
  38474. * code should just return, if not it must throw an exception.
  38475. *
  38476. * @throws PHPUnit_Framework_ExpectationFailedException
  38477. */
  38478. public function verify()
  38479. {
  38480. $count = $this->getInvocationCount();
  38481. if ($count > $this->allowedInvocations) {
  38482. throw new PHPUnit_Framework_ExpectationFailedException(
  38483. 'Expected invocation at most ' . $this->allowedInvocations .
  38484. ' times but it occured ' . $count . ' time(s).'
  38485. );
  38486. }
  38487. }
  38488. }
  38489. <?php
  38490. /*
  38491. * This file is part of the PHPUnit_MockObject package.
  38492. *
  38493. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38494. *
  38495. * For the full copyright and license information, please view the LICENSE
  38496. * file that was distributed with this source code.
  38497. */
  38498. /**
  38499. * Records invocations and provides convenience methods for checking them later
  38500. * on.
  38501. * This abstract class can be implemented by matchers which needs to check the
  38502. * number of times an invocation has occured.
  38503. *
  38504. * @package PHPUnit_MockObject
  38505. * @author Sebastian Bergmann <sebastian@phpunit.de>
  38506. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  38507. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  38508. * @version Release: @package_version@
  38509. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  38510. * @since Class available since Release 1.0.0
  38511. * @abstract
  38512. */
  38513. abstract class PHPUnit_Framework_MockObject_Matcher_InvokedRecorder implements PHPUnit_Framework_MockObject_Matcher_Invocation
  38514. {
  38515. /**
  38516. * @var PHPUnit_Framework_MockObject_Invocation[]
  38517. */
  38518. protected $invocations = array();
  38519. /**
  38520. * @return integer
  38521. */
  38522. public function getInvocationCount()
  38523. {
  38524. return count($this->invocations);
  38525. }
  38526. /**
  38527. * @return PHPUnit_Framework_MockObject_Invocation[]
  38528. */
  38529. public function getInvocations()
  38530. {
  38531. return $this->invocations;
  38532. }
  38533. /**
  38534. * @return boolean
  38535. */
  38536. public function hasBeenInvoked()
  38537. {
  38538. return count($this->invocations) > 0;
  38539. }
  38540. /**
  38541. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38542. */
  38543. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
  38544. {
  38545. $this->invocations[] = $invocation;
  38546. }
  38547. /**
  38548. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38549. * @return boolean
  38550. */
  38551. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  38552. {
  38553. return true;
  38554. }
  38555. }
  38556. <?php
  38557. /*
  38558. * This file is part of the PHPUnit_MockObject package.
  38559. *
  38560. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38561. *
  38562. * For the full copyright and license information, please view the LICENSE
  38563. * file that was distributed with this source code.
  38564. */
  38565. /**
  38566. * Invocation matcher which does not care about previous state from earlier
  38567. * invocations.
  38568. *
  38569. * This abstract class can be implemented by matchers which does not care about
  38570. * state but only the current run-time value of the invocation itself.
  38571. *
  38572. * @package PHPUnit_MockObject
  38573. * @author Sebastian Bergmann <sebastian@phpunit.de>
  38574. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  38575. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  38576. * @version Release: @package_version@
  38577. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  38578. * @since Class available since Release 1.0.0
  38579. * @abstract
  38580. */
  38581. abstract class PHPUnit_Framework_MockObject_Matcher_StatelessInvocation implements PHPUnit_Framework_MockObject_Matcher_Invocation
  38582. {
  38583. /**
  38584. * Registers the invocation $invocation in the object as being invoked.
  38585. * This will only occur after matches() returns true which means the
  38586. * current invocation is the correct one.
  38587. *
  38588. * The matcher can store information from the invocation which can later
  38589. * be checked in verify(), or it can check the values directly and throw
  38590. * and exception if an expectation is not met.
  38591. *
  38592. * If the matcher is a stub it will also have a return value.
  38593. *
  38594. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38595. * Object containing information on a mocked or stubbed method which
  38596. * was invoked.
  38597. * @return mixed
  38598. */
  38599. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
  38600. {
  38601. }
  38602. /**
  38603. * Checks if the invocation $invocation matches the current rules. If it does
  38604. * the matcher will get the invoked() method called which should check if an
  38605. * expectation is met.
  38606. *
  38607. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38608. * Object containing information on a mocked or stubbed method which
  38609. * was invoked.
  38610. * @return bool
  38611. */
  38612. public function verify()
  38613. {
  38614. }
  38615. }
  38616. <?php
  38617. /*
  38618. * This file is part of the PHPUnit_MockObject package.
  38619. *
  38620. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38621. *
  38622. * For the full copyright and license information, please view the LICENSE
  38623. * file that was distributed with this source code.
  38624. */
  38625. use Doctrine\Instantiator\Instantiator;
  38626. use Doctrine\Instantiator\Exception\InvalidArgumentException as InstantiatorInvalidArgumentException;
  38627. use Doctrine\Instantiator\Exception\UnexpectedValueException as InstantiatorUnexpectedValueException;
  38628. if (!function_exists('trait_exists')) {
  38629. function trait_exists($traitname, $autoload = true)
  38630. {
  38631. return false;
  38632. }
  38633. }
  38634. /**
  38635. * Mock Object Code Generator
  38636. *
  38637. * @package PHPUnit_MockObject
  38638. * @author Sebastian Bergmann <sebastian@phpunit.de>
  38639. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  38640. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  38641. * @version Release: @package_version@
  38642. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  38643. * @since Class available since Release 1.0.0
  38644. */
  38645. class PHPUnit_Framework_MockObject_Generator
  38646. {
  38647. /**
  38648. * @var array
  38649. */
  38650. private static $cache = array();
  38651. /**
  38652. * @var array
  38653. */
  38654. protected $blacklistedMethodNames = array(
  38655. '__CLASS__' => true,
  38656. '__DIR__' => true,
  38657. '__FILE__' => true,
  38658. '__FUNCTION__' => true,
  38659. '__LINE__' => true,
  38660. '__METHOD__' => true,
  38661. '__NAMESPACE__' => true,
  38662. '__TRAIT__' => true,
  38663. '__clone' => true,
  38664. '__halt_compiler' => true,
  38665. 'abstract' => true,
  38666. 'and' => true,
  38667. 'array' => true,
  38668. 'as' => true,
  38669. 'break' => true,
  38670. 'callable' => true,
  38671. 'case' => true,
  38672. 'catch' => true,
  38673. 'class' => true,
  38674. 'clone' => true,
  38675. 'const' => true,
  38676. 'continue' => true,
  38677. 'declare' => true,
  38678. 'default' => true,
  38679. 'die' => true,
  38680. 'do' => true,
  38681. 'echo' => true,
  38682. 'else' => true,
  38683. 'elseif' => true,
  38684. 'empty' => true,
  38685. 'enddeclare' => true,
  38686. 'endfor' => true,
  38687. 'endforeach' => true,
  38688. 'endif' => true,
  38689. 'endswitch' => true,
  38690. 'endwhile' => true,
  38691. 'eval' => true,
  38692. 'exit' => true,
  38693. 'expects' => true,
  38694. 'extends' => true,
  38695. 'final' => true,
  38696. 'for' => true,
  38697. 'foreach' => true,
  38698. 'function' => true,
  38699. 'global' => true,
  38700. 'goto' => true,
  38701. 'if' => true,
  38702. 'implements' => true,
  38703. 'include' => true,
  38704. 'include_once' => true,
  38705. 'instanceof' => true,
  38706. 'insteadof' => true,
  38707. 'interface' => true,
  38708. 'isset' => true,
  38709. 'list' => true,
  38710. 'namespace' => true,
  38711. 'new' => true,
  38712. 'or' => true,
  38713. 'print' => true,
  38714. 'private' => true,
  38715. 'protected' => true,
  38716. 'public' => true,
  38717. 'require' => true,
  38718. 'require_once' => true,
  38719. 'return' => true,
  38720. 'static' => true,
  38721. 'switch' => true,
  38722. 'throw' => true,
  38723. 'trait' => true,
  38724. 'try' => true,
  38725. 'unset' => true,
  38726. 'use' => true,
  38727. 'var' => true,
  38728. 'while' => true,
  38729. 'xor' => true
  38730. );
  38731. /**
  38732. * @var boolean
  38733. */
  38734. protected $soapLoaded = null;
  38735. /**
  38736. * Returns a mock object for the specified class.
  38737. *
  38738. * @param array|string $type
  38739. * @param array $methods
  38740. * @param array $arguments
  38741. * @param string $mockClassName
  38742. * @param boolean $callOriginalConstructor
  38743. * @param boolean $callOriginalClone
  38744. * @param boolean $callAutoload
  38745. * @param boolean $cloneArguments
  38746. * @param boolean $callOriginalMethods
  38747. * @param object $proxyTarget
  38748. * @return object
  38749. * @throws InvalidArgumentException
  38750. * @throws PHPUnit_Framework_Exception
  38751. * @throws PHPUnit_Framework_MockObject_RuntimeException
  38752. * @since Method available since Release 1.0.0
  38753. */
  38754. public function getMock($type, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = true, $callOriginalMethods = false, $proxyTarget = null)
  38755. {
  38756. if (!is_array($type) && !is_string($type)) {
  38757. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'array or string');
  38758. }
  38759. if (!is_string($mockClassName)) {
  38760. throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'string');
  38761. }
  38762. if (!is_array($methods) && !is_null($methods)) {
  38763. throw new InvalidArgumentException;
  38764. }
  38765. if ($type === 'Traversable' || $type === '\\Traversable') {
  38766. $type = 'Iterator';
  38767. }
  38768. if (is_array($type)) {
  38769. $type = array_unique(array_map(
  38770. function ($type) {
  38771. if ($type === 'Traversable' ||
  38772. $type === '\\Traversable' ||
  38773. $type === '\\Iterator') {
  38774. return 'Iterator';
  38775. }
  38776. return $type;
  38777. },
  38778. $type
  38779. ));
  38780. }
  38781. if (null !== $methods) {
  38782. foreach ($methods as $method) {
  38783. if (!preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*~', $method)) {
  38784. throw new PHPUnit_Framework_Exception(
  38785. sprintf(
  38786. 'Cannot stub or mock method with invalid name "%s"',
  38787. $method
  38788. )
  38789. );
  38790. }
  38791. }
  38792. if ($methods != array_unique($methods)) {
  38793. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38794. sprintf(
  38795. 'Cannot stub or mock using a method list that contains duplicates: "%s"',
  38796. implode(', ', $methods)
  38797. )
  38798. );
  38799. }
  38800. }
  38801. if ($mockClassName != '' && class_exists($mockClassName, false)) {
  38802. $reflect = new ReflectionClass($mockClassName);
  38803. if (!$reflect->implementsInterface("PHPUnit_Framework_MockObject_MockObject")) {
  38804. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38805. sprintf(
  38806. 'Class "%s" already exists.',
  38807. $mockClassName
  38808. )
  38809. );
  38810. }
  38811. }
  38812. $mock = $this->generate(
  38813. $type,
  38814. $methods,
  38815. $mockClassName,
  38816. $callOriginalClone,
  38817. $callAutoload,
  38818. $cloneArguments,
  38819. $callOriginalMethods
  38820. );
  38821. return $this->getObject(
  38822. $mock['code'],
  38823. $mock['mockClassName'],
  38824. $type,
  38825. $callOriginalConstructor,
  38826. $callAutoload,
  38827. $arguments,
  38828. $callOriginalMethods,
  38829. $proxyTarget
  38830. );
  38831. }
  38832. /**
  38833. * @param string $code
  38834. * @param string $className
  38835. * @param array|string $type
  38836. * @param boolean $callOriginalConstructor
  38837. * @param boolean $callAutoload
  38838. * @param array $arguments
  38839. * @param boolean $callOriginalMethods
  38840. * @param object $proxyTarget
  38841. * @return object
  38842. */
  38843. protected function getObject($code, $className, $type = '', $callOriginalConstructor = false, $callAutoload = false, array $arguments = array(), $callOriginalMethods = false, $proxyTarget = null)
  38844. {
  38845. $this->evalClass($code, $className);
  38846. if ($callOriginalConstructor &&
  38847. is_string($type) &&
  38848. !interface_exists($type, $callAutoload)) {
  38849. if (count($arguments) == 0) {
  38850. $object = new $className;
  38851. } else {
  38852. $class = new ReflectionClass($className);
  38853. $object = $class->newInstanceArgs($arguments);
  38854. }
  38855. } else {
  38856. try {
  38857. $instantiator = new Instantiator;
  38858. $object = $instantiator->instantiate($className);
  38859. } catch (InstantiatorUnexpectedValueException $exception) {
  38860. if ($exception->getPrevious()) {
  38861. $exception = $exception->getPrevious();
  38862. }
  38863. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38864. $exception->getMessage()
  38865. );
  38866. } catch (InstantiatorInvalidArgumentException $exception) {
  38867. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38868. $exception->getMessage()
  38869. );
  38870. }
  38871. }
  38872. if ($callOriginalMethods) {
  38873. if (!is_object($proxyTarget)) {
  38874. if (count($arguments) == 0) {
  38875. $proxyTarget = new $type;
  38876. } else {
  38877. $class = new ReflectionClass($type);
  38878. $proxyTarget = $class->newInstanceArgs($arguments);
  38879. }
  38880. }
  38881. $object->__phpunit_setOriginalObject($proxyTarget);
  38882. }
  38883. return $object;
  38884. }
  38885. /**
  38886. * @param string $code
  38887. * @param string $className
  38888. */
  38889. protected function evalClass($code, $className)
  38890. {
  38891. if (!class_exists($className, false)) {
  38892. eval($code);
  38893. }
  38894. }
  38895. /**
  38896. * Returns a mock object for the specified abstract class with all abstract
  38897. * methods of the class mocked. Concrete methods to mock can be specified with
  38898. * the last parameter
  38899. *
  38900. * @param string $originalClassName
  38901. * @param array $arguments
  38902. * @param string $mockClassName
  38903. * @param boolean $callOriginalConstructor
  38904. * @param boolean $callOriginalClone
  38905. * @param boolean $callAutoload
  38906. * @param array $mockedMethods
  38907. * @param boolean $cloneArguments
  38908. * @return object
  38909. * @since Method available since Release 1.0.0
  38910. * @throws PHPUnit_Framework_MockObject_RuntimeException
  38911. * @throws PHPUnit_Framework_Exception
  38912. */
  38913. public function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = true)
  38914. {
  38915. if (!is_string($originalClassName)) {
  38916. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  38917. }
  38918. if (!is_string($mockClassName)) {
  38919. throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string');
  38920. }
  38921. if (class_exists($originalClassName, $callAutoload) ||
  38922. interface_exists($originalClassName, $callAutoload)) {
  38923. $reflector = new ReflectionClass($originalClassName);
  38924. $methods = $mockedMethods;
  38925. foreach ($reflector->getMethods(ReflectionMethod::IS_ABSTRACT) as $method) {
  38926. if (!in_array($method->getName(), $methods)) {
  38927. $methods[] = $method->getName();
  38928. }
  38929. }
  38930. if (empty($methods)) {
  38931. $methods = null;
  38932. }
  38933. return $this->getMock(
  38934. $originalClassName,
  38935. $methods,
  38936. $arguments,
  38937. $mockClassName,
  38938. $callOriginalConstructor,
  38939. $callOriginalClone,
  38940. $callAutoload,
  38941. $cloneArguments
  38942. );
  38943. } else {
  38944. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38945. sprintf('Class "%s" does not exist.', $originalClassName)
  38946. );
  38947. }
  38948. }
  38949. /**
  38950. * Returns a mock object for the specified trait with all abstract methods
  38951. * of the trait mocked. Concrete methods to mock can be specified with the
  38952. * `$mockedMethods` parameter.
  38953. *
  38954. * @param string $traitName
  38955. * @param array $arguments
  38956. * @param string $mockClassName
  38957. * @param boolean $callOriginalConstructor
  38958. * @param boolean $callOriginalClone
  38959. * @param boolean $callAutoload
  38960. * @param array $mockedMethods
  38961. * @param boolean $cloneArguments
  38962. * @return object
  38963. * @since Method available since Release 1.2.3
  38964. * @throws PHPUnit_Framework_MockObject_RuntimeException
  38965. * @throws PHPUnit_Framework_Exception
  38966. */
  38967. public function getMockForTrait($traitName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = true)
  38968. {
  38969. if (!is_string($traitName)) {
  38970. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  38971. }
  38972. if (!is_string($mockClassName)) {
  38973. throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string');
  38974. }
  38975. if (!trait_exists($traitName, $callAutoload)) {
  38976. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38977. sprintf(
  38978. 'Trait "%s" does not exist.',
  38979. $traitName
  38980. )
  38981. );
  38982. }
  38983. $className = $this->generateClassName(
  38984. $traitName,
  38985. '',
  38986. 'Trait_'
  38987. );
  38988. $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
  38989. DIRECTORY_SEPARATOR;
  38990. $classTemplate = new Text_Template(
  38991. $templateDir . 'trait_class.tpl'
  38992. );
  38993. $classTemplate->setVar(
  38994. array(
  38995. 'prologue' => 'abstract ',
  38996. 'class_name' => $className['className'],
  38997. 'trait_name' => $traitName
  38998. )
  38999. );
  39000. $this->evalClass(
  39001. $classTemplate->render(),
  39002. $className['className']
  39003. );
  39004. return $this->getMockForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
  39005. }
  39006. /**
  39007. * Returns an object for the specified trait.
  39008. *
  39009. * @param string $traitName
  39010. * @param array $arguments
  39011. * @param string $traitClassName
  39012. * @param boolean $callOriginalConstructor
  39013. * @param boolean $callOriginalClone
  39014. * @param boolean $callAutoload
  39015. * @return object
  39016. * @since Method available since Release 1.1.0
  39017. * @throws PHPUnit_Framework_MockObject_RuntimeException
  39018. * @throws PHPUnit_Framework_Exception
  39019. */
  39020. public function getObjectForTrait($traitName, array $arguments = array(), $traitClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true)
  39021. {
  39022. if (!is_string($traitName)) {
  39023. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  39024. }
  39025. if (!is_string($traitClassName)) {
  39026. throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string');
  39027. }
  39028. if (!trait_exists($traitName, $callAutoload)) {
  39029. throw new PHPUnit_Framework_MockObject_RuntimeException(
  39030. sprintf(
  39031. 'Trait "%s" does not exist.',
  39032. $traitName
  39033. )
  39034. );
  39035. }
  39036. $className = $this->generateClassName(
  39037. $traitName,
  39038. $traitClassName,
  39039. 'Trait_'
  39040. );
  39041. $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
  39042. DIRECTORY_SEPARATOR;
  39043. $classTemplate = new Text_Template(
  39044. $templateDir . 'trait_class.tpl'
  39045. );
  39046. $classTemplate->setVar(
  39047. array(
  39048. 'prologue' => '',
  39049. 'class_name' => $className['className'],
  39050. 'trait_name' => $traitName
  39051. )
  39052. );
  39053. return $this->getObject(
  39054. $classTemplate->render(),
  39055. $className['className']
  39056. );
  39057. }
  39058. /**
  39059. * @param array|string $type
  39060. * @param array $methods
  39061. * @param string $mockClassName
  39062. * @param boolean $callOriginalClone
  39063. * @param boolean $callAutoload
  39064. * @param boolean $cloneArguments
  39065. * @param boolean $callOriginalMethods
  39066. * @return array
  39067. */
  39068. public function generate($type, array $methods = null, $mockClassName = '', $callOriginalClone = true, $callAutoload = true, $cloneArguments = true, $callOriginalMethods = false)
  39069. {
  39070. if (is_array($type)) {
  39071. sort($type);
  39072. }
  39073. if ($mockClassName == '') {
  39074. $key = md5(
  39075. is_array($type) ? join('_', $type) : $type .
  39076. serialize($methods) .
  39077. serialize($callOriginalClone) .
  39078. serialize($cloneArguments) .
  39079. serialize($callOriginalMethods)
  39080. );
  39081. if (isset(self::$cache[$key])) {
  39082. return self::$cache[$key];
  39083. }
  39084. }
  39085. $mock = $this->generateMock(
  39086. $type,
  39087. $methods,
  39088. $mockClassName,
  39089. $callOriginalClone,
  39090. $callAutoload,
  39091. $cloneArguments,
  39092. $callOriginalMethods
  39093. );
  39094. if (isset($key)) {
  39095. self::$cache[$key] = $mock;
  39096. }
  39097. return $mock;
  39098. }
  39099. /**
  39100. * @param string $wsdlFile
  39101. * @param string $className
  39102. * @param array $methods
  39103. * @param array $options
  39104. * @return string
  39105. * @throws PHPUnit_Framework_MockObject_RuntimeException
  39106. */
  39107. public function generateClassFromWsdl($wsdlFile, $className, array $methods = array(), array $options = array())
  39108. {
  39109. if ($this->soapLoaded === null) {
  39110. $this->soapLoaded = extension_loaded('soap');
  39111. }
  39112. if ($this->soapLoaded) {
  39113. $options = array_merge($options, array('cache_wsdl' => WSDL_CACHE_NONE));
  39114. $client = new SoapClient($wsdlFile, $options);
  39115. $_methods = array_unique($client->__getFunctions());
  39116. unset($client);
  39117. sort($_methods);
  39118. $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR .
  39119. 'Generator' . DIRECTORY_SEPARATOR;
  39120. $methodTemplate = new Text_Template(
  39121. $templateDir . 'wsdl_method.tpl'
  39122. );
  39123. $methodsBuffer = '';
  39124. foreach ($_methods as $method) {
  39125. $nameStart = strpos($method, ' ') + 1;
  39126. $nameEnd = strpos($method, '(');
  39127. $name = substr($method, $nameStart, $nameEnd - $nameStart);
  39128. if (empty($methods) || in_array($name, $methods)) {
  39129. $args = explode(
  39130. ',',
  39131. substr(
  39132. $method,
  39133. $nameEnd + 1,
  39134. strpos($method, ')') - $nameEnd - 1
  39135. )
  39136. );
  39137. $numArgs = count($args);
  39138. for ($i = 0; $i < $numArgs; $i++) {
  39139. $args[$i] = substr($args[$i], strpos($args[$i], '$'));
  39140. }
  39141. $methodTemplate->setVar(
  39142. array(
  39143. 'method_name' => $name,
  39144. 'arguments' => join(', ', $args)
  39145. )
  39146. );
  39147. $methodsBuffer .= $methodTemplate->render();
  39148. }
  39149. }
  39150. $optionsBuffer = 'array(';
  39151. foreach ($options as $key => $value) {
  39152. $optionsBuffer .= $key . ' => ' . $value;
  39153. }
  39154. $optionsBuffer .= ')';
  39155. $classTemplate = new Text_Template(
  39156. $templateDir . 'wsdl_class.tpl'
  39157. );
  39158. $namespace = '';
  39159. if (strpos($className, '\\') !== false) {
  39160. $parts = explode('\\', $className);
  39161. $className = array_pop($parts);
  39162. $namespace = 'namespace ' . join('\\', $parts) . ';' . "\n\n";
  39163. }
  39164. $classTemplate->setVar(
  39165. array(
  39166. 'namespace' => $namespace,
  39167. 'class_name' => $className,
  39168. 'wsdl' => $wsdlFile,
  39169. 'options' => $optionsBuffer,
  39170. 'methods' => $methodsBuffer
  39171. )
  39172. );
  39173. return $classTemplate->render();
  39174. } else {
  39175. throw new PHPUnit_Framework_MockObject_RuntimeException(
  39176. 'The SOAP extension is required to generate a mock object ' .
  39177. 'from WSDL.'
  39178. );
  39179. }
  39180. }
  39181. /**
  39182. * @param array|string $type
  39183. * @param array|null $methods
  39184. * @param string $mockClassName
  39185. * @param boolean $callOriginalClone
  39186. * @param boolean $callAutoload
  39187. * @param boolean $cloneArguments
  39188. * @param boolean $callOriginalMethods
  39189. * @return array
  39190. * @throws PHPUnit_Framework_Exception
  39191. */
  39192. protected function generateMock($type, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods)
  39193. {
  39194. $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
  39195. DIRECTORY_SEPARATOR;
  39196. $classTemplate = new Text_Template(
  39197. $templateDir . 'mocked_class.tpl'
  39198. );
  39199. $additionalInterfaces = array();
  39200. $cloneTemplate = '';
  39201. $isClass = false;
  39202. $isInterface = false;
  39203. $mockClassName = $this->generateClassName(
  39204. $type,
  39205. $mockClassName,
  39206. 'Mock_'
  39207. );
  39208. if (is_array($type)) {
  39209. foreach ($type as $_type) {
  39210. if (!interface_exists($_type, $callAutoload)) {
  39211. throw new PHPUnit_Framework_Exception(
  39212. sprintf(
  39213. 'Interface "%s" does not exist.',
  39214. $_type
  39215. )
  39216. );
  39217. }
  39218. $additionalInterfaces[] = $_type;
  39219. foreach ($this->getClassMethods($_type) as $method) {
  39220. if (in_array($method, $methods)) {
  39221. throw new PHPUnit_Framework_Exception(
  39222. sprintf(
  39223. 'Duplicate method "%s" not allowed.',
  39224. $method
  39225. )
  39226. );
  39227. }
  39228. $methods[] = $method;
  39229. }
  39230. }
  39231. }
  39232. if (class_exists($mockClassName['fullClassName'], $callAutoload)) {
  39233. $isClass = true;
  39234. } else {
  39235. if (interface_exists($mockClassName['fullClassName'], $callAutoload)) {
  39236. $isInterface = true;
  39237. }
  39238. }
  39239. if (!class_exists($mockClassName['fullClassName'], $callAutoload) &&
  39240. !interface_exists($mockClassName['fullClassName'], $callAutoload)) {
  39241. $prologue = 'class ' . $mockClassName['originalClassName'] . "\n{\n}\n\n";
  39242. if (!empty($mockClassName['namespaceName'])) {
  39243. $prologue = 'namespace ' . $mockClassName['namespaceName'] .
  39244. " {\n\n" . $prologue . "}\n\n" .
  39245. "namespace {\n\n";
  39246. $epilogue = "\n\n}";
  39247. }
  39248. $cloneTemplate = new Text_Template(
  39249. $templateDir . 'mocked_clone.tpl'
  39250. );
  39251. } else {
  39252. $class = new ReflectionClass($mockClassName['fullClassName']);
  39253. if ($class->isFinal()) {
  39254. throw new PHPUnit_Framework_Exception(
  39255. sprintf(
  39256. 'Class "%s" is declared "final" and cannot be mocked.',
  39257. $mockClassName['fullClassName']
  39258. )
  39259. );
  39260. }
  39261. if ($class->hasMethod('__clone')) {
  39262. $cloneMethod = $class->getMethod('__clone');
  39263. if (!$cloneMethod->isFinal()) {
  39264. if ($callOriginalClone && !$isInterface) {
  39265. $cloneTemplate = new Text_Template(
  39266. $templateDir . 'unmocked_clone.tpl'
  39267. );
  39268. } else {
  39269. $cloneTemplate = new Text_Template(
  39270. $templateDir . 'mocked_clone.tpl'
  39271. );
  39272. }
  39273. }
  39274. } else {
  39275. $cloneTemplate = new Text_Template(
  39276. $templateDir . 'mocked_clone.tpl'
  39277. );
  39278. }
  39279. }
  39280. if (is_object($cloneTemplate)) {
  39281. $cloneTemplate = $cloneTemplate->render();
  39282. }
  39283. if (is_array($methods) && empty($methods) &&
  39284. ($isClass || $isInterface)) {
  39285. $methods = $this->getClassMethods($mockClassName['fullClassName']);
  39286. }
  39287. if (!is_array($methods)) {
  39288. $methods = array();
  39289. }
  39290. $mockedMethods = '';
  39291. if (isset($class)) {
  39292. // https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103
  39293. if ($isInterface && $class->implementsInterface('Traversable') &&
  39294. !$class->implementsInterface('Iterator') &&
  39295. !$class->implementsInterface('IteratorAggregate')) {
  39296. $additionalInterfaces[] = 'Iterator';
  39297. $methods = array_merge($methods, $this->getClassMethods('Iterator'));
  39298. }
  39299. foreach ($methods as $methodName) {
  39300. try {
  39301. $method = $class->getMethod($methodName);
  39302. if ($this->canMockMethod($method)) {
  39303. $mockedMethods .= $this->generateMockedMethodDefinitionFromExisting(
  39304. $templateDir,
  39305. $method,
  39306. $cloneArguments,
  39307. $callOriginalMethods
  39308. );
  39309. }
  39310. } catch (ReflectionException $e) {
  39311. $mockedMethods .= $this->generateMockedMethodDefinition(
  39312. $templateDir,
  39313. $mockClassName['fullClassName'],
  39314. $methodName,
  39315. $cloneArguments
  39316. );
  39317. }
  39318. }
  39319. } else {
  39320. foreach ($methods as $methodName) {
  39321. $mockedMethods .= $this->generateMockedMethodDefinition(
  39322. $templateDir,
  39323. $mockClassName['fullClassName'],
  39324. $methodName,
  39325. $cloneArguments
  39326. );
  39327. }
  39328. }
  39329. $method = '';
  39330. if (!in_array('method', $methods)) {
  39331. $methodTemplate = new Text_Template(
  39332. $templateDir . 'mocked_class_method.tpl'
  39333. );
  39334. $method = $methodTemplate->render();
  39335. }
  39336. $classTemplate->setVar(
  39337. array(
  39338. 'prologue' => isset($prologue) ? $prologue : '',
  39339. 'epilogue' => isset($epilogue) ? $epilogue : '',
  39340. 'class_declaration' => $this->generateMockClassDeclaration(
  39341. $mockClassName,
  39342. $isInterface,
  39343. $additionalInterfaces
  39344. ),
  39345. 'clone' => $cloneTemplate,
  39346. 'mock_class_name' => $mockClassName['className'],
  39347. 'mocked_methods' => $mockedMethods,
  39348. 'method' => $method
  39349. )
  39350. );
  39351. return array(
  39352. 'code' => $classTemplate->render(),
  39353. 'mockClassName' => $mockClassName['className']
  39354. );
  39355. }
  39356. /**
  39357. * @param array|string $type
  39358. * @param string $className
  39359. * @param string $prefix
  39360. * @return array
  39361. */
  39362. protected function generateClassName($type, $className, $prefix)
  39363. {
  39364. if (is_array($type)) {
  39365. $type = join('_', $type);
  39366. }
  39367. if ($type[0] == '\\') {
  39368. $type = substr($type, 1);
  39369. }
  39370. $classNameParts = explode('\\', $type);
  39371. if (count($classNameParts) > 1) {
  39372. $type = array_pop($classNameParts);
  39373. $namespaceName = join('\\', $classNameParts);
  39374. $fullClassName = $namespaceName . '\\' . $type;
  39375. } else {
  39376. $namespaceName = '';
  39377. $fullClassName = $type;
  39378. }
  39379. if ($className == '') {
  39380. do {
  39381. $className = $prefix . $type . '_' .
  39382. substr(md5(microtime()), 0, 8);
  39383. } while (class_exists($className, false));
  39384. }
  39385. return array(
  39386. 'className' => $className,
  39387. 'originalClassName' => $type,
  39388. 'fullClassName' => $fullClassName,
  39389. 'namespaceName' => $namespaceName
  39390. );
  39391. }
  39392. /**
  39393. * @param array $mockClassName
  39394. * @param boolean $isInterface
  39395. * @param array $additionalInterfaces
  39396. * @return array
  39397. */
  39398. protected function generateMockClassDeclaration(array $mockClassName, $isInterface, array $additionalInterfaces = array())
  39399. {
  39400. $buffer = 'class ';
  39401. $additionalInterfaces[] = 'PHPUnit_Framework_MockObject_MockObject';
  39402. $interfaces = implode(', ', $additionalInterfaces);
  39403. if ($isInterface) {
  39404. $buffer .= sprintf(
  39405. "%s implements %s",
  39406. $mockClassName['className'],
  39407. $interfaces
  39408. );
  39409. if (!in_array($mockClassName['originalClassName'], $additionalInterfaces)) {
  39410. $buffer .= ', ';
  39411. if (!empty($mockClassName['namespaceName'])) {
  39412. $buffer .= $mockClassName['namespaceName'] . '\\';
  39413. }
  39414. $buffer .= $mockClassName['originalClassName'];
  39415. }
  39416. } else {
  39417. $buffer .= sprintf(
  39418. "%s extends %s%s implements %s",
  39419. $mockClassName['className'],
  39420. !empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '',
  39421. $mockClassName['originalClassName'],
  39422. $interfaces
  39423. );
  39424. }
  39425. return $buffer;
  39426. }
  39427. /**
  39428. * @param string $templateDir
  39429. * @param ReflectionMethod $method
  39430. * @param boolean $cloneArguments
  39431. * @param boolean $callOriginalMethods
  39432. * @return string
  39433. */
  39434. protected function generateMockedMethodDefinitionFromExisting($templateDir, ReflectionMethod $method, $cloneArguments, $callOriginalMethods)
  39435. {
  39436. if ($method->isPrivate()) {
  39437. $modifier = 'private';
  39438. } elseif ($method->isProtected()) {
  39439. $modifier = 'protected';
  39440. } else {
  39441. $modifier = 'public';
  39442. }
  39443. if ($method->isStatic()) {
  39444. $modifier .= ' static';
  39445. }
  39446. if ($method->returnsReference()) {
  39447. $reference = '&';
  39448. } else {
  39449. $reference = '';
  39450. }
  39451. return $this->generateMockedMethodDefinition(
  39452. $templateDir,
  39453. $method->getDeclaringClass()->getName(),
  39454. $method->getName(),
  39455. $cloneArguments,
  39456. $modifier,
  39457. $this->getMethodParameters($method),
  39458. $this->getMethodParameters($method, true),
  39459. $reference,
  39460. $callOriginalMethods,
  39461. $method->isStatic()
  39462. );
  39463. }
  39464. /**
  39465. * @param string $templateDir
  39466. * @param string $className
  39467. * @param string $methodName
  39468. * @param boolean $cloneArguments
  39469. * @param string $modifier
  39470. * @param string $arguments_decl
  39471. * @param string $arguments_call
  39472. * @param string $reference
  39473. * @param boolean $callOriginalMethods
  39474. * @param boolean $static
  39475. * @return string
  39476. */
  39477. protected function generateMockedMethodDefinition($templateDir, $className, $methodName, $cloneArguments = true, $modifier = 'public', $arguments_decl = '', $arguments_call = '', $reference = '', $callOriginalMethods = false, $static = false)
  39478. {
  39479. if ($static) {
  39480. $templateFile = 'mocked_static_method.tpl';
  39481. } else {
  39482. $templateFile = sprintf(
  39483. '%s_method.tpl',
  39484. $callOriginalMethods ? 'proxied' : 'mocked'
  39485. );
  39486. }
  39487. $template = new Text_Template($templateDir . $templateFile);
  39488. $template->setVar(
  39489. array(
  39490. 'arguments_decl' => $arguments_decl,
  39491. 'arguments_call' => $arguments_call,
  39492. 'arguments_count' => !empty($arguments_call) ? count(explode(',', $arguments_call)) : 0,
  39493. 'class_name' => $className,
  39494. 'method_name' => $methodName,
  39495. 'modifier' => $modifier,
  39496. 'reference' => $reference,
  39497. 'clone_arguments' => $cloneArguments ? 'TRUE' : 'FALSE'
  39498. )
  39499. );
  39500. return $template->render();
  39501. }
  39502. /**
  39503. * @param ReflectionMethod $method
  39504. * @return boolean
  39505. */
  39506. protected function canMockMethod(ReflectionMethod $method)
  39507. {
  39508. if ($method->isConstructor() ||
  39509. $method->isFinal() ||
  39510. $method->isPrivate() ||
  39511. isset($this->blacklistedMethodNames[$method->getName()])) {
  39512. return false;
  39513. }
  39514. return true;
  39515. }
  39516. /**
  39517. * Returns the parameters of a function or method.
  39518. *
  39519. * @param ReflectionMethod $method
  39520. * @param boolean $forCall
  39521. * @return string
  39522. * @throws PHPUnit_Framework_MockObject_RuntimeException
  39523. * @since Method available since Release 2.0.0
  39524. */
  39525. protected function getMethodParameters(ReflectionMethod $method, $forCall = false)
  39526. {
  39527. $parameters = array();
  39528. foreach ($method->getParameters() as $i => $parameter) {
  39529. $name = '$' . $parameter->getName();
  39530. /* Note: PHP extensions may use empty names for reference arguments
  39531. * or "..." for methods taking a variable number of arguments.
  39532. */
  39533. if ($name === '$' || $name === '$...') {
  39534. $name = '$arg' . $i;
  39535. }
  39536. if ($this->isVariadic($parameter)) {
  39537. if ($forCall) {
  39538. continue;
  39539. } else {
  39540. $name = '...' . $name;
  39541. }
  39542. }
  39543. $default = '';
  39544. $reference = '';
  39545. $typeHint = '';
  39546. if (!$forCall) {
  39547. if ($parameter->isArray()) {
  39548. $typeHint = 'array ';
  39549. } elseif ((defined('HHVM_VERSION') || version_compare(PHP_VERSION, '5.4.0', '>='))
  39550. && $parameter->isCallable()) {
  39551. $typeHint = 'callable ';
  39552. } else {
  39553. try {
  39554. $class = $parameter->getClass();
  39555. } catch (ReflectionException $e) {
  39556. throw new PHPUnit_Framework_MockObject_RuntimeException(
  39557. sprintf(
  39558. 'Cannot mock %s::%s() because a class or ' .
  39559. 'interface used in the signature is not loaded',
  39560. $method->getDeclaringClass()->getName(),
  39561. $method->getName()
  39562. ),
  39563. 0,
  39564. $e
  39565. );
  39566. }
  39567. if ($class !== null) {
  39568. $typeHint = $class->getName() . ' ';
  39569. }
  39570. }
  39571. if (!$this->isVariadic($parameter)) {
  39572. if ($parameter->isDefaultValueAvailable()) {
  39573. $value = $parameter->getDefaultValue();
  39574. $default = ' = ' . var_export($value, true);
  39575. } elseif ($parameter->isOptional()) {
  39576. $default = ' = null';
  39577. }
  39578. }
  39579. }
  39580. if ($parameter->isPassedByReference()) {
  39581. $reference = '&';
  39582. }
  39583. $parameters[] = $typeHint . $reference . $name . $default;
  39584. }
  39585. return join(', ', $parameters);
  39586. }
  39587. /**
  39588. * @param ReflectionParameter $parameter
  39589. * @return boolean
  39590. * @since Method available since Release 2.2.1
  39591. */
  39592. private function isVariadic(ReflectionParameter $parameter)
  39593. {
  39594. return method_exists('ReflectionParameter', 'isVariadic') && $parameter->isVariadic();
  39595. }
  39596. /**
  39597. * @param string $className
  39598. * @return array
  39599. * @since Method available since Release 2.3.2
  39600. */
  39601. private function getClassMethods($className)
  39602. {
  39603. $class = new ReflectionClass($className);
  39604. $methods = array();
  39605. foreach ($class->getMethods() as $method) {
  39606. if ($method->isPublic() || $method->isAbstract()) {
  39607. $methods[] = $method->getName();
  39608. }
  39609. }
  39610. return $methods;
  39611. }
  39612. }
  39613. public function {method_name}({arguments})
  39614. {
  39615. }
  39616. public function __clone()
  39617. {
  39618. $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
  39619. parent::__clone();
  39620. }
  39621. {prologue}{class_declaration}
  39622. {
  39623. private $__phpunit_invocationMocker;
  39624. private $__phpunit_originalObject;
  39625. {clone}{mocked_methods}
  39626. public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
  39627. {
  39628. return $this->__phpunit_getInvocationMocker()->expects($matcher);
  39629. }
  39630. {method}
  39631. public function __phpunit_setOriginalObject($originalObject)
  39632. {
  39633. $this->__phpunit_originalObject = $originalObject;
  39634. }
  39635. public function __phpunit_getInvocationMocker()
  39636. {
  39637. if ($this->__phpunit_invocationMocker === NULL) {
  39638. $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker;
  39639. }
  39640. return $this->__phpunit_invocationMocker;
  39641. }
  39642. public function __phpunit_hasMatchers()
  39643. {
  39644. return $this->__phpunit_getInvocationMocker()->hasMatchers();
  39645. }
  39646. public function __phpunit_verify()
  39647. {
  39648. $this->__phpunit_getInvocationMocker()->verify();
  39649. $this->__phpunit_invocationMocker = NULL;
  39650. }
  39651. }{epilogue}
  39652. public function __clone()
  39653. {
  39654. $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
  39655. }
  39656. {modifier} function {reference}{method_name}({arguments_decl})
  39657. {
  39658. $arguments = array({arguments_call});
  39659. $count = func_num_args();
  39660. if ($count > {arguments_count}) {
  39661. $_arguments = func_get_args();
  39662. for ($i = {arguments_count}; $i < $count; $i++) {
  39663. $arguments[] = $_arguments[$i];
  39664. }
  39665. }
  39666. $this->__phpunit_getInvocationMocker()->invoke(
  39667. new PHPUnit_Framework_MockObject_Invocation_Object(
  39668. '{class_name}', '{method_name}', $arguments, $this, {clone_arguments}
  39669. )
  39670. );
  39671. return call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $arguments);
  39672. }
  39673. {namespace}class {class_name} extends \SoapClient
  39674. {
  39675. public function __construct($wsdl, array $options)
  39676. {
  39677. parent::__construct('{wsdl}', $options);
  39678. }
  39679. {methods}}
  39680. {prologue}class {class_name}
  39681. {
  39682. use {trait_name};
  39683. }
  39684. {modifier} function {reference}{method_name}({arguments_decl})
  39685. {
  39686. $arguments = array({arguments_call});
  39687. $count = func_num_args();
  39688. if ($count > {arguments_count}) {
  39689. $_arguments = func_get_args();
  39690. for ($i = {arguments_count}; $i < $count; $i++) {
  39691. $arguments[] = $_arguments[$i];
  39692. }
  39693. }
  39694. $result = $this->__phpunit_getInvocationMocker()->invoke(
  39695. new PHPUnit_Framework_MockObject_Invocation_Object(
  39696. '{class_name}', '{method_name}', $arguments, $this, {clone_arguments}
  39697. )
  39698. );
  39699. return $result;
  39700. }
  39701. public function method()
  39702. {
  39703. $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
  39704. $expects = $this->expects($any);
  39705. return call_user_func_array(array($expects, 'method'), func_get_args());
  39706. }
  39707. {modifier} function {reference}{method_name}({arguments_decl})
  39708. {
  39709. throw new PHPUnit_Framework_MockObject_BadMethodCallException;
  39710. }
  39711. <?php
  39712. /*
  39713. * This file is part of the PHPUnit_MockObject package.
  39714. *
  39715. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39716. *
  39717. * For the full copyright and license information, please view the LICENSE
  39718. * file that was distributed with this source code.
  39719. */
  39720. /**
  39721. * Builder interface for invocation order matches.
  39722. *
  39723. * @package PHPUnit_MockObject
  39724. * @author Sebastian Bergmann <sebastian@phpunit.de>
  39725. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  39726. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  39727. * @version Release: @package_version@
  39728. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  39729. * @since Interface available since Release 1.0.0
  39730. */
  39731. interface PHPUnit_Framework_MockObject_Builder_Match extends PHPUnit_Framework_MockObject_Builder_Stub
  39732. {
  39733. /**
  39734. * Defines the expectation which must occur before the current is valid.
  39735. *
  39736. * @param string $id The identification of the expectation that should
  39737. * occur before this one.
  39738. * @return PHPUnit_Framework_MockObject_Builder_Stub
  39739. */
  39740. public function after($id);
  39741. }
  39742. <?php
  39743. /*
  39744. * This file is part of the PHPUnit_MockObject package.
  39745. *
  39746. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39747. *
  39748. * For the full copyright and license information, please view the LICENSE
  39749. * file that was distributed with this source code.
  39750. */
  39751. /**
  39752. * Builder interface for unique identifiers.
  39753. *
  39754. * Defines the interface for recording unique identifiers. The identifiers
  39755. * can be used to define the invocation order of expectations. The expectation
  39756. * is recorded using id() and then defined in order using
  39757. * PHPUnit_Framework_MockObject_Builder_Match::after().
  39758. *
  39759. * @package PHPUnit_MockObject
  39760. * @author Sebastian Bergmann <sebastian@phpunit.de>
  39761. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  39762. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  39763. * @version Release: @package_version@
  39764. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  39765. * @since Interface available since Release 1.0.0
  39766. */
  39767. interface PHPUnit_Framework_MockObject_Builder_Identity
  39768. {
  39769. /**
  39770. * Sets the identification of the expectation to $id.
  39771. *
  39772. * @note The identifier is unique per mock object.
  39773. * @param string $id Unique identifiation of expectation.
  39774. */
  39775. public function id($id);
  39776. }
  39777. <?php
  39778. /*
  39779. * This file is part of the PHPUnit_MockObject package.
  39780. *
  39781. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39782. *
  39783. * For the full copyright and license information, please view the LICENSE
  39784. * file that was distributed with this source code.
  39785. */
  39786. /**
  39787. * Builder for mocked or stubbed invocations.
  39788. *
  39789. * Provides methods for building expectations without having to resort to
  39790. * instantiating the various matchers manually. These methods also form a
  39791. * more natural way of reading the expectation. This class should be together
  39792. * with the test case PHPUnit_Framework_MockObject_TestCase.
  39793. *
  39794. * @package PHPUnit_MockObject
  39795. * @author Sebastian Bergmann <sebastian@phpunit.de>
  39796. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  39797. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  39798. * @version Release: @package_version@
  39799. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  39800. * @since Class available since Release 1.0.0
  39801. */
  39802. class PHPUnit_Framework_MockObject_Builder_InvocationMocker implements PHPUnit_Framework_MockObject_Builder_MethodNameMatch
  39803. {
  39804. /**
  39805. * @var PHPUnit_Framework_MockObject_Stub_MatcherCollection
  39806. */
  39807. protected $collection;
  39808. /**
  39809. * @var PHPUnit_Framework_MockObject_Matcher
  39810. */
  39811. protected $matcher;
  39812. /**
  39813. * @param PHPUnit_Framework_MockObject_Stub_MatcherCollection $collection
  39814. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher
  39815. */
  39816. public function __construct(PHPUnit_Framework_MockObject_Stub_MatcherCollection $collection, PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher)
  39817. {
  39818. $this->collection = $collection;
  39819. $this->matcher = new PHPUnit_Framework_MockObject_Matcher(
  39820. $invocationMatcher
  39821. );
  39822. $this->collection->addMatcher($this->matcher);
  39823. }
  39824. /**
  39825. * @return PHPUnit_Framework_MockObject_Matcher
  39826. */
  39827. public function getMatcher()
  39828. {
  39829. return $this->matcher;
  39830. }
  39831. /**
  39832. * @param mixed $id
  39833. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39834. */
  39835. public function id($id)
  39836. {
  39837. $this->collection->registerId($id, $this);
  39838. return $this;
  39839. }
  39840. /**
  39841. * @param PHPUnit_Framework_MockObject_Stub $stub
  39842. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39843. */
  39844. public function will(PHPUnit_Framework_MockObject_Stub $stub)
  39845. {
  39846. $this->matcher->stub = $stub;
  39847. return $this;
  39848. }
  39849. /**
  39850. * @param mixed $value
  39851. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39852. */
  39853. public function willReturn($value)
  39854. {
  39855. $stub = new PHPUnit_Framework_MockObject_Stub_Return(
  39856. $value
  39857. );
  39858. return $this->will($stub);
  39859. }
  39860. /**
  39861. * @param array $valueMap
  39862. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39863. */
  39864. public function willReturnMap(array $valueMap)
  39865. {
  39866. $stub = new PHPUnit_Framework_MockObject_Stub_ReturnValueMap(
  39867. $valueMap
  39868. );
  39869. return $this->will($stub);
  39870. }
  39871. /**
  39872. * @param mixed $argumentIndex
  39873. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39874. */
  39875. public function willReturnArgument($argumentIndex)
  39876. {
  39877. $stub = new PHPUnit_Framework_MockObject_Stub_ReturnArgument(
  39878. $argumentIndex
  39879. );
  39880. return $this->will($stub);
  39881. }
  39882. /**
  39883. * @param callable $callback
  39884. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39885. */
  39886. public function willReturnCallback($callback)
  39887. {
  39888. $stub = new PHPUnit_Framework_MockObject_Stub_ReturnCallback(
  39889. $callback
  39890. );
  39891. return $this->will($stub);
  39892. }
  39893. /**
  39894. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39895. */
  39896. public function willReturnSelf()
  39897. {
  39898. $stub = new PHPUnit_Framework_MockObject_Stub_ReturnSelf();
  39899. return $this->will($stub);
  39900. }
  39901. /**
  39902. * @param mixed $value, ...
  39903. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39904. */
  39905. public function willReturnOnConsecutiveCalls()
  39906. {
  39907. $args = func_get_args();
  39908. $stub = new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args);
  39909. return $this->will($stub);
  39910. }
  39911. /**
  39912. * @param Exception $exception
  39913. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39914. */
  39915. public function willThrowException(Exception $exception)
  39916. {
  39917. $stub = new PHPUnit_Framework_MockObject_Stub_Exception($exception);
  39918. return $this->will($stub);
  39919. }
  39920. /**
  39921. * @param mixed $id
  39922. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39923. */
  39924. public function after($id)
  39925. {
  39926. $this->matcher->afterMatchBuilderId = $id;
  39927. return $this;
  39928. }
  39929. /**
  39930. * Validate that a parameters matcher can be defined, throw exceptions otherwise.
  39931. *
  39932. * @throws PHPUnit_Framework_Exception
  39933. */
  39934. private function canDefineParameters()
  39935. {
  39936. if ($this->matcher->methodNameMatcher === null) {
  39937. throw new PHPUnit_Framework_Exception(
  39938. 'Method name matcher is not defined, cannot define parameter ' .
  39939. ' matcher without one'
  39940. );
  39941. }
  39942. if ($this->matcher->parametersMatcher !== null) {
  39943. throw new PHPUnit_Framework_Exception(
  39944. 'Parameter matcher is already defined, cannot redefine'
  39945. );
  39946. }
  39947. }
  39948. /**
  39949. * @param mixed $argument, ...
  39950. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39951. */
  39952. public function with()
  39953. {
  39954. $args = func_get_args();
  39955. $this->canDefineParameters();
  39956. $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_Parameters($args);
  39957. return $this;
  39958. }
  39959. /**
  39960. * @param mixed ...$argument
  39961. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39962. */
  39963. public function withConsecutive()
  39964. {
  39965. $args = func_get_args();
  39966. $this->canDefineParameters();
  39967. $this->matcher->parametersMatcher =
  39968. new PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters($args);
  39969. return $this;
  39970. }
  39971. /**
  39972. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39973. */
  39974. public function withAnyParameters()
  39975. {
  39976. $this->canDefineParameters();
  39977. $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_AnyParameters;
  39978. return $this;
  39979. }
  39980. /**
  39981. * @param PHPUnit_Framework_Constraint|string $constraint
  39982. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39983. */
  39984. public function method($constraint)
  39985. {
  39986. if ($this->matcher->methodNameMatcher !== null) {
  39987. throw new PHPUnit_Framework_Exception(
  39988. 'Method name matcher is already defined, cannot redefine'
  39989. );
  39990. }
  39991. $this->matcher->methodNameMatcher = new PHPUnit_Framework_MockObject_Matcher_MethodName($constraint);
  39992. return $this;
  39993. }
  39994. }
  39995. <?php
  39996. /*
  39997. * This file is part of the PHPUnit_MockObject package.
  39998. *
  39999. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40000. *
  40001. * For the full copyright and license information, please view the LICENSE
  40002. * file that was distributed with this source code.
  40003. */
  40004. /**
  40005. * Builder interface for parameter matchers.
  40006. *
  40007. * @package PHPUnit_MockObject
  40008. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40009. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40010. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40011. * @version Release: @package_version@
  40012. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40013. * @since Interface available since Release 1.0.0
  40014. */
  40015. interface PHPUnit_Framework_MockObject_Builder_ParametersMatch extends PHPUnit_Framework_MockObject_Builder_Match
  40016. {
  40017. /**
  40018. * Sets the parameters to match for, each parameter to this funtion will
  40019. * be part of match. To perform specific matches or constraints create a
  40020. * new PHPUnit_Framework_Constraint and use it for the parameter.
  40021. * If the parameter value is not a constraint it will use the
  40022. * PHPUnit_Framework_Constraint_IsEqual for the value.
  40023. *
  40024. * Some examples:
  40025. * <code>
  40026. * // match first parameter with value 2
  40027. * $b->with(2);
  40028. * // match first parameter with value 'smock' and second identical to 42
  40029. * $b->with('smock', new PHPUnit_Framework_Constraint_IsEqual(42));
  40030. * </code>
  40031. *
  40032. * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch
  40033. */
  40034. public function with();
  40035. /**
  40036. * Sets a matcher which allows any kind of parameters.
  40037. *
  40038. * Some examples:
  40039. * <code>
  40040. * // match any number of parameters
  40041. * $b->withAnyParamers();
  40042. * </code>
  40043. *
  40044. * @return PHPUnit_Framework_MockObject_Matcher_AnyParameters
  40045. */
  40046. public function withAnyParameters();
  40047. }
  40048. <?php
  40049. /*
  40050. * This file is part of the PHPUnit_MockObject package.
  40051. *
  40052. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40053. *
  40054. * For the full copyright and license information, please view the LICENSE
  40055. * file that was distributed with this source code.
  40056. */
  40057. /**
  40058. * Interface for builders which can register builders with a given identification.
  40059. *
  40060. * This interface relates to PHPUnit_Framework_MockObject_Builder_Identity.
  40061. *
  40062. * @package PHPUnit_MockObject
  40063. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40064. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40065. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40066. * @version Release: @package_version@
  40067. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40068. * @since Interface available since Release 1.0.0
  40069. */
  40070. interface PHPUnit_Framework_MockObject_Builder_Namespace
  40071. {
  40072. /**
  40073. * Looks up the match builder with identification $id and returns it.
  40074. *
  40075. * @param string $id The identifiction of the match builder.
  40076. * @return PHPUnit_Framework_MockObject_Builder_Match
  40077. */
  40078. public function lookupId($id);
  40079. /**
  40080. * Registers the match builder $builder with the identification $id. The
  40081. * builder can later be looked up using lookupId() to figure out if it
  40082. * has been invoked.
  40083. *
  40084. * @param string $id
  40085. * The identification of the match builder.
  40086. * @param PHPUnit_Framework_MockObject_Builder_Match $builder
  40087. * The builder which is being registered.
  40088. */
  40089. public function registerId($id, PHPUnit_Framework_MockObject_Builder_Match $builder);
  40090. }
  40091. <?php
  40092. /*
  40093. * This file is part of the PHPUnit_MockObject package.
  40094. *
  40095. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40096. *
  40097. * For the full copyright and license information, please view the LICENSE
  40098. * file that was distributed with this source code.
  40099. */
  40100. /**
  40101. * Builder interface for matcher of method names.
  40102. *
  40103. * @package PHPUnit_MockObject
  40104. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40105. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40106. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40107. * @version Release: @package_version@
  40108. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40109. * @since Interface available since Release 1.0.0
  40110. */
  40111. interface PHPUnit_Framework_MockObject_Builder_MethodNameMatch extends PHPUnit_Framework_MockObject_Builder_ParametersMatch
  40112. {
  40113. /**
  40114. * Adds a new method name match and returns the parameter match object for
  40115. * further matching possibilities.
  40116. *
  40117. * @param PHPUnit_Framework_Constraint $name
  40118. * Constraint for matching method, if a string is passed it will use
  40119. * the PHPUnit_Framework_Constraint_IsEqual.
  40120. * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch
  40121. */
  40122. public function method($name);
  40123. }
  40124. <?php
  40125. /*
  40126. * This file is part of the PHPUnit_MockObject package.
  40127. *
  40128. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40129. *
  40130. * For the full copyright and license information, please view the LICENSE
  40131. * file that was distributed with this source code.
  40132. */
  40133. /**
  40134. * Builder interface for stubs which are actions replacing an invocation.
  40135. *
  40136. * @package PHPUnit_MockObject
  40137. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40138. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40139. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40140. * @version Release: @package_version@
  40141. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40142. * @since Interface available since Release 1.0.0
  40143. */
  40144. interface PHPUnit_Framework_MockObject_Builder_Stub extends PHPUnit_Framework_MockObject_Builder_Identity
  40145. {
  40146. /**
  40147. * Stubs the matching method with the stub object $stub. Any invocations of
  40148. * the matched method will now be handled by the stub instead.
  40149. *
  40150. * @param PHPUnit_Framework_MockObject_Stub $stub The stub object.
  40151. * @return PHPUnit_Framework_MockObject_Builder_Identity
  40152. */
  40153. public function will(PHPUnit_Framework_MockObject_Stub $stub);
  40154. }
  40155. <?php
  40156. /*
  40157. * This file is part of the PHPUnit_MockObject package.
  40158. *
  40159. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40160. *
  40161. * For the full copyright and license information, please view the LICENSE
  40162. * file that was distributed with this source code.
  40163. */
  40164. /**
  40165. * Represents a non-static invocation.
  40166. *
  40167. * @package PHPUnit_MockObject
  40168. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40169. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40170. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40171. * @version Release: @package_version@
  40172. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40173. * @since Class available since Release 1.0.0
  40174. */
  40175. class PHPUnit_Framework_MockObject_Invocation_Object extends PHPUnit_Framework_MockObject_Invocation_Static
  40176. {
  40177. /**
  40178. * @var object
  40179. */
  40180. public $object;
  40181. /**
  40182. * @param string $className
  40183. * @param string $methodname
  40184. * @param array $parameters
  40185. * @param object $object
  40186. * @param object $cloneObjects
  40187. */
  40188. public function __construct($className, $methodName, array $parameters, $object, $cloneObjects = false)
  40189. {
  40190. parent::__construct($className, $methodName, $parameters, $cloneObjects);
  40191. $this->object = $object;
  40192. }
  40193. }
  40194. <?php
  40195. /*
  40196. * This file is part of the PHPUnit_MockObject package.
  40197. *
  40198. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40199. *
  40200. * For the full copyright and license information, please view the LICENSE
  40201. * file that was distributed with this source code.
  40202. */
  40203. use SebastianBergmann\Exporter\Exporter;
  40204. /**
  40205. * Represents a static invocation.
  40206. *
  40207. * @package PHPUnit_MockObject
  40208. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40209. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40210. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40211. * @version Release: @package_version@
  40212. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40213. * @since Class available since Release 1.0.0
  40214. */
  40215. class PHPUnit_Framework_MockObject_Invocation_Static implements PHPUnit_Framework_MockObject_Invocation, PHPUnit_Framework_SelfDescribing
  40216. {
  40217. /**
  40218. * @var array
  40219. */
  40220. protected static $uncloneableExtensions = array(
  40221. 'mysqli' => true,
  40222. 'SQLite' => true,
  40223. 'sqlite3' => true,
  40224. 'tidy' => true,
  40225. 'xmlwriter' => true,
  40226. 'xsl' => true
  40227. );
  40228. /**
  40229. * @var array
  40230. */
  40231. protected static $uncloneableClasses = array(
  40232. 'Closure',
  40233. 'COMPersistHelper',
  40234. 'IteratorIterator',
  40235. 'RecursiveIteratorIterator',
  40236. 'SplFileObject',
  40237. 'PDORow',
  40238. 'ZipArchive'
  40239. );
  40240. /**
  40241. * @var string
  40242. */
  40243. public $className;
  40244. /**
  40245. * @var string
  40246. */
  40247. public $methodName;
  40248. /**
  40249. * @var array
  40250. */
  40251. public $parameters;
  40252. /**
  40253. * @param string $className
  40254. * @param string $methodname
  40255. * @param array $parameters
  40256. * @param boolean $cloneObjects
  40257. */
  40258. public function __construct($className, $methodName, array $parameters, $cloneObjects = false)
  40259. {
  40260. $this->className = $className;
  40261. $this->methodName = $methodName;
  40262. $this->parameters = $parameters;
  40263. if (!$cloneObjects) {
  40264. return;
  40265. }
  40266. foreach ($this->parameters as $key => $value) {
  40267. if (is_object($value)) {
  40268. $this->parameters[$key] = $this->cloneObject($value);
  40269. }
  40270. }
  40271. }
  40272. /**
  40273. * @return string
  40274. */
  40275. public function toString()
  40276. {
  40277. $exporter = new Exporter;
  40278. return sprintf(
  40279. "%s::%s(%s)",
  40280. $this->className,
  40281. $this->methodName,
  40282. join(
  40283. ', ',
  40284. array_map(
  40285. array($exporter, 'shortenedExport'),
  40286. $this->parameters
  40287. )
  40288. )
  40289. );
  40290. }
  40291. /**
  40292. * @param object $original
  40293. * @return object
  40294. */
  40295. protected function cloneObject($original)
  40296. {
  40297. $cloneable = null;
  40298. $object = new ReflectionObject($original);
  40299. // Check the blacklist before asking PHP reflection to work around
  40300. // https://bugs.php.net/bug.php?id=53967
  40301. if ($object->isInternal() &&
  40302. isset(self::$uncloneableExtensions[$object->getExtensionName()])) {
  40303. $cloneable = false;
  40304. }
  40305. if ($cloneable === null) {
  40306. foreach (self::$uncloneableClasses as $class) {
  40307. if ($original instanceof $class) {
  40308. $cloneable = false;
  40309. break;
  40310. }
  40311. }
  40312. }
  40313. if ($cloneable === null && method_exists($object, 'isCloneable')) {
  40314. $cloneable = $object->isCloneable();
  40315. }
  40316. if ($cloneable === null && $object->hasMethod('__clone')) {
  40317. $method = $object->getMethod('__clone');
  40318. $cloneable = $method->isPublic();
  40319. }
  40320. if ($cloneable === null) {
  40321. $cloneable = true;
  40322. }
  40323. if ($cloneable) {
  40324. try {
  40325. return clone $original;
  40326. } catch (Exception $e) {
  40327. return $original;
  40328. }
  40329. } else {
  40330. return $original;
  40331. }
  40332. }
  40333. }
  40334. <?php
  40335. /*
  40336. * This file is part of the PHPUnit_MockObject package.
  40337. *
  40338. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40339. *
  40340. * For the full copyright and license information, please view the LICENSE
  40341. * file that was distributed with this source code.
  40342. */
  40343. /**
  40344. * An object that stubs the process of a normal method for a mock object.
  40345. *
  40346. * The stub object will replace the code for the stubbed method and return a
  40347. * specific value instead of the original value.
  40348. *
  40349. * @package PHPUnit_MockObject
  40350. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40351. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40352. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40353. * @version Release: @package_version@
  40354. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40355. * @since Interface available since Release 1.0.0
  40356. */
  40357. interface PHPUnit_Framework_MockObject_Stub extends PHPUnit_Framework_SelfDescribing
  40358. {
  40359. /**
  40360. * Fakes the processing of the invocation $invocation by returning a
  40361. * specific value.
  40362. *
  40363. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  40364. * The invocation which was mocked and matched by the current method
  40365. * and argument matchers.
  40366. * @return mixed
  40367. */
  40368. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation);
  40369. }
  40370. <?php
  40371. /*
  40372. * This file is part of the PHPUnit_MockObject package.
  40373. *
  40374. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40375. *
  40376. * For the full copyright and license information, please view the LICENSE
  40377. * file that was distributed with this source code.
  40378. */
  40379. /**
  40380. * Stubs a method by raising a user-defined exception.
  40381. *
  40382. * @package PHPUnit_MockObject
  40383. * @author Oliver Schlicht <o.schlicht@bitExpert.de>
  40384. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40385. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40386. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40387. * @version Release: @package_version@
  40388. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40389. * @since Class available since Release 1.0.0
  40390. */
  40391. class PHPUnit_Framework_MockObject_Stub_Exception implements PHPUnit_Framework_MockObject_Stub
  40392. {
  40393. protected $exception;
  40394. public function __construct(Exception $exception)
  40395. {
  40396. $this->exception = $exception;
  40397. }
  40398. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40399. {
  40400. throw $this->exception;
  40401. }
  40402. public function toString()
  40403. {
  40404. return sprintf(
  40405. 'raise user-specified exception %s',
  40406. PHPUnit_Util_Type::export($this->exception)
  40407. );
  40408. }
  40409. }
  40410. <?php
  40411. /*
  40412. * This file is part of the PHPUnit_MockObject package.
  40413. *
  40414. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40415. *
  40416. * For the full copyright and license information, please view the LICENSE
  40417. * file that was distributed with this source code.
  40418. */
  40419. /**
  40420. * Stubs a method by returning a user-defined value.
  40421. *
  40422. * @package PHPUnit_MockObject
  40423. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40424. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40425. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40426. * @version Release: @package_version@
  40427. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40428. * @since Class available since Release 1.0.0
  40429. */
  40430. class PHPUnit_Framework_MockObject_Stub_Return implements PHPUnit_Framework_MockObject_Stub
  40431. {
  40432. protected $value;
  40433. public function __construct($value)
  40434. {
  40435. $this->value = $value;
  40436. }
  40437. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40438. {
  40439. return $this->value;
  40440. }
  40441. public function toString()
  40442. {
  40443. return sprintf(
  40444. 'return user-specified value %s',
  40445. PHPUnit_Util_Type::export($this->value)
  40446. );
  40447. }
  40448. }
  40449. <?php
  40450. /*
  40451. * This file is part of the PHPUnit_MockObject package.
  40452. *
  40453. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40454. *
  40455. * For the full copyright and license information, please view the LICENSE
  40456. * file that was distributed with this source code.
  40457. */
  40458. /**
  40459. * Stubs a method by returning the current object.
  40460. *
  40461. * @package PHPUnit_MockObject
  40462. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40463. * @author Kris Wallsmith <kris.wallsmith@gmail.com>
  40464. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40465. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40466. * @version Release: @package_version@
  40467. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40468. * @since Class available since Release 1.1.0
  40469. */
  40470. class PHPUnit_Framework_MockObject_Stub_ReturnSelf implements PHPUnit_Framework_MockObject_Stub
  40471. {
  40472. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40473. {
  40474. if (!$invocation instanceof PHPUnit_Framework_MockObject_Invocation_Object) {
  40475. throw new PHPUnit_Framework_Exception(
  40476. 'The current object can only be returned when mocking an ' .
  40477. 'object, not a static class.'
  40478. );
  40479. }
  40480. return $invocation->object;
  40481. }
  40482. public function toString()
  40483. {
  40484. return 'return the current object';
  40485. }
  40486. }
  40487. <?php
  40488. /*
  40489. * This file is part of the PHPUnit_MockObject package.
  40490. *
  40491. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40492. *
  40493. * For the full copyright and license information, please view the LICENSE
  40494. * file that was distributed with this source code.
  40495. */
  40496. /**
  40497. * Stubs a method by returning a value from a map.
  40498. *
  40499. * @package PHPUnit_MockObject
  40500. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40501. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40502. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40503. * @version Release: @package_version@
  40504. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40505. * @since Class available since Release 1.1.0
  40506. */
  40507. class PHPUnit_Framework_MockObject_Stub_ReturnValueMap implements PHPUnit_Framework_MockObject_Stub
  40508. {
  40509. protected $valueMap;
  40510. public function __construct(array $valueMap)
  40511. {
  40512. $this->valueMap = $valueMap;
  40513. }
  40514. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40515. {
  40516. $parameterCount = count($invocation->parameters);
  40517. foreach ($this->valueMap as $map) {
  40518. if (!is_array($map) || $parameterCount != count($map) - 1) {
  40519. continue;
  40520. }
  40521. $return = array_pop($map);
  40522. if ($invocation->parameters === $map) {
  40523. return $return;
  40524. }
  40525. }
  40526. return null;
  40527. }
  40528. public function toString()
  40529. {
  40530. return 'return value from a map';
  40531. }
  40532. }
  40533. <?php
  40534. /*
  40535. * This file is part of the PHPUnit_MockObject package.
  40536. *
  40537. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40538. *
  40539. * For the full copyright and license information, please view the LICENSE
  40540. * file that was distributed with this source code.
  40541. */
  40542. /**
  40543. * Stubs a method by returning a user-defined stack of values.
  40544. *
  40545. * @package PHPUnit_MockObject
  40546. * @author Patrick Müller <elias0@gmx.net>
  40547. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40548. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40549. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40550. * @version Release: @package_version@
  40551. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40552. * @since Class available since Release 1.0.0
  40553. */
  40554. class PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls implements PHPUnit_Framework_MockObject_Stub
  40555. {
  40556. protected $stack;
  40557. protected $value;
  40558. public function __construct($stack)
  40559. {
  40560. $this->stack = $stack;
  40561. }
  40562. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40563. {
  40564. $this->value = array_shift($this->stack);
  40565. if ($this->value instanceof PHPUnit_Framework_MockObject_Stub) {
  40566. $this->value = $this->value->invoke($invocation);
  40567. }
  40568. return $this->value;
  40569. }
  40570. public function toString()
  40571. {
  40572. return sprintf(
  40573. 'return user-specified value %s',
  40574. PHPUnit_Util_Type::export($this->value)
  40575. );
  40576. }
  40577. }
  40578. <?php
  40579. /*
  40580. * This file is part of the PHPUnit_MockObject package.
  40581. *
  40582. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40583. *
  40584. * For the full copyright and license information, please view the LICENSE
  40585. * file that was distributed with this source code.
  40586. */
  40587. /**
  40588. * Stubs a method by returning a user-defined value.
  40589. *
  40590. * @package PHPUnit_MockObject
  40591. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40592. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40593. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40594. * @version Release: @package_version@
  40595. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40596. * @since Interface available since Release 1.0.0
  40597. */
  40598. interface PHPUnit_Framework_MockObject_Stub_MatcherCollection
  40599. {
  40600. /**
  40601. * Adds a new matcher to the collection which can be used as an expectation
  40602. * or a stub.
  40603. *
  40604. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
  40605. * Matcher for invocations to mock objects.
  40606. */
  40607. public function addMatcher(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher);
  40608. }
  40609. <?php
  40610. /*
  40611. * This file is part of the PHPUnit_MockObject package.
  40612. *
  40613. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40614. *
  40615. * For the full copyright and license information, please view the LICENSE
  40616. * file that was distributed with this source code.
  40617. */
  40618. /**
  40619. *
  40620. *
  40621. * @package PHPUnit_MockObject
  40622. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40623. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40624. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40625. * @version Release: @package_version@
  40626. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40627. * @since Class available since Release 1.0.0
  40628. */
  40629. class PHPUnit_Framework_MockObject_Stub_ReturnCallback implements PHPUnit_Framework_MockObject_Stub
  40630. {
  40631. protected $callback;
  40632. public function __construct($callback)
  40633. {
  40634. $this->callback = $callback;
  40635. }
  40636. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40637. {
  40638. return call_user_func_array($this->callback, $invocation->parameters);
  40639. }
  40640. public function toString()
  40641. {
  40642. if (is_array($this->callback)) {
  40643. if (is_object($this->callback[0])) {
  40644. $class = get_class($this->callback[0]);
  40645. $type = '->';
  40646. } else {
  40647. $class = $this->callback[0];
  40648. $type = '::';
  40649. }
  40650. return sprintf(
  40651. 'return result of user defined callback %s%s%s() with the ' .
  40652. 'passed arguments',
  40653. $class,
  40654. $type,
  40655. $this->callback[1]
  40656. );
  40657. } else {
  40658. return 'return result of user defined callback ' . $this->callback .
  40659. ' with the passed arguments';
  40660. }
  40661. }
  40662. }
  40663. <?php
  40664. /*
  40665. * This file is part of the PHPUnit_MockObject package.
  40666. *
  40667. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40668. *
  40669. * For the full copyright and license information, please view the LICENSE
  40670. * file that was distributed with this source code.
  40671. */
  40672. /**
  40673. * Stubs a method by returning an argument that was passed to the mocked method.
  40674. *
  40675. * @package PHPUnit_MockObject
  40676. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40677. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40678. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40679. * @version Release: @package_version@
  40680. * @link http://github.com/sebastianbergmann/phpunit-mock-objects
  40681. * @since Class available since Release 1.0.0
  40682. */
  40683. class PHPUnit_Framework_MockObject_Stub_ReturnArgument extends PHPUnit_Framework_MockObject_Stub_Return
  40684. {
  40685. protected $argumentIndex;
  40686. public function __construct($argumentIndex)
  40687. {
  40688. $this->argumentIndex = $argumentIndex;
  40689. }
  40690. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40691. {
  40692. if (isset($invocation->parameters[$this->argumentIndex])) {
  40693. return $invocation->parameters[$this->argumentIndex];
  40694. } else {
  40695. return null;
  40696. }
  40697. }
  40698. public function toString()
  40699. {
  40700. return sprintf('return argument #%d', $this->argumentIndex);
  40701. }
  40702. }
  40703. <?php
  40704. /*
  40705. * This file is part of PHPUnit.
  40706. *
  40707. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40708. *
  40709. * For the full copyright and license information, please view the LICENSE
  40710. * file that was distributed with this source code.
  40711. */
  40712. /**
  40713. * Marker interface for PHPUnit exceptions.
  40714. *
  40715. * @package PHPUnit
  40716. * @subpackage Framework
  40717. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40718. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40719. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40720. * @link http://www.phpunit.de/
  40721. * @since Interface available since Release 4.0.0
  40722. */
  40723. interface PHPUnit_Exception
  40724. {
  40725. }
  40726. <?php
  40727. /*
  40728. * This file is part of PHPUnit.
  40729. *
  40730. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40731. *
  40732. * For the full copyright and license information, please view the LICENSE
  40733. * file that was distributed with this source code.
  40734. */
  40735. /**
  40736. * A Test can be run and collect its results.
  40737. *
  40738. * @package PHPUnit
  40739. * @subpackage Framework
  40740. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40741. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40742. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40743. * @link http://www.phpunit.de/
  40744. * @since Interface available since Release 2.0.0
  40745. */
  40746. interface PHPUnit_Framework_Test extends Countable
  40747. {
  40748. /**
  40749. * Runs a test and collects its result in a TestResult instance.
  40750. *
  40751. * @param PHPUnit_Framework_TestResult $result
  40752. * @return PHPUnit_Framework_TestResult
  40753. */
  40754. public function run(PHPUnit_Framework_TestResult $result = null);
  40755. }
  40756. <?php
  40757. /*
  40758. * This file is part of PHPUnit.
  40759. *
  40760. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40761. *
  40762. * For the full copyright and license information, please view the LICENSE
  40763. * file that was distributed with this source code.
  40764. */
  40765. /**
  40766. * Base class for all PHPUnit Framework exceptions.
  40767. *
  40768. * Ensures that exceptions thrown during a test run do not leave stray
  40769. * references behind.
  40770. *
  40771. * Every Exception contains a stack trace. Each stack frame contains the 'args'
  40772. * of the called function. The function arguments can contain references to
  40773. * instantiated objects. The references prevent the objects from being
  40774. * destructed (until test results are eventually printed), so memory cannot be
  40775. * freed up.
  40776. *
  40777. * With enabled process isolation, test results are serialized in the child
  40778. * process and unserialized in the parent process. The stack trace of Exceptions
  40779. * may contain objects that cannot be serialized or unserialized (e.g., PDO
  40780. * connections). Unserializing user-space objects from the child process into
  40781. * the parent would break the intended encapsulation of process isolation.
  40782. *
  40783. * @see http://fabien.potencier.org/article/9/php-serialization-stack-traces-and-exceptions
  40784. *
  40785. * @package PHPUnit
  40786. * @subpackage Framework
  40787. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40788. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40789. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40790. * @link http://www.phpunit.de/
  40791. * @since Class available since Release 3.4.0
  40792. */
  40793. class PHPUnit_Framework_Exception extends RuntimeException implements PHPUnit_Exception
  40794. {
  40795. /**
  40796. * @var array
  40797. */
  40798. protected $serializableTrace;
  40799. public function __construct($message = '', $code = 0, Exception $previous = null)
  40800. {
  40801. parent::__construct($message, $code, $previous);
  40802. $this->serializableTrace = $this->getTrace();
  40803. foreach ($this->serializableTrace as $i => $call) {
  40804. unset($this->serializableTrace[$i]['args']);
  40805. }
  40806. }
  40807. /**
  40808. * Returns the serializable trace (without 'args').
  40809. *
  40810. * @return array
  40811. */
  40812. public function getSerializableTrace()
  40813. {
  40814. return $this->serializableTrace;
  40815. }
  40816. /**
  40817. * @return string
  40818. */
  40819. public function __toString()
  40820. {
  40821. $string = PHPUnit_Framework_TestFailure::exceptionToString($this);
  40822. if ($trace = PHPUnit_Util_Filter::getFilteredStacktrace($this)) {
  40823. $string .= "\n" . $trace;
  40824. }
  40825. return $string;
  40826. }
  40827. public function __sleep()
  40828. {
  40829. return array_keys(get_object_vars($this));
  40830. }
  40831. }
  40832. <?php
  40833. /*
  40834. * This file is part of PHPUnit.
  40835. *
  40836. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40837. *
  40838. * For the full copyright and license information, please view the LICENSE
  40839. * file that was distributed with this source code.
  40840. */
  40841. /**
  40842. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  40843. * case of a test that printed output.
  40844. *
  40845. * @package PHPUnit
  40846. * @subpackage Framework
  40847. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40848. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40849. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40850. * @link http://www.phpunit.de/
  40851. * @since Class available since Release 3.6.0
  40852. */
  40853. class PHPUnit_Framework_OutputError extends PHPUnit_Framework_AssertionFailedError
  40854. {
  40855. }
  40856. <?php
  40857. /*
  40858. * This file is part of PHPUnit.
  40859. *
  40860. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40861. *
  40862. * For the full copyright and license information, please view the LICENSE
  40863. * file that was distributed with this source code.
  40864. */
  40865. /**
  40866. * A set of assert methods.
  40867. *
  40868. * @package PHPUnit
  40869. * @subpackage Framework
  40870. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40871. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  40872. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  40873. * @link http://www.phpunit.de/
  40874. * @since Class available since Release 2.0.0
  40875. */
  40876. abstract class PHPUnit_Framework_Assert
  40877. {
  40878. /**
  40879. * @var integer
  40880. */
  40881. private static $count = 0;
  40882. /**
  40883. * Asserts that an array has a specified key.
  40884. *
  40885. * @param mixed $key
  40886. * @param array|ArrayAccess $array
  40887. * @param string $message
  40888. * @since Method available since Release 3.0.0
  40889. */
  40890. public static function assertArrayHasKey($key, $array, $message = '')
  40891. {
  40892. if (!(is_integer($key) || is_string($key))) {
  40893. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40894. 1,
  40895. 'integer or string'
  40896. );
  40897. }
  40898. if (!(is_array($array) || $array instanceof ArrayAccess)) {
  40899. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40900. 2,
  40901. 'array or ArrayAccess'
  40902. );
  40903. }
  40904. $constraint = new PHPUnit_Framework_Constraint_ArrayHasKey($key);
  40905. self::assertThat($array, $constraint, $message);
  40906. }
  40907. /**
  40908. * Asserts that an array has a specified subset.
  40909. *
  40910. * @param array|ArrayAccess $subset
  40911. * @param array|ArrayAccess $array
  40912. * @param boolean $strict Check for object identity
  40913. * @param string $message
  40914. * @since Method available since Release 4.4.0
  40915. */
  40916. public static function assertArraySubset($subset, $array, $strict = false, $message = '')
  40917. {
  40918. if (!is_array($subset)) {
  40919. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40920. 1,
  40921. 'array or ArrayAccess'
  40922. );
  40923. }
  40924. if (!is_array($array)) {
  40925. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40926. 2,
  40927. 'array or ArrayAccess'
  40928. );
  40929. }
  40930. $constraint = new PHPUnit_Framework_Constraint_ArraySubset($subset, $strict);
  40931. self::assertThat($array, $constraint, $message);
  40932. }
  40933. /**
  40934. * Asserts that an array does not have a specified key.
  40935. *
  40936. * @param mixed $key
  40937. * @param array|ArrayAccess $array
  40938. * @param string $message
  40939. * @since Method available since Release 3.0.0
  40940. */
  40941. public static function assertArrayNotHasKey($key, $array, $message = '')
  40942. {
  40943. if (!(is_integer($key) || is_string($key))) {
  40944. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40945. 1,
  40946. 'integer or string'
  40947. );
  40948. }
  40949. if (!(is_array($array) || $array instanceof ArrayAccess)) {
  40950. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40951. 2,
  40952. 'array or ArrayAccess'
  40953. );
  40954. }
  40955. $constraint = new PHPUnit_Framework_Constraint_Not(
  40956. new PHPUnit_Framework_Constraint_ArrayHasKey($key)
  40957. );
  40958. self::assertThat($array, $constraint, $message);
  40959. }
  40960. /**
  40961. * Asserts that a haystack contains a needle.
  40962. *
  40963. * @param mixed $needle
  40964. * @param mixed $haystack
  40965. * @param string $message
  40966. * @param boolean $ignoreCase
  40967. * @param boolean $checkForObjectIdentity
  40968. * @param boolean $checkForNonObjectIdentity
  40969. * @since Method available since Release 2.1.0
  40970. */
  40971. public static function assertContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  40972. {
  40973. if (is_array($haystack) ||
  40974. is_object($haystack) && $haystack instanceof Traversable) {
  40975. $constraint = new PHPUnit_Framework_Constraint_TraversableContains(
  40976. $needle,
  40977. $checkForObjectIdentity,
  40978. $checkForNonObjectIdentity
  40979. );
  40980. } elseif (is_string($haystack)) {
  40981. $constraint = new PHPUnit_Framework_Constraint_StringContains(
  40982. $needle,
  40983. $ignoreCase
  40984. );
  40985. } else {
  40986. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40987. 2,
  40988. 'array, traversable or string'
  40989. );
  40990. }
  40991. self::assertThat($haystack, $constraint, $message);
  40992. }
  40993. /**
  40994. * Asserts that a haystack that is stored in a static attribute of a class
  40995. * or an attribute of an object contains a needle.
  40996. *
  40997. * @param mixed $needle
  40998. * @param string $haystackAttributeName
  40999. * @param mixed $haystackClassOrObject
  41000. * @param string $message
  41001. * @param boolean $ignoreCase
  41002. * @param boolean $checkForObjectIdentity
  41003. * @param boolean $checkForNonObjectIdentity
  41004. * @since Method available since Release 3.0.0
  41005. */
  41006. public static function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  41007. {
  41008. self::assertContains(
  41009. $needle,
  41010. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  41011. $message,
  41012. $ignoreCase,
  41013. $checkForObjectIdentity,
  41014. $checkForNonObjectIdentity
  41015. );
  41016. }
  41017. /**
  41018. * Asserts that a haystack does not contain a needle.
  41019. *
  41020. * @param mixed $needle
  41021. * @param mixed $haystack
  41022. * @param string $message
  41023. * @param boolean $ignoreCase
  41024. * @param boolean $checkForObjectIdentity
  41025. * @param boolean $checkForNonObjectIdentity
  41026. * @since Method available since Release 2.1.0
  41027. */
  41028. public static function assertNotContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  41029. {
  41030. if (is_array($haystack) ||
  41031. is_object($haystack) && $haystack instanceof Traversable) {
  41032. $constraint = new PHPUnit_Framework_Constraint_Not(
  41033. new PHPUnit_Framework_Constraint_TraversableContains(
  41034. $needle,
  41035. $checkForObjectIdentity,
  41036. $checkForNonObjectIdentity
  41037. )
  41038. );
  41039. } elseif (is_string($haystack)) {
  41040. $constraint = new PHPUnit_Framework_Constraint_Not(
  41041. new PHPUnit_Framework_Constraint_StringContains(
  41042. $needle,
  41043. $ignoreCase
  41044. )
  41045. );
  41046. } else {
  41047. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  41048. 2,
  41049. 'array, traversable or string'
  41050. );
  41051. }
  41052. self::assertThat($haystack, $constraint, $message);
  41053. }
  41054. /**
  41055. * Asserts that a haystack that is stored in a static attribute of a class
  41056. * or an attribute of an object does not contain a needle.
  41057. *
  41058. * @param mixed $needle
  41059. * @param string $haystackAttributeName
  41060. * @param mixed $haystackClassOrObject
  41061. * @param string $message
  41062. * @param boolean $ignoreCase
  41063. * @param boolean $checkForObjectIdentity
  41064. * @param boolean $checkForNonObjectIdentity
  41065. * @since Method available since Release 3.0.0
  41066. */
  41067. public static function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  41068. {
  41069. self::assertNotContains(
  41070. $needle,
  41071. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  41072. $message,
  41073. $ignoreCase,
  41074. $checkForObjectIdentity,
  41075. $checkForNonObjectIdentity
  41076. );
  41077. }
  41078. /**
  41079. * Asserts that a haystack contains only values of a given type.
  41080. *
  41081. * @param string $type
  41082. * @param mixed $haystack
  41083. * @param boolean $isNativeType
  41084. * @param string $message
  41085. * @since Method available since Release 3.1.4
  41086. */
  41087. public static function assertContainsOnly($type, $haystack, $isNativeType = null, $message = '')
  41088. {
  41089. if (!(is_array($haystack) ||
  41090. is_object($haystack) && $haystack instanceof Traversable)) {
  41091. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  41092. 2,
  41093. 'array or traversable'
  41094. );
  41095. }
  41096. if ($isNativeType == null) {
  41097. $isNativeType = PHPUnit_Util_Type::isType($type);
  41098. }
  41099. self::assertThat(
  41100. $haystack,
  41101. new PHPUnit_Framework_Constraint_TraversableContainsOnly(
  41102. $type,
  41103. $isNativeType
  41104. ),
  41105. $message
  41106. );
  41107. }
  41108. /**
  41109. * Asserts that a haystack contains only instances of a given classname
  41110. *
  41111. * @param string $classname
  41112. * @param array|Traversable $haystack
  41113. * @param string $message
  41114. */
  41115. public static function assertContainsOnlyInstancesOf($classname, $haystack, $message = '')
  41116. {
  41117. if (!(is_array($haystack) ||
  41118. is_object($haystack) && $haystack instanceof Traversable)) {
  41119. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  41120. 2,
  41121. 'array or traversable'
  41122. );
  41123. }
  41124. self::assertThat(
  41125. $haystack,
  41126. new PHPUnit_Framework_Constraint_TraversableContainsOnly(
  41127. $classname,
  41128. false
  41129. ),
  41130. $message
  41131. );
  41132. }
  41133. /**
  41134. * Asserts that a haystack that is stored in a static attribute of a class
  41135. * or an attribute of an object contains only values of a given type.
  41136. *
  41137. * @param string $type
  41138. * @param string $haystackAttributeName
  41139. * @param mixed $haystackClassOrObject
  41140. * @param boolean $isNativeType
  41141. * @param string $message
  41142. * @since Method available since Release 3.1.4
  41143. */
  41144. public static function assertAttributeContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
  41145. {
  41146. self::assertContainsOnly(
  41147. $type,
  41148. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  41149. $isNativeType,
  41150. $message
  41151. );
  41152. }
  41153. /**
  41154. * Asserts that a haystack does not contain only values of a given type.
  41155. *
  41156. * @param string $type
  41157. * @param mixed $haystack
  41158. * @param boolean $isNativeType
  41159. * @param string $message
  41160. * @since Method available since Release 3.1.4
  41161. */
  41162. public static function assertNotContainsOnly($type, $haystack, $isNativeType = null, $message = '')
  41163. {
  41164. if (!(is_array($haystack) ||
  41165. is_object($haystack) && $haystack instanceof Traversable)) {
  41166. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  41167. 2,
  41168. 'array or traversable'
  41169. );
  41170. }
  41171. if ($isNativeType == null) {
  41172. $isNativeType = PHPUnit_Util_Type::isType($type);
  41173. }
  41174. self::assertThat(
  41175. $haystack,
  41176. new PHPUnit_Framework_Constraint_Not(
  41177. new PHPUnit_Framework_Constraint_TraversableContainsOnly(
  41178. $type,
  41179. $isNativeType
  41180. )
  41181. ),
  41182. $message
  41183. );
  41184. }
  41185. /**
  41186. * Asserts that a haystack that is stored in a static attribute of a class
  41187. * or an attribute of an object does not contain only values of a given
  41188. * type.
  41189. *
  41190. * @param string $type
  41191. * @param string $haystackAttributeName
  41192. * @param mixed $haystackClassOrObject
  41193. * @param boolean $isNativeType
  41194. * @param string $message
  41195. * @since Method available since Release 3.1.4
  41196. */
  41197. public static function assertAttributeNotContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
  41198. {
  41199. self::assertNotContainsOnly(
  41200. $type,
  41201. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  41202. $isNativeType,
  41203. $message
  41204. );
  41205. }
  41206. /**
  41207. * Asserts the number of elements of an array, Countable or Traversable.
  41208. *
  41209. * @param integer $expectedCount
  41210. * @param mixed $haystack
  41211. * @param string $message
  41212. */
  41213. public static function assertCount($expectedCount, $haystack, $message = '')
  41214. {
  41215. if (!is_int($expectedCount)) {
  41216. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  41217. }
  41218. if (!$haystack instanceof Countable &&
  41219. !$haystack instanceof Traversable &&
  41220. !is_array($haystack)) {
  41221. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
  41222. }
  41223. self::assertThat(
  41224. $haystack,
  41225. new PHPUnit_Framework_Constraint_Count($expectedCount),
  41226. $message
  41227. );
  41228. }
  41229. /**
  41230. * Asserts the number of elements of an array, Countable or Traversable
  41231. * that is stored in an attribute.
  41232. *
  41233. * @param integer $expectedCount
  41234. * @param string $haystackAttributeName
  41235. * @param mixed $haystackClassOrObject
  41236. * @param string $message
  41237. * @since Method available since Release 3.6.0
  41238. */
  41239. public static function assertAttributeCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
  41240. {
  41241. self::assertCount(
  41242. $expectedCount,
  41243. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  41244. $message
  41245. );
  41246. }
  41247. /**
  41248. * Asserts the number of elements of an array, Countable or Traversable.
  41249. *
  41250. * @param integer $expectedCount
  41251. * @param mixed $haystack
  41252. * @param string $message
  41253. */
  41254. public static function assertNotCount($expectedCount, $haystack, $message = '')
  41255. {
  41256. if (!is_int($expectedCount)) {
  41257. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  41258. }
  41259. if (!$haystack instanceof Countable &&
  41260. !$haystack instanceof Traversable &&
  41261. !is_array($haystack)) {
  41262. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
  41263. }
  41264. $constraint = new PHPUnit_Framework_Constraint_Not(
  41265. new PHPUnit_Framework_Constraint_Count($expectedCount)
  41266. );
  41267. self::assertThat($haystack, $constraint, $message);
  41268. }
  41269. /**
  41270. * Asserts the number of elements of an array, Countable or Traversable
  41271. * that is stored in an attribute.
  41272. *
  41273. * @param integer $expectedCount
  41274. * @param string $haystackAttributeName
  41275. * @param mixed $haystackClassOrObject
  41276. * @param string $message
  41277. * @since Method available since Release 3.6.0
  41278. */
  41279. public static function assertAttributeNotCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
  41280. {
  41281. self::assertNotCount(
  41282. $expectedCount,
  41283. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  41284. $message
  41285. );
  41286. }
  41287. /**
  41288. * Asserts that two variables are equal.
  41289. *
  41290. * @param mixed $expected
  41291. * @param mixed $actual
  41292. * @param string $message
  41293. * @param float $delta
  41294. * @param integer $maxDepth
  41295. * @param boolean $canonicalize
  41296. * @param boolean $ignoreCase
  41297. */
  41298. public static function assertEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  41299. {
  41300. $constraint = new PHPUnit_Framework_Constraint_IsEqual(
  41301. $expected,
  41302. $delta,
  41303. $maxDepth,
  41304. $canonicalize,
  41305. $ignoreCase
  41306. );
  41307. self::assertThat($actual, $constraint, $message);
  41308. }
  41309. /**
  41310. * Asserts that a variable is equal to an attribute of an object.
  41311. *
  41312. * @param mixed $expected
  41313. * @param string $actualAttributeName
  41314. * @param string $actualClassOrObject
  41315. * @param string $message
  41316. * @param float $delta
  41317. * @param integer $maxDepth
  41318. * @param boolean $canonicalize
  41319. * @param boolean $ignoreCase
  41320. */
  41321. public static function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  41322. {
  41323. self::assertEquals(
  41324. $expected,
  41325. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41326. $message,
  41327. $delta,
  41328. $maxDepth,
  41329. $canonicalize,
  41330. $ignoreCase
  41331. );
  41332. }
  41333. /**
  41334. * Asserts that two variables are not equal.
  41335. *
  41336. * @param mixed $expected
  41337. * @param mixed $actual
  41338. * @param string $message
  41339. * @param float $delta
  41340. * @param integer $maxDepth
  41341. * @param boolean $canonicalize
  41342. * @param boolean $ignoreCase
  41343. * @since Method available since Release 2.3.0
  41344. */
  41345. public static function assertNotEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  41346. {
  41347. $constraint = new PHPUnit_Framework_Constraint_Not(
  41348. new PHPUnit_Framework_Constraint_IsEqual(
  41349. $expected,
  41350. $delta,
  41351. $maxDepth,
  41352. $canonicalize,
  41353. $ignoreCase
  41354. )
  41355. );
  41356. self::assertThat($actual, $constraint, $message);
  41357. }
  41358. /**
  41359. * Asserts that a variable is not equal to an attribute of an object.
  41360. *
  41361. * @param mixed $expected
  41362. * @param string $actualAttributeName
  41363. * @param string $actualClassOrObject
  41364. * @param string $message
  41365. * @param float $delta
  41366. * @param integer $maxDepth
  41367. * @param boolean $canonicalize
  41368. * @param boolean $ignoreCase
  41369. */
  41370. public static function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  41371. {
  41372. self::assertNotEquals(
  41373. $expected,
  41374. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41375. $message,
  41376. $delta,
  41377. $maxDepth,
  41378. $canonicalize,
  41379. $ignoreCase
  41380. );
  41381. }
  41382. /**
  41383. * Asserts that a variable is empty.
  41384. *
  41385. * @param mixed $actual
  41386. * @param string $message
  41387. * @throws PHPUnit_Framework_AssertionFailedError
  41388. */
  41389. public static function assertEmpty($actual, $message = '')
  41390. {
  41391. self::assertThat($actual, self::isEmpty(), $message);
  41392. }
  41393. /**
  41394. * Asserts that a static attribute of a class or an attribute of an object
  41395. * is empty.
  41396. *
  41397. * @param string $haystackAttributeName
  41398. * @param mixed $haystackClassOrObject
  41399. * @param string $message
  41400. * @since Method available since Release 3.5.0
  41401. */
  41402. public static function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
  41403. {
  41404. self::assertEmpty(
  41405. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  41406. $message
  41407. );
  41408. }
  41409. /**
  41410. * Asserts that a variable is not empty.
  41411. *
  41412. * @param mixed $actual
  41413. * @param string $message
  41414. * @throws PHPUnit_Framework_AssertionFailedError
  41415. */
  41416. public static function assertNotEmpty($actual, $message = '')
  41417. {
  41418. self::assertThat($actual, self::logicalNot(self::isEmpty()), $message);
  41419. }
  41420. /**
  41421. * Asserts that a static attribute of a class or an attribute of an object
  41422. * is not empty.
  41423. *
  41424. * @param string $haystackAttributeName
  41425. * @param mixed $haystackClassOrObject
  41426. * @param string $message
  41427. * @since Method available since Release 3.5.0
  41428. */
  41429. public static function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
  41430. {
  41431. self::assertNotEmpty(
  41432. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  41433. $message
  41434. );
  41435. }
  41436. /**
  41437. * Asserts that a value is greater than another value.
  41438. *
  41439. * @param mixed $expected
  41440. * @param mixed $actual
  41441. * @param string $message
  41442. * @since Method available since Release 3.1.0
  41443. */
  41444. public static function assertGreaterThan($expected, $actual, $message = '')
  41445. {
  41446. self::assertThat($actual, self::greaterThan($expected), $message);
  41447. }
  41448. /**
  41449. * Asserts that an attribute is greater than another value.
  41450. *
  41451. * @param mixed $expected
  41452. * @param string $actualAttributeName
  41453. * @param string $actualClassOrObject
  41454. * @param string $message
  41455. * @since Method available since Release 3.1.0
  41456. */
  41457. public static function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  41458. {
  41459. self::assertGreaterThan(
  41460. $expected,
  41461. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41462. $message
  41463. );
  41464. }
  41465. /**
  41466. * Asserts that a value is greater than or equal to another value.
  41467. *
  41468. * @param mixed $expected
  41469. * @param mixed $actual
  41470. * @param string $message
  41471. * @since Method available since Release 3.1.0
  41472. */
  41473. public static function assertGreaterThanOrEqual($expected, $actual, $message = '')
  41474. {
  41475. self::assertThat(
  41476. $actual,
  41477. self::greaterThanOrEqual($expected),
  41478. $message
  41479. );
  41480. }
  41481. /**
  41482. * Asserts that an attribute is greater than or equal to another value.
  41483. *
  41484. * @param mixed $expected
  41485. * @param string $actualAttributeName
  41486. * @param string $actualClassOrObject
  41487. * @param string $message
  41488. * @since Method available since Release 3.1.0
  41489. */
  41490. public static function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  41491. {
  41492. self::assertGreaterThanOrEqual(
  41493. $expected,
  41494. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41495. $message
  41496. );
  41497. }
  41498. /**
  41499. * Asserts that a value is smaller than another value.
  41500. *
  41501. * @param mixed $expected
  41502. * @param mixed $actual
  41503. * @param string $message
  41504. * @since Method available since Release 3.1.0
  41505. */
  41506. public static function assertLessThan($expected, $actual, $message = '')
  41507. {
  41508. self::assertThat($actual, self::lessThan($expected), $message);
  41509. }
  41510. /**
  41511. * Asserts that an attribute is smaller than another value.
  41512. *
  41513. * @param mixed $expected
  41514. * @param string $actualAttributeName
  41515. * @param string $actualClassOrObject
  41516. * @param string $message
  41517. * @since Method available since Release 3.1.0
  41518. */
  41519. public static function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  41520. {
  41521. self::assertLessThan(
  41522. $expected,
  41523. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41524. $message
  41525. );
  41526. }
  41527. /**
  41528. * Asserts that a value is smaller than or equal to another value.
  41529. *
  41530. * @param mixed $expected
  41531. * @param mixed $actual
  41532. * @param string $message
  41533. * @since Method available since Release 3.1.0
  41534. */
  41535. public static function assertLessThanOrEqual($expected, $actual, $message = '')
  41536. {
  41537. self::assertThat($actual, self::lessThanOrEqual($expected), $message);
  41538. }
  41539. /**
  41540. * Asserts that an attribute is smaller than or equal to another value.
  41541. *
  41542. * @param mixed $expected
  41543. * @param string $actualAttributeName
  41544. * @param string $actualClassOrObject
  41545. * @param string $message
  41546. * @since Method available since Release 3.1.0
  41547. */
  41548. public static function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  41549. {
  41550. self::assertLessThanOrEqual(
  41551. $expected,
  41552. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41553. $message
  41554. );
  41555. }
  41556. /**
  41557. * Asserts that the contents of one file is equal to the contents of another
  41558. * file.
  41559. *
  41560. * @param string $expected
  41561. * @param string $actual
  41562. * @param string $message
  41563. * @param boolean $canonicalize
  41564. * @param boolean $ignoreCase
  41565. * @since Method available since Release 3.2.14
  41566. */
  41567. public static function assertFileEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
  41568. {
  41569. self::assertFileExists($expected, $message);
  41570. self::assertFileExists($actual, $message);
  41571. self::assertEquals(
  41572. file_get_contents($expected),
  41573. file_get_contents($actual),
  41574. $message,
  41575. 0,
  41576. 10,
  41577. $canonicalize,
  41578. $ignoreCase
  41579. );
  41580. }
  41581. /**
  41582. * Asserts that the contents of one file is not equal to the contents of
  41583. * another file.
  41584. *
  41585. * @param string $expected
  41586. * @param string $actual
  41587. * @param string $message
  41588. * @param boolean $canonicalize
  41589. * @param boolean $ignoreCase
  41590. * @since Method available since Release 3.2.14
  41591. */
  41592. public static function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
  41593. {
  41594. self::assertFileExists($expected, $message);
  41595. self::assertFileExists($actual, $message);
  41596. self::assertNotEquals(
  41597. file_get_contents($expected),
  41598. file_get_contents($actual),
  41599. $message,
  41600. 0,
  41601. 10,
  41602. $canonicalize,
  41603. $ignoreCase
  41604. );
  41605. }
  41606. /**
  41607. * Asserts that the contents of a string is equal
  41608. * to the contents of a file.
  41609. *
  41610. * @param string $expectedFile
  41611. * @param string $actualString
  41612. * @param string $message
  41613. * @param boolean $canonicalize
  41614. * @param boolean $ignoreCase
  41615. * @since Method available since Release 3.3.0
  41616. */
  41617. public static function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
  41618. {
  41619. self::assertFileExists($expectedFile, $message);
  41620. self::assertEquals(
  41621. file_get_contents($expectedFile),
  41622. $actualString,
  41623. $message,
  41624. 0,
  41625. 10,
  41626. $canonicalize,
  41627. $ignoreCase
  41628. );
  41629. }
  41630. /**
  41631. * Asserts that the contents of a string is not equal
  41632. * to the contents of a file.
  41633. *
  41634. * @param string $expectedFile
  41635. * @param string $actualString
  41636. * @param string $message
  41637. * @param boolean $canonicalize
  41638. * @param boolean $ignoreCase
  41639. * @since Method available since Release 3.3.0
  41640. */
  41641. public static function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
  41642. {
  41643. self::assertFileExists($expectedFile, $message);
  41644. self::assertNotEquals(
  41645. file_get_contents($expectedFile),
  41646. $actualString,
  41647. $message,
  41648. 0,
  41649. 10,
  41650. $canonicalize,
  41651. $ignoreCase
  41652. );
  41653. }
  41654. /**
  41655. * Asserts that a file exists.
  41656. *
  41657. * @param string $filename
  41658. * @param string $message
  41659. * @since Method available since Release 3.0.0
  41660. */
  41661. public static function assertFileExists($filename, $message = '')
  41662. {
  41663. if (!is_string($filename)) {
  41664. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41665. }
  41666. $constraint = new PHPUnit_Framework_Constraint_FileExists;
  41667. self::assertThat($filename, $constraint, $message);
  41668. }
  41669. /**
  41670. * Asserts that a file does not exist.
  41671. *
  41672. * @param string $filename
  41673. * @param string $message
  41674. * @since Method available since Release 3.0.0
  41675. */
  41676. public static function assertFileNotExists($filename, $message = '')
  41677. {
  41678. if (!is_string($filename)) {
  41679. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41680. }
  41681. $constraint = new PHPUnit_Framework_Constraint_Not(
  41682. new PHPUnit_Framework_Constraint_FileExists
  41683. );
  41684. self::assertThat($filename, $constraint, $message);
  41685. }
  41686. /**
  41687. * Asserts that a condition is true.
  41688. *
  41689. * @param boolean $condition
  41690. * @param string $message
  41691. * @throws PHPUnit_Framework_AssertionFailedError
  41692. */
  41693. public static function assertTrue($condition, $message = '')
  41694. {
  41695. self::assertThat($condition, self::isTrue(), $message);
  41696. }
  41697. /**
  41698. * Asserts that a condition is not true.
  41699. *
  41700. * @param boolean $condition
  41701. * @param string $message
  41702. * @throws PHPUnit_Framework_AssertionFailedError
  41703. */
  41704. public static function assertNotTrue($condition, $message = '')
  41705. {
  41706. self::assertThat($condition, self::logicalNot(self::isTrue()), $message);
  41707. }
  41708. /**
  41709. * Asserts that a condition is false.
  41710. *
  41711. * @param boolean $condition
  41712. * @param string $message
  41713. * @throws PHPUnit_Framework_AssertionFailedError
  41714. */
  41715. public static function assertFalse($condition, $message = '')
  41716. {
  41717. self::assertThat($condition, self::isFalse(), $message);
  41718. }
  41719. /**
  41720. * Asserts that a condition is not false.
  41721. *
  41722. * @param boolean $condition
  41723. * @param string $message
  41724. * @throws PHPUnit_Framework_AssertionFailedError
  41725. */
  41726. public static function assertNotFalse($condition, $message = '')
  41727. {
  41728. self::assertThat($condition, self::logicalNot(self::isFalse()), $message);
  41729. }
  41730. /**
  41731. * Asserts that a variable is not null.
  41732. *
  41733. * @param mixed $actual
  41734. * @param string $message
  41735. */
  41736. public static function assertNotNull($actual, $message = '')
  41737. {
  41738. self::assertThat($actual, self::logicalNot(self::isNull()), $message);
  41739. }
  41740. /**
  41741. * Asserts that a variable is null.
  41742. *
  41743. * @param mixed $actual
  41744. * @param string $message
  41745. */
  41746. public static function assertNull($actual, $message = '')
  41747. {
  41748. self::assertThat($actual, self::isNull(), $message);
  41749. }
  41750. /**
  41751. * Asserts that a class has a specified attribute.
  41752. *
  41753. * @param string $attributeName
  41754. * @param string $className
  41755. * @param string $message
  41756. * @since Method available since Release 3.1.0
  41757. */
  41758. public static function assertClassHasAttribute($attributeName, $className, $message = '')
  41759. {
  41760. if (!is_string($attributeName)) {
  41761. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41762. }
  41763. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41764. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41765. }
  41766. if (!is_string($className) || !class_exists($className)) {
  41767. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
  41768. }
  41769. $constraint = new PHPUnit_Framework_Constraint_ClassHasAttribute(
  41770. $attributeName
  41771. );
  41772. self::assertThat($className, $constraint, $message);
  41773. }
  41774. /**
  41775. * Asserts that a class does not have a specified attribute.
  41776. *
  41777. * @param string $attributeName
  41778. * @param string $className
  41779. * @param string $message
  41780. * @since Method available since Release 3.1.0
  41781. */
  41782. public static function assertClassNotHasAttribute($attributeName, $className, $message = '')
  41783. {
  41784. if (!is_string($attributeName)) {
  41785. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41786. }
  41787. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41788. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41789. }
  41790. if (!is_string($className) || !class_exists($className)) {
  41791. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
  41792. }
  41793. $constraint = new PHPUnit_Framework_Constraint_Not(
  41794. new PHPUnit_Framework_Constraint_ClassHasAttribute($attributeName)
  41795. );
  41796. self::assertThat($className, $constraint, $message);
  41797. }
  41798. /**
  41799. * Asserts that a class has a specified static attribute.
  41800. *
  41801. * @param string $attributeName
  41802. * @param string $className
  41803. * @param string $message
  41804. * @since Method available since Release 3.1.0
  41805. */
  41806. public static function assertClassHasStaticAttribute($attributeName, $className, $message = '')
  41807. {
  41808. if (!is_string($attributeName)) {
  41809. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41810. }
  41811. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41812. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41813. }
  41814. if (!is_string($className) || !class_exists($className)) {
  41815. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
  41816. }
  41817. $constraint = new PHPUnit_Framework_Constraint_ClassHasStaticAttribute(
  41818. $attributeName
  41819. );
  41820. self::assertThat($className, $constraint, $message);
  41821. }
  41822. /**
  41823. * Asserts that a class does not have a specified static attribute.
  41824. *
  41825. * @param string $attributeName
  41826. * @param string $className
  41827. * @param string $message
  41828. * @since Method available since Release 3.1.0
  41829. */
  41830. public static function assertClassNotHasStaticAttribute($attributeName, $className, $message = '')
  41831. {
  41832. if (!is_string($attributeName)) {
  41833. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41834. }
  41835. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41836. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41837. }
  41838. if (!is_string($className) || !class_exists($className)) {
  41839. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
  41840. }
  41841. $constraint = new PHPUnit_Framework_Constraint_Not(
  41842. new PHPUnit_Framework_Constraint_ClassHasStaticAttribute(
  41843. $attributeName
  41844. )
  41845. );
  41846. self::assertThat($className, $constraint, $message);
  41847. }
  41848. /**
  41849. * Asserts that an object has a specified attribute.
  41850. *
  41851. * @param string $attributeName
  41852. * @param object $object
  41853. * @param string $message
  41854. * @since Method available since Release 3.0.0
  41855. */
  41856. public static function assertObjectHasAttribute($attributeName, $object, $message = '')
  41857. {
  41858. if (!is_string($attributeName)) {
  41859. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41860. }
  41861. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41862. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41863. }
  41864. if (!is_object($object)) {
  41865. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object');
  41866. }
  41867. $constraint = new PHPUnit_Framework_Constraint_ObjectHasAttribute(
  41868. $attributeName
  41869. );
  41870. self::assertThat($object, $constraint, $message);
  41871. }
  41872. /**
  41873. * Asserts that an object does not have a specified attribute.
  41874. *
  41875. * @param string $attributeName
  41876. * @param object $object
  41877. * @param string $message
  41878. * @since Method available since Release 3.0.0
  41879. */
  41880. public static function assertObjectNotHasAttribute($attributeName, $object, $message = '')
  41881. {
  41882. if (!is_string($attributeName)) {
  41883. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41884. }
  41885. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41886. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41887. }
  41888. if (!is_object($object)) {
  41889. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object');
  41890. }
  41891. $constraint = new PHPUnit_Framework_Constraint_Not(
  41892. new PHPUnit_Framework_Constraint_ObjectHasAttribute($attributeName)
  41893. );
  41894. self::assertThat($object, $constraint, $message);
  41895. }
  41896. /**
  41897. * Asserts that two variables have the same type and value.
  41898. * Used on objects, it asserts that two variables reference
  41899. * the same object.
  41900. *
  41901. * @param mixed $expected
  41902. * @param mixed $actual
  41903. * @param string $message
  41904. */
  41905. public static function assertSame($expected, $actual, $message = '')
  41906. {
  41907. if (is_bool($expected) && is_bool($actual)) {
  41908. self::assertEquals($expected, $actual, $message);
  41909. } else {
  41910. $constraint = new PHPUnit_Framework_Constraint_IsIdentical(
  41911. $expected
  41912. );
  41913. self::assertThat($actual, $constraint, $message);
  41914. }
  41915. }
  41916. /**
  41917. * Asserts that a variable and an attribute of an object have the same type
  41918. * and value.
  41919. *
  41920. * @param mixed $expected
  41921. * @param string $actualAttributeName
  41922. * @param object $actualClassOrObject
  41923. * @param string $message
  41924. */
  41925. public static function assertAttributeSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  41926. {
  41927. self::assertSame(
  41928. $expected,
  41929. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41930. $message
  41931. );
  41932. }
  41933. /**
  41934. * Asserts that two variables do not have the same type and value.
  41935. * Used on objects, it asserts that two variables do not reference
  41936. * the same object.
  41937. *
  41938. * @param mixed $expected
  41939. * @param mixed $actual
  41940. * @param string $message
  41941. */
  41942. public static function assertNotSame($expected, $actual, $message = '')
  41943. {
  41944. if (is_bool($expected) && is_bool($actual)) {
  41945. self::assertNotEquals($expected, $actual, $message);
  41946. } else {
  41947. $constraint = new PHPUnit_Framework_Constraint_Not(
  41948. new PHPUnit_Framework_Constraint_IsIdentical($expected)
  41949. );
  41950. self::assertThat($actual, $constraint, $message);
  41951. }
  41952. }
  41953. /**
  41954. * Asserts that a variable and an attribute of an object do not have the
  41955. * same type and value.
  41956. *
  41957. * @param mixed $expected
  41958. * @param string $actualAttributeName
  41959. * @param object $actualClassOrObject
  41960. * @param string $message
  41961. */
  41962. public static function assertAttributeNotSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  41963. {
  41964. self::assertNotSame(
  41965. $expected,
  41966. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41967. $message
  41968. );
  41969. }
  41970. /**
  41971. * Asserts that a variable is of a given type.
  41972. *
  41973. * @param string $expected
  41974. * @param mixed $actual
  41975. * @param string $message
  41976. * @since Method available since Release 3.5.0
  41977. */
  41978. public static function assertInstanceOf($expected, $actual, $message = '')
  41979. {
  41980. if (!(is_string($expected) && (class_exists($expected) || interface_exists($expected)))) {
  41981. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class or interface name');
  41982. }
  41983. $constraint = new PHPUnit_Framework_Constraint_IsInstanceOf(
  41984. $expected
  41985. );
  41986. self::assertThat($actual, $constraint, $message);
  41987. }
  41988. /**
  41989. * Asserts that an attribute is of a given type.
  41990. *
  41991. * @param string $expected
  41992. * @param string $attributeName
  41993. * @param mixed $classOrObject
  41994. * @param string $message
  41995. * @since Method available since Release 3.5.0
  41996. */
  41997. public static function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '')
  41998. {
  41999. self::assertInstanceOf(
  42000. $expected,
  42001. self::readAttribute($classOrObject, $attributeName),
  42002. $message
  42003. );
  42004. }
  42005. /**
  42006. * Asserts that a variable is not of a given type.
  42007. *
  42008. * @param string $expected
  42009. * @param mixed $actual
  42010. * @param string $message
  42011. * @since Method available since Release 3.5.0
  42012. */
  42013. public static function assertNotInstanceOf($expected, $actual, $message = '')
  42014. {
  42015. if (!(is_string($expected) && (class_exists($expected) || interface_exists($expected)))) {
  42016. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class or interface name');
  42017. }
  42018. $constraint = new PHPUnit_Framework_Constraint_Not(
  42019. new PHPUnit_Framework_Constraint_IsInstanceOf($expected)
  42020. );
  42021. self::assertThat($actual, $constraint, $message);
  42022. }
  42023. /**
  42024. * Asserts that an attribute is of a given type.
  42025. *
  42026. * @param string $expected
  42027. * @param string $attributeName
  42028. * @param mixed $classOrObject
  42029. * @param string $message
  42030. * @since Method available since Release 3.5.0
  42031. */
  42032. public static function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '')
  42033. {
  42034. self::assertNotInstanceOf(
  42035. $expected,
  42036. self::readAttribute($classOrObject, $attributeName),
  42037. $message
  42038. );
  42039. }
  42040. /**
  42041. * Asserts that a variable is of a given type.
  42042. *
  42043. * @param string $expected
  42044. * @param mixed $actual
  42045. * @param string $message
  42046. * @since Method available since Release 3.5.0
  42047. */
  42048. public static function assertInternalType($expected, $actual, $message = '')
  42049. {
  42050. if (!is_string($expected)) {
  42051. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42052. }
  42053. $constraint = new PHPUnit_Framework_Constraint_IsType(
  42054. $expected
  42055. );
  42056. self::assertThat($actual, $constraint, $message);
  42057. }
  42058. /**
  42059. * Asserts that an attribute is of a given type.
  42060. *
  42061. * @param string $expected
  42062. * @param string $attributeName
  42063. * @param mixed $classOrObject
  42064. * @param string $message
  42065. * @since Method available since Release 3.5.0
  42066. */
  42067. public static function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '')
  42068. {
  42069. self::assertInternalType(
  42070. $expected,
  42071. self::readAttribute($classOrObject, $attributeName),
  42072. $message
  42073. );
  42074. }
  42075. /**
  42076. * Asserts that a variable is not of a given type.
  42077. *
  42078. * @param string $expected
  42079. * @param mixed $actual
  42080. * @param string $message
  42081. * @since Method available since Release 3.5.0
  42082. */
  42083. public static function assertNotInternalType($expected, $actual, $message = '')
  42084. {
  42085. if (!is_string($expected)) {
  42086. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42087. }
  42088. $constraint = new PHPUnit_Framework_Constraint_Not(
  42089. new PHPUnit_Framework_Constraint_IsType($expected)
  42090. );
  42091. self::assertThat($actual, $constraint, $message);
  42092. }
  42093. /**
  42094. * Asserts that an attribute is of a given type.
  42095. *
  42096. * @param string $expected
  42097. * @param string $attributeName
  42098. * @param mixed $classOrObject
  42099. * @param string $message
  42100. * @since Method available since Release 3.5.0
  42101. */
  42102. public static function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '')
  42103. {
  42104. self::assertNotInternalType(
  42105. $expected,
  42106. self::readAttribute($classOrObject, $attributeName),
  42107. $message
  42108. );
  42109. }
  42110. /**
  42111. * Asserts that a string matches a given regular expression.
  42112. *
  42113. * @param string $pattern
  42114. * @param string $string
  42115. * @param string $message
  42116. */
  42117. public static function assertRegExp($pattern, $string, $message = '')
  42118. {
  42119. if (!is_string($pattern)) {
  42120. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42121. }
  42122. if (!is_string($string)) {
  42123. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42124. }
  42125. $constraint = new PHPUnit_Framework_Constraint_PCREMatch($pattern);
  42126. self::assertThat($string, $constraint, $message);
  42127. }
  42128. /**
  42129. * Asserts that a string does not match a given regular expression.
  42130. *
  42131. * @param string $pattern
  42132. * @param string $string
  42133. * @param string $message
  42134. * @since Method available since Release 2.1.0
  42135. */
  42136. public static function assertNotRegExp($pattern, $string, $message = '')
  42137. {
  42138. if (!is_string($pattern)) {
  42139. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42140. }
  42141. if (!is_string($string)) {
  42142. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42143. }
  42144. $constraint = new PHPUnit_Framework_Constraint_Not(
  42145. new PHPUnit_Framework_Constraint_PCREMatch($pattern)
  42146. );
  42147. self::assertThat($string, $constraint, $message);
  42148. }
  42149. /**
  42150. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  42151. * is the same.
  42152. *
  42153. * @param array|Countable|Traversable $expected
  42154. * @param array|Countable|Traversable $actual
  42155. * @param string $message
  42156. */
  42157. public static function assertSameSize($expected, $actual, $message = '')
  42158. {
  42159. if (!$expected instanceof Countable &&
  42160. !$expected instanceof Traversable &&
  42161. !is_array($expected)) {
  42162. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable or traversable');
  42163. }
  42164. if (!$actual instanceof Countable &&
  42165. !$actual instanceof Traversable &&
  42166. !is_array($actual)) {
  42167. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
  42168. }
  42169. self::assertThat(
  42170. $actual,
  42171. new PHPUnit_Framework_Constraint_SameSize($expected),
  42172. $message
  42173. );
  42174. }
  42175. /**
  42176. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  42177. * is not the same.
  42178. *
  42179. * @param array|Countable|Traversable $expected
  42180. * @param array|Countable|Traversable $actual
  42181. * @param string $message
  42182. */
  42183. public static function assertNotSameSize($expected, $actual, $message = '')
  42184. {
  42185. if (!$expected instanceof Countable &&
  42186. !$expected instanceof Traversable &&
  42187. !is_array($expected)) {
  42188. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable or traversable');
  42189. }
  42190. if (!$actual instanceof Countable &&
  42191. !$actual instanceof Traversable &&
  42192. !is_array($actual)) {
  42193. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
  42194. }
  42195. $constraint = new PHPUnit_Framework_Constraint_Not(
  42196. new PHPUnit_Framework_Constraint_SameSize($expected)
  42197. );
  42198. self::assertThat($actual, $constraint, $message);
  42199. }
  42200. /**
  42201. * Asserts that a string matches a given format string.
  42202. *
  42203. * @param string $format
  42204. * @param string $string
  42205. * @param string $message
  42206. * @since Method available since Release 3.5.0
  42207. */
  42208. public static function assertStringMatchesFormat($format, $string, $message = '')
  42209. {
  42210. if (!is_string($format)) {
  42211. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42212. }
  42213. if (!is_string($string)) {
  42214. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42215. }
  42216. $constraint = new PHPUnit_Framework_Constraint_StringMatches($format);
  42217. self::assertThat($string, $constraint, $message);
  42218. }
  42219. /**
  42220. * Asserts that a string does not match a given format string.
  42221. *
  42222. * @param string $format
  42223. * @param string $string
  42224. * @param string $message
  42225. * @since Method available since Release 3.5.0
  42226. */
  42227. public static function assertStringNotMatchesFormat($format, $string, $message = '')
  42228. {
  42229. if (!is_string($format)) {
  42230. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42231. }
  42232. if (!is_string($string)) {
  42233. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42234. }
  42235. $constraint = new PHPUnit_Framework_Constraint_Not(
  42236. new PHPUnit_Framework_Constraint_StringMatches($format)
  42237. );
  42238. self::assertThat($string, $constraint, $message);
  42239. }
  42240. /**
  42241. * Asserts that a string matches a given format file.
  42242. *
  42243. * @param string $formatFile
  42244. * @param string $string
  42245. * @param string $message
  42246. * @since Method available since Release 3.5.0
  42247. */
  42248. public static function assertStringMatchesFormatFile($formatFile, $string, $message = '')
  42249. {
  42250. self::assertFileExists($formatFile, $message);
  42251. if (!is_string($string)) {
  42252. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42253. }
  42254. $constraint = new PHPUnit_Framework_Constraint_StringMatches(
  42255. file_get_contents($formatFile)
  42256. );
  42257. self::assertThat($string, $constraint, $message);
  42258. }
  42259. /**
  42260. * Asserts that a string does not match a given format string.
  42261. *
  42262. * @param string $formatFile
  42263. * @param string $string
  42264. * @param string $message
  42265. * @since Method available since Release 3.5.0
  42266. */
  42267. public static function assertStringNotMatchesFormatFile($formatFile, $string, $message = '')
  42268. {
  42269. self::assertFileExists($formatFile, $message);
  42270. if (!is_string($string)) {
  42271. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42272. }
  42273. $constraint = new PHPUnit_Framework_Constraint_Not(
  42274. new PHPUnit_Framework_Constraint_StringMatches(
  42275. file_get_contents($formatFile)
  42276. )
  42277. );
  42278. self::assertThat($string, $constraint, $message);
  42279. }
  42280. /**
  42281. * Asserts that a string starts with a given prefix.
  42282. *
  42283. * @param string $prefix
  42284. * @param string $string
  42285. * @param string $message
  42286. * @since Method available since Release 3.4.0
  42287. */
  42288. public static function assertStringStartsWith($prefix, $string, $message = '')
  42289. {
  42290. if (!is_string($prefix)) {
  42291. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42292. }
  42293. if (!is_string($string)) {
  42294. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42295. }
  42296. $constraint = new PHPUnit_Framework_Constraint_StringStartsWith(
  42297. $prefix
  42298. );
  42299. self::assertThat($string, $constraint, $message);
  42300. }
  42301. /**
  42302. * Asserts that a string starts not with a given prefix.
  42303. *
  42304. * @param string $prefix
  42305. * @param string $string
  42306. * @param string $message
  42307. * @since Method available since Release 3.4.0
  42308. */
  42309. public static function assertStringStartsNotWith($prefix, $string, $message = '')
  42310. {
  42311. if (!is_string($prefix)) {
  42312. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42313. }
  42314. if (!is_string($string)) {
  42315. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42316. }
  42317. $constraint = new PHPUnit_Framework_Constraint_Not(
  42318. new PHPUnit_Framework_Constraint_StringStartsWith($prefix)
  42319. );
  42320. self::assertThat($string, $constraint, $message);
  42321. }
  42322. /**
  42323. * Asserts that a string ends with a given suffix.
  42324. *
  42325. * @param string $suffix
  42326. * @param string $string
  42327. * @param string $message
  42328. * @since Method available since Release 3.4.0
  42329. */
  42330. public static function assertStringEndsWith($suffix, $string, $message = '')
  42331. {
  42332. if (!is_string($suffix)) {
  42333. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42334. }
  42335. if (!is_string($string)) {
  42336. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42337. }
  42338. $constraint = new PHPUnit_Framework_Constraint_StringEndsWith($suffix);
  42339. self::assertThat($string, $constraint, $message);
  42340. }
  42341. /**
  42342. * Asserts that a string ends not with a given suffix.
  42343. *
  42344. * @param string $suffix
  42345. * @param string $string
  42346. * @param string $message
  42347. * @since Method available since Release 3.4.0
  42348. */
  42349. public static function assertStringEndsNotWith($suffix, $string, $message = '')
  42350. {
  42351. if (!is_string($suffix)) {
  42352. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42353. }
  42354. if (!is_string($string)) {
  42355. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42356. }
  42357. $constraint = new PHPUnit_Framework_Constraint_Not(
  42358. new PHPUnit_Framework_Constraint_StringEndsWith($suffix)
  42359. );
  42360. self::assertThat($string, $constraint, $message);
  42361. }
  42362. /**
  42363. * Asserts that two XML files are equal.
  42364. *
  42365. * @param string $expectedFile
  42366. * @param string $actualFile
  42367. * @param string $message
  42368. * @since Method available since Release 3.1.0
  42369. */
  42370. public static function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '')
  42371. {
  42372. self::assertFileExists($expectedFile);
  42373. self::assertFileExists($actualFile);
  42374. $expected = new DOMDocument;
  42375. $expected->preserveWhiteSpace = false;
  42376. $expected->load($expectedFile);
  42377. $actual = new DOMDocument;
  42378. $actual->preserveWhiteSpace = false;
  42379. $actual->load($actualFile);
  42380. self::assertEquals($expected, $actual, $message);
  42381. }
  42382. /**
  42383. * Asserts that two XML files are not equal.
  42384. *
  42385. * @param string $expectedFile
  42386. * @param string $actualFile
  42387. * @param string $message
  42388. * @since Method available since Release 3.1.0
  42389. */
  42390. public static function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '')
  42391. {
  42392. self::assertFileExists($expectedFile);
  42393. self::assertFileExists($actualFile);
  42394. $expected = new DOMDocument;
  42395. $expected->preserveWhiteSpace = false;
  42396. $expected->load($expectedFile);
  42397. $actual = new DOMDocument;
  42398. $actual->preserveWhiteSpace = false;
  42399. $actual->load($actualFile);
  42400. self::assertNotEquals($expected, $actual, $message);
  42401. }
  42402. /**
  42403. * Asserts that two XML documents are equal.
  42404. *
  42405. * @param string $expectedFile
  42406. * @param string $actualXml
  42407. * @param string $message
  42408. * @since Method available since Release 3.3.0
  42409. */
  42410. public static function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '')
  42411. {
  42412. self::assertFileExists($expectedFile);
  42413. $expected = new DOMDocument;
  42414. $expected->preserveWhiteSpace = false;
  42415. $expected->load($expectedFile);
  42416. $actual = new DOMDocument;
  42417. $actual->preserveWhiteSpace = false;
  42418. $actual->loadXML($actualXml);
  42419. self::assertEquals($expected, $actual, $message);
  42420. }
  42421. /**
  42422. * Asserts that two XML documents are not equal.
  42423. *
  42424. * @param string $expectedFile
  42425. * @param string $actualXml
  42426. * @param string $message
  42427. * @since Method available since Release 3.3.0
  42428. */
  42429. public static function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '')
  42430. {
  42431. self::assertFileExists($expectedFile);
  42432. $expected = new DOMDocument;
  42433. $expected->preserveWhiteSpace = false;
  42434. $expected->load($expectedFile);
  42435. $actual = new DOMDocument;
  42436. $actual->preserveWhiteSpace = false;
  42437. $actual->loadXML($actualXml);
  42438. self::assertNotEquals($expected, $actual, $message);
  42439. }
  42440. /**
  42441. * Asserts that two XML documents are equal.
  42442. *
  42443. * @param string $expectedXml
  42444. * @param string $actualXml
  42445. * @param string $message
  42446. * @since Method available since Release 3.1.0
  42447. */
  42448. public static function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '')
  42449. {
  42450. $expected = new DOMDocument;
  42451. $expected->preserveWhiteSpace = false;
  42452. $expected->loadXML($expectedXml);
  42453. $actual = new DOMDocument;
  42454. $actual->preserveWhiteSpace = false;
  42455. $actual->loadXML($actualXml);
  42456. self::assertEquals($expected, $actual, $message);
  42457. }
  42458. /**
  42459. * Asserts that two XML documents are not equal.
  42460. *
  42461. * @param string $expectedXml
  42462. * @param string $actualXml
  42463. * @param string $message
  42464. * @since Method available since Release 3.1.0
  42465. */
  42466. public static function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '')
  42467. {
  42468. $expected = new DOMDocument;
  42469. $expected->preserveWhiteSpace = false;
  42470. $expected->loadXML($expectedXml);
  42471. $actual = new DOMDocument;
  42472. $actual->preserveWhiteSpace = false;
  42473. $actual->loadXML($actualXml);
  42474. self::assertNotEquals($expected, $actual, $message);
  42475. }
  42476. /**
  42477. * Asserts that a hierarchy of DOMElements matches.
  42478. *
  42479. * @param DOMElement $expectedElement
  42480. * @param DOMElement $actualElement
  42481. * @param boolean $checkAttributes
  42482. * @param string $message
  42483. * @author Mattis Stordalen Flister <mattis@xait.no>
  42484. * @since Method available since Release 3.3.0
  42485. */
  42486. public static function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = false, $message = '')
  42487. {
  42488. $expectedElement = clone $expectedElement;
  42489. $actualElement = clone $actualElement;
  42490. self::assertEquals(
  42491. $expectedElement->tagName,
  42492. $actualElement->tagName,
  42493. $message
  42494. );
  42495. if ($checkAttributes) {
  42496. self::assertEquals(
  42497. $expectedElement->attributes->length,
  42498. $actualElement->attributes->length,
  42499. sprintf(
  42500. '%s%sNumber of attributes on node "%s" does not match',
  42501. $message,
  42502. !empty($message) ? "\n" : '',
  42503. $expectedElement->tagName
  42504. )
  42505. );
  42506. for ($i = 0; $i < $expectedElement->attributes->length; $i++) {
  42507. $expectedAttribute = $expectedElement->attributes->item($i);
  42508. $actualAttribute = $actualElement->attributes->getNamedItem(
  42509. $expectedAttribute->name
  42510. );
  42511. if (!$actualAttribute) {
  42512. self::fail(
  42513. sprintf(
  42514. '%s%sCould not find attribute "%s" on node "%s"',
  42515. $message,
  42516. !empty($message) ? "\n" : '',
  42517. $expectedAttribute->name,
  42518. $expectedElement->tagName
  42519. )
  42520. );
  42521. }
  42522. }
  42523. }
  42524. PHPUnit_Util_XML::removeCharacterDataNodes($expectedElement);
  42525. PHPUnit_Util_XML::removeCharacterDataNodes($actualElement);
  42526. self::assertEquals(
  42527. $expectedElement->childNodes->length,
  42528. $actualElement->childNodes->length,
  42529. sprintf(
  42530. '%s%sNumber of child nodes of "%s" differs',
  42531. $message,
  42532. !empty($message) ? "\n" : '',
  42533. $expectedElement->tagName
  42534. )
  42535. );
  42536. for ($i = 0; $i < $expectedElement->childNodes->length; $i++) {
  42537. self::assertEqualXMLStructure(
  42538. $expectedElement->childNodes->item($i),
  42539. $actualElement->childNodes->item($i),
  42540. $checkAttributes,
  42541. $message
  42542. );
  42543. }
  42544. }
  42545. /**
  42546. * Assert the presence, absence, or count of elements in a document matching
  42547. * the CSS $selector, regardless of the contents of those elements.
  42548. *
  42549. * The first argument, $selector, is the CSS selector used to match
  42550. * the elements in the $actual document.
  42551. *
  42552. * The second argument, $count, can be either boolean or numeric.
  42553. * When boolean, it asserts for presence of elements matching the selector
  42554. * (true) or absence of elements (false).
  42555. * When numeric, it asserts the count of elements.
  42556. *
  42557. * assertSelectCount("#binder", true, $xml); // any?
  42558. * assertSelectCount(".binder", 3, $xml); // exactly 3?
  42559. *
  42560. * @param array $selector
  42561. * @param integer|boolean|array $count
  42562. * @param mixed $actual
  42563. * @param string $message
  42564. * @param boolean $isHtml
  42565. * @since Method available since Release 3.3.0
  42566. * @author Mike Naberezny <mike@maintainable.com>
  42567. * @author Derek DeVries <derek@maintainable.com>
  42568. * @deprecated
  42569. */
  42570. public static function assertSelectCount($selector, $count, $actual, $message = '', $isHtml = true)
  42571. {
  42572. trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  42573. self::assertSelectEquals(
  42574. $selector,
  42575. true,
  42576. $count,
  42577. $actual,
  42578. $message,
  42579. $isHtml
  42580. );
  42581. }
  42582. /**
  42583. * assertSelectRegExp("#binder .name", "/Mike|Derek/", true, $xml); // any?
  42584. * assertSelectRegExp("#binder .name", "/Mike|Derek/", 3, $xml); // 3?
  42585. *
  42586. * @param array $selector
  42587. * @param string $pattern
  42588. * @param integer|boolean|array $count
  42589. * @param mixed $actual
  42590. * @param string $message
  42591. * @param boolean $isHtml
  42592. * @since Method available since Release 3.3.0
  42593. * @author Mike Naberezny <mike@maintainable.com>
  42594. * @author Derek DeVries <derek@maintainable.com>
  42595. * @deprecated
  42596. */
  42597. public static function assertSelectRegExp($selector, $pattern, $count, $actual, $message = '', $isHtml = true)
  42598. {
  42599. trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  42600. self::assertSelectEquals(
  42601. $selector,
  42602. "regexp:$pattern",
  42603. $count,
  42604. $actual,
  42605. $message,
  42606. $isHtml
  42607. );
  42608. }
  42609. /**
  42610. * assertSelectEquals("#binder .name", "Chuck", true, $xml); // any?
  42611. * assertSelectEquals("#binder .name", "Chuck", false, $xml); // none?
  42612. *
  42613. * @param array $selector
  42614. * @param string $content
  42615. * @param integer|boolean|array $count
  42616. * @param mixed $actual
  42617. * @param string $message
  42618. * @param boolean $isHtml
  42619. * @since Method available since Release 3.3.0
  42620. * @author Mike Naberezny <mike@maintainable.com>
  42621. * @author Derek DeVries <derek@maintainable.com>
  42622. * @deprecated
  42623. */
  42624. public static function assertSelectEquals($selector, $content, $count, $actual, $message = '', $isHtml = true)
  42625. {
  42626. trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  42627. $tags = PHPUnit_Util_XML::cssSelect(
  42628. $selector,
  42629. $content,
  42630. $actual,
  42631. $isHtml
  42632. );
  42633. // assert specific number of elements
  42634. if (is_numeric($count)) {
  42635. $counted = $tags ? count($tags) : 0;
  42636. self::assertEquals($count, $counted, $message);
  42637. } // assert any elements exist if true, assert no elements exist if false
  42638. elseif (is_bool($count)) {
  42639. $any = count($tags) > 0 && $tags[0] instanceof DOMNode;
  42640. if ($count) {
  42641. self::assertTrue($any, $message);
  42642. } else {
  42643. self::assertFalse($any, $message);
  42644. }
  42645. } // check for range number of elements
  42646. elseif (is_array($count) &&
  42647. (isset($count['>']) || isset($count['<']) ||
  42648. isset($count['>=']) || isset($count['<=']))) {
  42649. $counted = $tags ? count($tags) : 0;
  42650. if (isset($count['>'])) {
  42651. self::assertTrue($counted > $count['>'], $message);
  42652. }
  42653. if (isset($count['>='])) {
  42654. self::assertTrue($counted >= $count['>='], $message);
  42655. }
  42656. if (isset($count['<'])) {
  42657. self::assertTrue($counted < $count['<'], $message);
  42658. }
  42659. if (isset($count['<='])) {
  42660. self::assertTrue($counted <= $count['<='], $message);
  42661. }
  42662. } else {
  42663. throw new PHPUnit_Framework_Exception;
  42664. }
  42665. }
  42666. /**
  42667. * Evaluate an HTML or XML string and assert its structure and/or contents.
  42668. *
  42669. * The first argument ($matcher) is an associative array that specifies the
  42670. * match criteria for the assertion:
  42671. *
  42672. * - `id` : the node with the given id attribute must match the
  42673. * corresponding value.
  42674. * - `tag` : the node type must match the corresponding value.
  42675. * - `attributes` : a hash. The node's attributes must match the
  42676. * corresponding values in the hash.
  42677. * - `content` : The text content must match the given value.
  42678. * - `parent` : a hash. The node's parent must match the
  42679. * corresponding hash.
  42680. * - `child` : a hash. At least one of the node's immediate children
  42681. * must meet the criteria described by the hash.
  42682. * - `ancestor` : a hash. At least one of the node's ancestors must
  42683. * meet the criteria described by the hash.
  42684. * - `descendant` : a hash. At least one of the node's descendants must
  42685. * meet the criteria described by the hash.
  42686. * - `children` : a hash, for counting children of a node.
  42687. * Accepts the keys:
  42688. * - `count` : a number which must equal the number of children
  42689. * that match
  42690. * - `less_than` : the number of matching children must be greater
  42691. * than this number
  42692. * - `greater_than` : the number of matching children must be less than
  42693. * this number
  42694. * - `only` : another hash consisting of the keys to use to match
  42695. * on the children, and only matching children will be
  42696. * counted
  42697. *
  42698. * <code>
  42699. * // Matcher that asserts that there is an element with an id="my_id".
  42700. * $matcher = array('id' => 'my_id');
  42701. *
  42702. * // Matcher that asserts that there is a "span" tag.
  42703. * $matcher = array('tag' => 'span');
  42704. *
  42705. * // Matcher that asserts that there is a "span" tag with the content
  42706. * // "Hello World".
  42707. * $matcher = array('tag' => 'span', 'content' => 'Hello World');
  42708. *
  42709. * // Matcher that asserts that there is a "span" tag with content matching
  42710. * // the regular expression pattern.
  42711. * $matcher = array('tag' => 'span', 'content' => 'regexp:/Try P(HP|ython)/');
  42712. *
  42713. * // Matcher that asserts that there is a "span" with an "list" class
  42714. * // attribute.
  42715. * $matcher = array(
  42716. * 'tag' => 'span',
  42717. * 'attributes' => array('class' => 'list')
  42718. * );
  42719. *
  42720. * // Matcher that asserts that there is a "span" inside of a "div".
  42721. * $matcher = array(
  42722. * 'tag' => 'span',
  42723. * 'parent' => array('tag' => 'div')
  42724. * );
  42725. *
  42726. * // Matcher that asserts that there is a "span" somewhere inside a
  42727. * // "table".
  42728. * $matcher = array(
  42729. * 'tag' => 'span',
  42730. * 'ancestor' => array('tag' => 'table')
  42731. * );
  42732. *
  42733. * // Matcher that asserts that there is a "span" with at least one "em"
  42734. * // child.
  42735. * $matcher = array(
  42736. * 'tag' => 'span',
  42737. * 'child' => array('tag' => 'em')
  42738. * );
  42739. *
  42740. * // Matcher that asserts that there is a "span" containing a (possibly
  42741. * // nested) "strong" tag.
  42742. * $matcher = array(
  42743. * 'tag' => 'span',
  42744. * 'descendant' => array('tag' => 'strong')
  42745. * );
  42746. *
  42747. * // Matcher that asserts that there is a "span" containing 5-10 "em" tags
  42748. * // as immediate children.
  42749. * $matcher = array(
  42750. * 'tag' => 'span',
  42751. * 'children' => array(
  42752. * 'less_than' => 11,
  42753. * 'greater_than' => 4,
  42754. * 'only' => array('tag' => 'em')
  42755. * )
  42756. * );
  42757. *
  42758. * // Matcher that asserts that there is a "div", with an "ul" ancestor and
  42759. * // a "li" parent (with class="enum"), and containing a "span" descendant
  42760. * // that contains an element with id="my_test" and the text "Hello World".
  42761. * $matcher = array(
  42762. * 'tag' => 'div',
  42763. * 'ancestor' => array('tag' => 'ul'),
  42764. * 'parent' => array(
  42765. * 'tag' => 'li',
  42766. * 'attributes' => array('class' => 'enum')
  42767. * ),
  42768. * 'descendant' => array(
  42769. * 'tag' => 'span',
  42770. * 'child' => array(
  42771. * 'id' => 'my_test',
  42772. * 'content' => 'Hello World'
  42773. * )
  42774. * )
  42775. * );
  42776. *
  42777. * // Use assertTag() to apply a $matcher to a piece of $html.
  42778. * $this->assertTag($matcher, $html);
  42779. *
  42780. * // Use assertTag() to apply a $matcher to a piece of $xml.
  42781. * $this->assertTag($matcher, $xml, '', false);
  42782. * </code>
  42783. *
  42784. * The second argument ($actual) is a string containing either HTML or
  42785. * XML text to be tested.
  42786. *
  42787. * The third argument ($message) is an optional message that will be
  42788. * used if the assertion fails.
  42789. *
  42790. * The fourth argument ($html) is an optional flag specifying whether
  42791. * to load the $actual string into a DOMDocument using the HTML or
  42792. * XML load strategy. It is true by default, which assumes the HTML
  42793. * load strategy. In many cases, this will be acceptable for XML as well.
  42794. *
  42795. * @param array $matcher
  42796. * @param string $actual
  42797. * @param string $message
  42798. * @param boolean $isHtml
  42799. * @since Method available since Release 3.3.0
  42800. * @author Mike Naberezny <mike@maintainable.com>
  42801. * @author Derek DeVries <derek@maintainable.com>
  42802. * @deprecated
  42803. */
  42804. public static function assertTag($matcher, $actual, $message = '', $isHtml = true)
  42805. {
  42806. trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  42807. $dom = PHPUnit_Util_XML::load($actual, $isHtml);
  42808. $tags = PHPUnit_Util_XML::findNodes($dom, $matcher, $isHtml);
  42809. $matched = count($tags) > 0 && $tags[0] instanceof DOMNode;
  42810. self::assertTrue($matched, $message);
  42811. }
  42812. /**
  42813. * This assertion is the exact opposite of assertTag().
  42814. *
  42815. * Rather than asserting that $matcher results in a match, it asserts that
  42816. * $matcher does not match.
  42817. *
  42818. * @param array $matcher
  42819. * @param string $actual
  42820. * @param string $message
  42821. * @param boolean $isHtml
  42822. * @since Method available since Release 3.3.0
  42823. * @author Mike Naberezny <mike@maintainable.com>
  42824. * @author Derek DeVries <derek@maintainable.com>
  42825. * @deprecated
  42826. */
  42827. public static function assertNotTag($matcher, $actual, $message = '', $isHtml = true)
  42828. {
  42829. trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  42830. $dom = PHPUnit_Util_XML::load($actual, $isHtml);
  42831. $tags = PHPUnit_Util_XML::findNodes($dom, $matcher, $isHtml);
  42832. $matched = count($tags) > 0 && $tags[0] instanceof DOMNode;
  42833. self::assertFalse($matched, $message);
  42834. }
  42835. /**
  42836. * Evaluates a PHPUnit_Framework_Constraint matcher object.
  42837. *
  42838. * @param mixed $value
  42839. * @param PHPUnit_Framework_Constraint $constraint
  42840. * @param string $message
  42841. * @since Method available since Release 3.0.0
  42842. */
  42843. public static function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '')
  42844. {
  42845. self::$count += count($constraint);
  42846. $constraint->evaluate($value, $message);
  42847. }
  42848. /**
  42849. * Asserts that a string is a valid JSON string.
  42850. *
  42851. * @param string $actualJson
  42852. * @param string $message
  42853. * @since Method available since Release 3.7.20
  42854. */
  42855. public static function assertJson($actualJson, $message = '')
  42856. {
  42857. if (!is_string($actualJson)) {
  42858. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42859. }
  42860. self::assertThat($actualJson, self::isJson(), $message);
  42861. }
  42862. /**
  42863. * Asserts that two given JSON encoded objects or arrays are equal.
  42864. *
  42865. * @param string $expectedJson
  42866. * @param string $actualJson
  42867. * @param string $message
  42868. */
  42869. public static function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = '')
  42870. {
  42871. self::assertJson($expectedJson, $message);
  42872. self::assertJson($actualJson, $message);
  42873. $expected = json_decode($expectedJson);
  42874. $actual = json_decode($actualJson);
  42875. self::assertEquals($expected, $actual, $message);
  42876. }
  42877. /**
  42878. * Asserts that two given JSON encoded objects or arrays are not equal.
  42879. *
  42880. * @param string $expectedJson
  42881. * @param string $actualJson
  42882. * @param string $message
  42883. */
  42884. public static function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message = '')
  42885. {
  42886. self::assertJson($expectedJson, $message);
  42887. self::assertJson($actualJson, $message);
  42888. $expected = json_decode($expectedJson);
  42889. $actual = json_decode($actualJson);
  42890. self::assertNotEquals($expected, $actual, $message);
  42891. }
  42892. /**
  42893. * Asserts that the generated JSON encoded object and the content of the given file are equal.
  42894. *
  42895. * @param string $expectedFile
  42896. * @param string $actualJson
  42897. * @param string $message
  42898. */
  42899. public static function assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message = '')
  42900. {
  42901. self::assertFileExists($expectedFile, $message);
  42902. $expectedJson = file_get_contents($expectedFile);
  42903. self::assertJson($expectedJson, $message);
  42904. self::assertJson($actualJson, $message);
  42905. // call constraint
  42906. $constraint = new PHPUnit_Framework_Constraint_JsonMatches(
  42907. $expectedJson
  42908. );
  42909. self::assertThat($actualJson, $constraint, $message);
  42910. }
  42911. /**
  42912. * Asserts that the generated JSON encoded object and the content of the given file are not equal.
  42913. *
  42914. * @param string $expectedFile
  42915. * @param string $actualJson
  42916. * @param string $message
  42917. */
  42918. public static function assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message = '')
  42919. {
  42920. self::assertFileExists($expectedFile, $message);
  42921. $expectedJson = file_get_contents($expectedFile);
  42922. self::assertJson($expectedJson, $message);
  42923. self::assertJson($actualJson, $message);
  42924. // call constraint
  42925. $constraint = new PHPUnit_Framework_Constraint_JsonMatches(
  42926. $expectedJson
  42927. );
  42928. self::assertThat($actualJson, new PHPUnit_Framework_Constraint_Not($constraint), $message);
  42929. }
  42930. /**
  42931. * Asserts that two JSON files are not equal.
  42932. *
  42933. * @param string $expectedFile
  42934. * @param string $actualFile
  42935. * @param string $message
  42936. */
  42937. public static function assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message = '')
  42938. {
  42939. self::assertFileExists($expectedFile, $message);
  42940. self::assertFileExists($actualFile, $message);
  42941. $actualJson = file_get_contents($actualFile);
  42942. $expectedJson = file_get_contents($expectedFile);
  42943. self::assertJson($expectedJson, $message);
  42944. self::assertJson($actualJson, $message);
  42945. // call constraint
  42946. $constraintExpected = new PHPUnit_Framework_Constraint_JsonMatches(
  42947. $expectedJson
  42948. );
  42949. $constraintActual = new PHPUnit_Framework_Constraint_JsonMatches($actualJson);
  42950. self::assertThat($expectedJson, new PHPUnit_Framework_Constraint_Not($constraintActual), $message);
  42951. self::assertThat($actualJson, new PHPUnit_Framework_Constraint_Not($constraintExpected), $message);
  42952. }
  42953. /**
  42954. * Asserts that two JSON files are equal.
  42955. *
  42956. * @param string $expectedFile
  42957. * @param string $actualFile
  42958. * @param string $message
  42959. */
  42960. public static function assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message = '')
  42961. {
  42962. self::assertFileExists($expectedFile, $message);
  42963. self::assertFileExists($actualFile, $message);
  42964. $actualJson = file_get_contents($actualFile);
  42965. $expectedJson = file_get_contents($expectedFile);
  42966. self::assertJson($expectedJson, $message);
  42967. self::assertJson($actualJson, $message);
  42968. // call constraint
  42969. $constraintExpected = new PHPUnit_Framework_Constraint_JsonMatches(
  42970. $expectedJson
  42971. );
  42972. $constraintActual = new PHPUnit_Framework_Constraint_JsonMatches($actualJson);
  42973. self::assertThat($expectedJson, $constraintActual, $message);
  42974. self::assertThat($actualJson, $constraintExpected, $message);
  42975. }
  42976. /**
  42977. * Returns a PHPUnit_Framework_Constraint_And matcher object.
  42978. *
  42979. * @return PHPUnit_Framework_Constraint_And
  42980. * @since Method available since Release 3.0.0
  42981. */
  42982. public static function logicalAnd()
  42983. {
  42984. $constraints = func_get_args();
  42985. $constraint = new PHPUnit_Framework_Constraint_And;
  42986. $constraint->setConstraints($constraints);
  42987. return $constraint;
  42988. }
  42989. /**
  42990. * Returns a PHPUnit_Framework_Constraint_Or matcher object.
  42991. *
  42992. * @return PHPUnit_Framework_Constraint_Or
  42993. * @since Method available since Release 3.0.0
  42994. */
  42995. public static function logicalOr()
  42996. {
  42997. $constraints = func_get_args();
  42998. $constraint = new PHPUnit_Framework_Constraint_Or;
  42999. $constraint->setConstraints($constraints);
  43000. return $constraint;
  43001. }
  43002. /**
  43003. * Returns a PHPUnit_Framework_Constraint_Not matcher object.
  43004. *
  43005. * @param PHPUnit_Framework_Constraint $constraint
  43006. * @return PHPUnit_Framework_Constraint_Not
  43007. * @since Method available since Release 3.0.0
  43008. */
  43009. public static function logicalNot(PHPUnit_Framework_Constraint $constraint)
  43010. {
  43011. return new PHPUnit_Framework_Constraint_Not($constraint);
  43012. }
  43013. /**
  43014. * Returns a PHPUnit_Framework_Constraint_Xor matcher object.
  43015. *
  43016. * @return PHPUnit_Framework_Constraint_Xor
  43017. * @since Method available since Release 3.0.0
  43018. */
  43019. public static function logicalXor()
  43020. {
  43021. $constraints = func_get_args();
  43022. $constraint = new PHPUnit_Framework_Constraint_Xor;
  43023. $constraint->setConstraints($constraints);
  43024. return $constraint;
  43025. }
  43026. /**
  43027. * Returns a PHPUnit_Framework_Constraint_IsAnything matcher object.
  43028. *
  43029. * @return PHPUnit_Framework_Constraint_IsAnything
  43030. * @since Method available since Release 3.0.0
  43031. */
  43032. public static function anything()
  43033. {
  43034. return new PHPUnit_Framework_Constraint_IsAnything;
  43035. }
  43036. /**
  43037. * Returns a PHPUnit_Framework_Constraint_IsTrue matcher object.
  43038. *
  43039. * @return PHPUnit_Framework_Constraint_IsTrue
  43040. * @since Method available since Release 3.3.0
  43041. */
  43042. public static function isTrue()
  43043. {
  43044. return new PHPUnit_Framework_Constraint_IsTrue;
  43045. }
  43046. /**
  43047. * Returns a PHPUnit_Framework_Constraint_Callback matcher object.
  43048. *
  43049. * @param callable $callback
  43050. * @return PHPUnit_Framework_Constraint_Callback
  43051. */
  43052. public static function callback($callback)
  43053. {
  43054. return new PHPUnit_Framework_Constraint_Callback($callback);
  43055. }
  43056. /**
  43057. * Returns a PHPUnit_Framework_Constraint_IsFalse matcher object.
  43058. *
  43059. * @return PHPUnit_Framework_Constraint_IsFalse
  43060. * @since Method available since Release 3.3.0
  43061. */
  43062. public static function isFalse()
  43063. {
  43064. return new PHPUnit_Framework_Constraint_IsFalse;
  43065. }
  43066. /**
  43067. * Returns a PHPUnit_Framework_Constraint_IsJson matcher object.
  43068. *
  43069. * @return PHPUnit_Framework_Constraint_IsJson
  43070. * @since Method available since Release 3.7.20
  43071. */
  43072. public static function isJson()
  43073. {
  43074. return new PHPUnit_Framework_Constraint_IsJson;
  43075. }
  43076. /**
  43077. * Returns a PHPUnit_Framework_Constraint_IsNull matcher object.
  43078. *
  43079. * @return PHPUnit_Framework_Constraint_IsNull
  43080. * @since Method available since Release 3.3.0
  43081. */
  43082. public static function isNull()
  43083. {
  43084. return new PHPUnit_Framework_Constraint_IsNull;
  43085. }
  43086. /**
  43087. * Returns a PHPUnit_Framework_Constraint_Attribute matcher object.
  43088. *
  43089. * @param PHPUnit_Framework_Constraint $constraint
  43090. * @param string $attributeName
  43091. * @return PHPUnit_Framework_Constraint_Attribute
  43092. * @since Method available since Release 3.1.0
  43093. */
  43094. public static function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName)
  43095. {
  43096. return new PHPUnit_Framework_Constraint_Attribute(
  43097. $constraint,
  43098. $attributeName
  43099. );
  43100. }
  43101. /**
  43102. * Returns a PHPUnit_Framework_Constraint_TraversableContains matcher
  43103. * object.
  43104. *
  43105. * @param mixed $value
  43106. * @param boolean $checkForObjectIdentity
  43107. * @param boolean $checkForNonObjectIdentity
  43108. * @return PHPUnit_Framework_Constraint_TraversableContains
  43109. * @since Method available since Release 3.0.0
  43110. */
  43111. public static function contains($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  43112. {
  43113. return new PHPUnit_Framework_Constraint_TraversableContains($value, $checkForObjectIdentity, $checkForNonObjectIdentity);
  43114. }
  43115. /**
  43116. * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
  43117. * object.
  43118. *
  43119. * @param string $type
  43120. * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
  43121. * @since Method available since Release 3.1.4
  43122. */
  43123. public static function containsOnly($type)
  43124. {
  43125. return new PHPUnit_Framework_Constraint_TraversableContainsOnly($type);
  43126. }
  43127. /**
  43128. * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
  43129. * object.
  43130. *
  43131. * @param string $classname
  43132. * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
  43133. */
  43134. public static function containsOnlyInstancesOf($classname)
  43135. {
  43136. return new PHPUnit_Framework_Constraint_TraversableContainsOnly($classname, false);
  43137. }
  43138. /**
  43139. * Returns a PHPUnit_Framework_Constraint_ArrayHasKey matcher object.
  43140. *
  43141. * @param mixed $key
  43142. * @return PHPUnit_Framework_Constraint_ArrayHasKey
  43143. * @since Method available since Release 3.0.0
  43144. */
  43145. public static function arrayHasKey($key)
  43146. {
  43147. return new PHPUnit_Framework_Constraint_ArrayHasKey($key);
  43148. }
  43149. /**
  43150. * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object.
  43151. *
  43152. * @param mixed $value
  43153. * @param float $delta
  43154. * @param integer $maxDepth
  43155. * @param boolean $canonicalize
  43156. * @param boolean $ignoreCase
  43157. * @return PHPUnit_Framework_Constraint_IsEqual
  43158. * @since Method available since Release 3.0.0
  43159. */
  43160. public static function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  43161. {
  43162. return new PHPUnit_Framework_Constraint_IsEqual(
  43163. $value,
  43164. $delta,
  43165. $maxDepth,
  43166. $canonicalize,
  43167. $ignoreCase
  43168. );
  43169. }
  43170. /**
  43171. * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object
  43172. * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher
  43173. * object.
  43174. *
  43175. * @param string $attributeName
  43176. * @param mixed $value
  43177. * @param float $delta
  43178. * @param integer $maxDepth
  43179. * @param boolean $canonicalize
  43180. * @param boolean $ignoreCase
  43181. * @return PHPUnit_Framework_Constraint_Attribute
  43182. * @since Method available since Release 3.1.0
  43183. */
  43184. public static function attributeEqualTo($attributeName, $value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  43185. {
  43186. return self::attribute(
  43187. self::equalTo(
  43188. $value,
  43189. $delta,
  43190. $maxDepth,
  43191. $canonicalize,
  43192. $ignoreCase
  43193. ),
  43194. $attributeName
  43195. );
  43196. }
  43197. /**
  43198. * Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object.
  43199. *
  43200. * @return PHPUnit_Framework_Constraint_IsEmpty
  43201. * @since Method available since Release 3.5.0
  43202. */
  43203. public static function isEmpty()
  43204. {
  43205. return new PHPUnit_Framework_Constraint_IsEmpty;
  43206. }
  43207. /**
  43208. * Returns a PHPUnit_Framework_Constraint_FileExists matcher object.
  43209. *
  43210. * @return PHPUnit_Framework_Constraint_FileExists
  43211. * @since Method available since Release 3.0.0
  43212. */
  43213. public static function fileExists()
  43214. {
  43215. return new PHPUnit_Framework_Constraint_FileExists;
  43216. }
  43217. /**
  43218. * Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object.
  43219. *
  43220. * @param mixed $value
  43221. * @return PHPUnit_Framework_Constraint_GreaterThan
  43222. * @since Method available since Release 3.0.0
  43223. */
  43224. public static function greaterThan($value)
  43225. {
  43226. return new PHPUnit_Framework_Constraint_GreaterThan($value);
  43227. }
  43228. /**
  43229. * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
  43230. * a PHPUnit_Framework_Constraint_IsEqual and a
  43231. * PHPUnit_Framework_Constraint_GreaterThan matcher object.
  43232. *
  43233. * @param mixed $value
  43234. * @return PHPUnit_Framework_Constraint_Or
  43235. * @since Method available since Release 3.1.0
  43236. */
  43237. public static function greaterThanOrEqual($value)
  43238. {
  43239. return self::logicalOr(
  43240. new PHPUnit_Framework_Constraint_IsEqual($value),
  43241. new PHPUnit_Framework_Constraint_GreaterThan($value)
  43242. );
  43243. }
  43244. /**
  43245. * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object.
  43246. *
  43247. * @param string $attributeName
  43248. * @return PHPUnit_Framework_Constraint_ClassHasAttribute
  43249. * @since Method available since Release 3.1.0
  43250. */
  43251. public static function classHasAttribute($attributeName)
  43252. {
  43253. return new PHPUnit_Framework_Constraint_ClassHasAttribute(
  43254. $attributeName
  43255. );
  43256. }
  43257. /**
  43258. * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher
  43259. * object.
  43260. *
  43261. * @param string $attributeName
  43262. * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute
  43263. * @since Method available since Release 3.1.0
  43264. */
  43265. public static function classHasStaticAttribute($attributeName)
  43266. {
  43267. return new PHPUnit_Framework_Constraint_ClassHasStaticAttribute(
  43268. $attributeName
  43269. );
  43270. }
  43271. /**
  43272. * Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object.
  43273. *
  43274. * @param string $attributeName
  43275. * @return PHPUnit_Framework_Constraint_ObjectHasAttribute
  43276. * @since Method available since Release 3.0.0
  43277. */
  43278. public static function objectHasAttribute($attributeName)
  43279. {
  43280. return new PHPUnit_Framework_Constraint_ObjectHasAttribute(
  43281. $attributeName
  43282. );
  43283. }
  43284. /**
  43285. * Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object.
  43286. *
  43287. * @param mixed $value
  43288. * @return PHPUnit_Framework_Constraint_IsIdentical
  43289. * @since Method available since Release 3.0.0
  43290. */
  43291. public static function identicalTo($value)
  43292. {
  43293. return new PHPUnit_Framework_Constraint_IsIdentical($value);
  43294. }
  43295. /**
  43296. * Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object.
  43297. *
  43298. * @param string $className
  43299. * @return PHPUnit_Framework_Constraint_IsInstanceOf
  43300. * @since Method available since Release 3.0.0
  43301. */
  43302. public static function isInstanceOf($className)
  43303. {
  43304. return new PHPUnit_Framework_Constraint_IsInstanceOf($className);
  43305. }
  43306. /**
  43307. * Returns a PHPUnit_Framework_Constraint_IsType matcher object.
  43308. *
  43309. * @param string $type
  43310. * @return PHPUnit_Framework_Constraint_IsType
  43311. * @since Method available since Release 3.0.0
  43312. */
  43313. public static function isType($type)
  43314. {
  43315. return new PHPUnit_Framework_Constraint_IsType($type);
  43316. }
  43317. /**
  43318. * Returns a PHPUnit_Framework_Constraint_LessThan matcher object.
  43319. *
  43320. * @param mixed $value
  43321. * @return PHPUnit_Framework_Constraint_LessThan
  43322. * @since Method available since Release 3.0.0
  43323. */
  43324. public static function lessThan($value)
  43325. {
  43326. return new PHPUnit_Framework_Constraint_LessThan($value);
  43327. }
  43328. /**
  43329. * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
  43330. * a PHPUnit_Framework_Constraint_IsEqual and a
  43331. * PHPUnit_Framework_Constraint_LessThan matcher object.
  43332. *
  43333. * @param mixed $value
  43334. * @return PHPUnit_Framework_Constraint_Or
  43335. * @since Method available since Release 3.1.0
  43336. */
  43337. public static function lessThanOrEqual($value)
  43338. {
  43339. return self::logicalOr(
  43340. new PHPUnit_Framework_Constraint_IsEqual($value),
  43341. new PHPUnit_Framework_Constraint_LessThan($value)
  43342. );
  43343. }
  43344. /**
  43345. * Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object.
  43346. *
  43347. * @param string $pattern
  43348. * @return PHPUnit_Framework_Constraint_PCREMatch
  43349. * @since Method available since Release 3.0.0
  43350. */
  43351. public static function matchesRegularExpression($pattern)
  43352. {
  43353. return new PHPUnit_Framework_Constraint_PCREMatch($pattern);
  43354. }
  43355. /**
  43356. * Returns a PHPUnit_Framework_Constraint_StringMatches matcher object.
  43357. *
  43358. * @param string $string
  43359. * @return PHPUnit_Framework_Constraint_StringMatches
  43360. * @since Method available since Release 3.5.0
  43361. */
  43362. public static function matches($string)
  43363. {
  43364. return new PHPUnit_Framework_Constraint_StringMatches($string);
  43365. }
  43366. /**
  43367. * Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object.
  43368. *
  43369. * @param mixed $prefix
  43370. * @return PHPUnit_Framework_Constraint_StringStartsWith
  43371. * @since Method available since Release 3.4.0
  43372. */
  43373. public static function stringStartsWith($prefix)
  43374. {
  43375. return new PHPUnit_Framework_Constraint_StringStartsWith($prefix);
  43376. }
  43377. /**
  43378. * Returns a PHPUnit_Framework_Constraint_StringContains matcher object.
  43379. *
  43380. * @param string $string
  43381. * @param boolean $case
  43382. * @return PHPUnit_Framework_Constraint_StringContains
  43383. * @since Method available since Release 3.0.0
  43384. */
  43385. public static function stringContains($string, $case = true)
  43386. {
  43387. return new PHPUnit_Framework_Constraint_StringContains($string, $case);
  43388. }
  43389. /**
  43390. * Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object.
  43391. *
  43392. * @param mixed $suffix
  43393. * @return PHPUnit_Framework_Constraint_StringEndsWith
  43394. * @since Method available since Release 3.4.0
  43395. */
  43396. public static function stringEndsWith($suffix)
  43397. {
  43398. return new PHPUnit_Framework_Constraint_StringEndsWith($suffix);
  43399. }
  43400. /**
  43401. * Returns a PHPUnit_Framework_Constraint_Count matcher object.
  43402. *
  43403. * @param int $count
  43404. * @return PHPUnit_Framework_Constraint_Count
  43405. */
  43406. public static function countOf($count)
  43407. {
  43408. return new PHPUnit_Framework_Constraint_Count($count);
  43409. }
  43410. /**
  43411. * Fails a test with the given message.
  43412. *
  43413. * @param string $message
  43414. * @throws PHPUnit_Framework_AssertionFailedError
  43415. */
  43416. public static function fail($message = '')
  43417. {
  43418. throw new PHPUnit_Framework_AssertionFailedError($message);
  43419. }
  43420. /**
  43421. * Returns the value of an attribute of a class or an object.
  43422. * This also works for attributes that are declared protected or private.
  43423. *
  43424. * @param mixed $classOrObject
  43425. * @param string $attributeName
  43426. * @return mixed
  43427. * @throws PHPUnit_Framework_Exception
  43428. */
  43429. public static function readAttribute($classOrObject, $attributeName)
  43430. {
  43431. if (!is_string($attributeName)) {
  43432. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  43433. }
  43434. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  43435. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
  43436. }
  43437. if (is_string($classOrObject)) {
  43438. if (!class_exists($classOrObject)) {
  43439. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  43440. 1,
  43441. 'class name'
  43442. );
  43443. }
  43444. return self::getStaticAttribute(
  43445. $classOrObject,
  43446. $attributeName
  43447. );
  43448. } elseif (is_object($classOrObject)) {
  43449. return self::getObjectAttribute(
  43450. $classOrObject,
  43451. $attributeName
  43452. );
  43453. } else {
  43454. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  43455. 1,
  43456. 'class name or object'
  43457. );
  43458. }
  43459. }
  43460. /**
  43461. * Returns the value of a static attribute.
  43462. * This also works for attributes that are declared protected or private.
  43463. *
  43464. * @param string $className
  43465. * @param string $attributeName
  43466. * @return mixed
  43467. * @throws PHPUnit_Framework_Exception
  43468. * @since Method available since Release 4.0.0
  43469. */
  43470. public static function getStaticAttribute($className, $attributeName)
  43471. {
  43472. if (!is_string($className)) {
  43473. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  43474. }
  43475. if (!class_exists($className)) {
  43476. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class name');
  43477. }
  43478. if (!is_string($attributeName)) {
  43479. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  43480. }
  43481. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  43482. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
  43483. }
  43484. $class = new ReflectionClass($className);
  43485. while ($class) {
  43486. $attributes = $class->getStaticProperties();
  43487. if (array_key_exists($attributeName, $attributes)) {
  43488. return $attributes[$attributeName];
  43489. }
  43490. $class = $class->getParentClass();
  43491. }
  43492. throw new PHPUnit_Framework_Exception(
  43493. sprintf(
  43494. 'Attribute "%s" not found in class.',
  43495. $attributeName
  43496. )
  43497. );
  43498. }
  43499. /**
  43500. * Returns the value of an object's attribute.
  43501. * This also works for attributes that are declared protected or private.
  43502. *
  43503. * @param object $object
  43504. * @param string $attributeName
  43505. * @return mixed
  43506. * @throws PHPUnit_Framework_Exception
  43507. * @since Method available since Release 4.0.0
  43508. */
  43509. public static function getObjectAttribute($object, $attributeName)
  43510. {
  43511. if (!is_object($object)) {
  43512. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'object');
  43513. }
  43514. if (!is_string($attributeName)) {
  43515. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  43516. }
  43517. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  43518. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
  43519. }
  43520. try {
  43521. $attribute = new ReflectionProperty($object, $attributeName);
  43522. } catch (ReflectionException $e) {
  43523. $reflector = new ReflectionObject($object);
  43524. while ($reflector = $reflector->getParentClass()) {
  43525. try {
  43526. $attribute = $reflector->getProperty($attributeName);
  43527. break;
  43528. } catch (ReflectionException $e) {
  43529. }
  43530. }
  43531. }
  43532. if (isset($attribute)) {
  43533. if (!$attribute || $attribute->isPublic()) {
  43534. return $object->$attributeName;
  43535. }
  43536. $attribute->setAccessible(true);
  43537. $value = $attribute->getValue($object);
  43538. $attribute->setAccessible(false);
  43539. return $value;
  43540. }
  43541. throw new PHPUnit_Framework_Exception(
  43542. sprintf(
  43543. 'Attribute "%s" not found in object.',
  43544. $attributeName
  43545. )
  43546. );
  43547. }
  43548. /**
  43549. * Mark the test as incomplete.
  43550. *
  43551. * @param string $message
  43552. * @throws PHPUnit_Framework_IncompleteTestError
  43553. * @since Method available since Release 3.0.0
  43554. */
  43555. public static function markTestIncomplete($message = '')
  43556. {
  43557. throw new PHPUnit_Framework_IncompleteTestError($message);
  43558. }
  43559. /**
  43560. * Mark the test as skipped.
  43561. *
  43562. * @param string $message
  43563. * @throws PHPUnit_Framework_SkippedTestError
  43564. * @since Method available since Release 3.0.0
  43565. */
  43566. public static function markTestSkipped($message = '')
  43567. {
  43568. throw new PHPUnit_Framework_SkippedTestError($message);
  43569. }
  43570. /**
  43571. * Return the current assertion count.
  43572. *
  43573. * @return integer
  43574. * @since Method available since Release 3.3.3
  43575. */
  43576. public static function getCount()
  43577. {
  43578. return self::$count;
  43579. }
  43580. /**
  43581. * Reset the assertion counter.
  43582. *
  43583. * @since Method available since Release 3.3.3
  43584. */
  43585. public static function resetCount()
  43586. {
  43587. self::$count = 0;
  43588. }
  43589. }
  43590. <?php
  43591. /*
  43592. * This file is part of PHPUnit.
  43593. *
  43594. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43595. *
  43596. * For the full copyright and license information, please view the LICENSE
  43597. * file that was distributed with this source code.
  43598. */
  43599. /**
  43600. * @package PHPUnit
  43601. * @subpackage Framework
  43602. * @author Sebastian Bergmann <sebastian@phpunit.de>
  43603. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  43604. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  43605. * @link http://www.phpunit.de/
  43606. * @since Class available since Release 4.0.0
  43607. */
  43608. class PHPUnit_Framework_CodeCoverageException extends PHPUnit_Framework_Exception
  43609. {
  43610. }
  43611. <?php
  43612. /*
  43613. * This file is part of PHPUnit.
  43614. *
  43615. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43616. *
  43617. * For the full copyright and license information, please view the LICENSE
  43618. * file that was distributed with this source code.
  43619. */
  43620. /**
  43621. * A TestSuite is a composite of Tests. It runs a collection of test cases.
  43622. *
  43623. * Here is an example using the dynamic test definition.
  43624. *
  43625. * <code>
  43626. * <?php
  43627. * $suite = new PHPUnit_Framework_TestSuite;
  43628. * $suite->addTest(new MathTest('testPass'));
  43629. * ?>
  43630. * </code>
  43631. *
  43632. * Alternatively, a TestSuite can extract the tests to be run automatically.
  43633. * To do so you pass a ReflectionClass instance for your
  43634. * PHPUnit_Framework_TestCase class to the PHPUnit_Framework_TestSuite
  43635. * constructor.
  43636. *
  43637. * <code>
  43638. * <?php
  43639. * $suite = new PHPUnit_Framework_TestSuite(
  43640. * new ReflectionClass('MathTest')
  43641. * );
  43642. * ?>
  43643. * </code>
  43644. *
  43645. * This constructor creates a suite with all the methods starting with
  43646. * "test" that take no arguments.
  43647. *
  43648. * @package PHPUnit
  43649. * @subpackage Framework
  43650. * @author Sebastian Bergmann <sebastian@phpunit.de>
  43651. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  43652. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  43653. * @link http://www.phpunit.de/
  43654. * @since Class available since Release 2.0.0
  43655. */
  43656. class PHPUnit_Framework_TestSuite implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing, IteratorAggregate
  43657. {
  43658. /**
  43659. * Last count of tests in this suite.
  43660. *
  43661. * @var integer|null
  43662. */
  43663. private $cachedNumTests;
  43664. /**
  43665. * Enable or disable the backup and restoration of the $GLOBALS array.
  43666. *
  43667. * @var boolean
  43668. */
  43669. protected $backupGlobals = null;
  43670. /**
  43671. * Enable or disable the backup and restoration of static attributes.
  43672. *
  43673. * @var boolean
  43674. */
  43675. protected $backupStaticAttributes = null;
  43676. /**
  43677. * @var boolean
  43678. */
  43679. private $disallowChangesToGlobalState = null;
  43680. /**
  43681. * @var boolean
  43682. */
  43683. protected $runTestInSeparateProcess = false;
  43684. /**
  43685. * The name of the test suite.
  43686. *
  43687. * @var string
  43688. */
  43689. protected $name = '';
  43690. /**
  43691. * The test groups of the test suite.
  43692. *
  43693. * @var array
  43694. */
  43695. protected $groups = array();
  43696. /**
  43697. * The tests in the test suite.
  43698. *
  43699. * @var array
  43700. */
  43701. protected $tests = array();
  43702. /**
  43703. * The number of tests in the test suite.
  43704. *
  43705. * @var integer
  43706. */
  43707. protected $numTests = -1;
  43708. /**
  43709. * @var boolean
  43710. */
  43711. protected $testCase = false;
  43712. /**
  43713. * @var array
  43714. */
  43715. protected $foundClasses = array();
  43716. /**
  43717. * @var PHPUnit_Runner_Filter_Factory
  43718. */
  43719. private $iteratorFilter = null;
  43720. /**
  43721. * Constructs a new TestSuite:
  43722. *
  43723. * - PHPUnit_Framework_TestSuite() constructs an empty TestSuite.
  43724. *
  43725. * - PHPUnit_Framework_TestSuite(ReflectionClass) constructs a
  43726. * TestSuite from the given class.
  43727. *
  43728. * - PHPUnit_Framework_TestSuite(ReflectionClass, String)
  43729. * constructs a TestSuite from the given class with the given
  43730. * name.
  43731. *
  43732. * - PHPUnit_Framework_TestSuite(String) either constructs a
  43733. * TestSuite from the given class (if the passed string is the
  43734. * name of an existing class) or constructs an empty TestSuite
  43735. * with the given name.
  43736. *
  43737. * @param mixed $theClass
  43738. * @param string $name
  43739. * @throws PHPUnit_Framework_Exception
  43740. */
  43741. public function __construct($theClass = '', $name = '')
  43742. {
  43743. $argumentsValid = false;
  43744. if (is_object($theClass) &&
  43745. $theClass instanceof ReflectionClass) {
  43746. $argumentsValid = true;
  43747. } elseif (is_string($theClass) &&
  43748. $theClass !== '' &&
  43749. class_exists($theClass, false)) {
  43750. $argumentsValid = true;
  43751. if ($name == '') {
  43752. $name = $theClass;
  43753. }
  43754. $theClass = new ReflectionClass($theClass);
  43755. } elseif (is_string($theClass)) {
  43756. $this->setName($theClass);
  43757. return;
  43758. }
  43759. if (!$argumentsValid) {
  43760. throw new PHPUnit_Framework_Exception;
  43761. }
  43762. if (!$theClass->isSubclassOf('PHPUnit_Framework_TestCase')) {
  43763. throw new PHPUnit_Framework_Exception(
  43764. 'Class "' . $theClass->name . '" does not extend PHPUnit_Framework_TestCase.'
  43765. );
  43766. }
  43767. if ($name != '') {
  43768. $this->setName($name);
  43769. } else {
  43770. $this->setName($theClass->getName());
  43771. }
  43772. $constructor = $theClass->getConstructor();
  43773. if ($constructor !== null &&
  43774. !$constructor->isPublic()) {
  43775. $this->addTest(
  43776. self::warning(
  43777. sprintf(
  43778. 'Class "%s" has no public constructor.',
  43779. $theClass->getName()
  43780. )
  43781. )
  43782. );
  43783. return;
  43784. }
  43785. foreach ($theClass->getMethods() as $method) {
  43786. $this->addTestMethod($theClass, $method);
  43787. }
  43788. if (empty($this->tests)) {
  43789. $this->addTest(
  43790. self::warning(
  43791. sprintf(
  43792. 'No tests found in class "%s".',
  43793. $theClass->getName()
  43794. )
  43795. )
  43796. );
  43797. }
  43798. $this->testCase = true;
  43799. }
  43800. /**
  43801. * Returns a string representation of the test suite.
  43802. *
  43803. * @return string
  43804. */
  43805. public function toString()
  43806. {
  43807. return $this->getName();
  43808. }
  43809. /**
  43810. * Adds a test to the suite.
  43811. *
  43812. * @param PHPUnit_Framework_Test $test
  43813. * @param array $groups
  43814. */
  43815. public function addTest(PHPUnit_Framework_Test $test, $groups = array())
  43816. {
  43817. $class = new ReflectionClass($test);
  43818. if (!$class->isAbstract()) {
  43819. $this->tests[] = $test;
  43820. $this->numTests = -1;
  43821. if ($test instanceof PHPUnit_Framework_TestSuite &&
  43822. empty($groups)) {
  43823. $groups = $test->getGroups();
  43824. }
  43825. if (empty($groups)) {
  43826. $groups = array('__nogroup__');
  43827. }
  43828. foreach ($groups as $group) {
  43829. if (!isset($this->groups[$group])) {
  43830. $this->groups[$group] = array($test);
  43831. } else {
  43832. $this->groups[$group][] = $test;
  43833. }
  43834. }
  43835. }
  43836. }
  43837. /**
  43838. * Adds the tests from the given class to the suite.
  43839. *
  43840. * @param mixed $testClass
  43841. * @throws PHPUnit_Framework_Exception
  43842. */
  43843. public function addTestSuite($testClass)
  43844. {
  43845. if (is_string($testClass) && class_exists($testClass)) {
  43846. $testClass = new ReflectionClass($testClass);
  43847. }
  43848. if (!is_object($testClass)) {
  43849. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  43850. 1,
  43851. 'class name or object'
  43852. );
  43853. }
  43854. if ($testClass instanceof PHPUnit_Framework_TestSuite) {
  43855. $this->addTest($testClass);
  43856. } elseif ($testClass instanceof ReflectionClass) {
  43857. $suiteMethod = false;
  43858. if (!$testClass->isAbstract()) {
  43859. if ($testClass->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) {
  43860. $method = $testClass->getMethod(
  43861. PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME
  43862. );
  43863. if ($method->isStatic()) {
  43864. $this->addTest(
  43865. $method->invoke(null, $testClass->getName())
  43866. );
  43867. $suiteMethod = true;
  43868. }
  43869. }
  43870. }
  43871. if (!$suiteMethod && !$testClass->isAbstract()) {
  43872. $this->addTest(new PHPUnit_Framework_TestSuite($testClass));
  43873. }
  43874. } else {
  43875. throw new PHPUnit_Framework_Exception;
  43876. }
  43877. }
  43878. /**
  43879. * Wraps both <code>addTest()</code> and <code>addTestSuite</code>
  43880. * as well as the separate import statements for the user's convenience.
  43881. *
  43882. * If the named file cannot be read or there are no new tests that can be
  43883. * added, a <code>PHPUnit_Framework_Warning</code> will be created instead,
  43884. * leaving the current test run untouched.
  43885. *
  43886. * @param string $filename
  43887. * @param array $phptOptions Array with ini settings for the php instance
  43888. * run, key being the name if the setting,
  43889. * value the ini value.
  43890. * @throws PHPUnit_Framework_Exception
  43891. * @since Method available since Release 2.3.0
  43892. * @author Stefano F. Rausch <stefano@rausch-e.net>
  43893. */
  43894. public function addTestFile($filename, $phptOptions = array())
  43895. {
  43896. if (!is_string($filename)) {
  43897. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  43898. }
  43899. if (file_exists($filename) && substr($filename, -5) == '.phpt') {
  43900. $this->addTest(
  43901. new PHPUnit_Extensions_PhptTestCase($filename, $phptOptions)
  43902. );
  43903. return;
  43904. }
  43905. // The given file may contain further stub classes in addition to the
  43906. // test class itself. Figure out the actual test class.
  43907. $classes = get_declared_classes();
  43908. $filename = PHPUnit_Util_Fileloader::checkAndLoad($filename);
  43909. $newClasses = array_diff(get_declared_classes(), $classes);
  43910. // The diff is empty in case a parent class (with test methods) is added
  43911. // AFTER a child class that inherited from it. To account for that case,
  43912. // cumulate all discovered classes, so the parent class may be found in
  43913. // a later invocation.
  43914. if ($newClasses) {
  43915. // On the assumption that test classes are defined first in files,
  43916. // process discovered classes in approximate LIFO order, so as to
  43917. // avoid unnecessary reflection.
  43918. $this->foundClasses = array_merge($newClasses, $this->foundClasses);
  43919. }
  43920. // The test class's name must match the filename, either in full, or as
  43921. // a PEAR/PSR-0 prefixed shortname ('NameSpace_ShortName'), or as a
  43922. // PSR-1 local shortname ('NameSpace\ShortName'). The comparison must be
  43923. // anchored to prevent false-positive matches (e.g., 'OtherShortName').
  43924. $shortname = basename($filename, '.php');
  43925. $shortnameRegEx = '/(?:^|_|\\\\)' . preg_quote($shortname, '/') . '$/';
  43926. foreach ($this->foundClasses as $i => $className) {
  43927. if (preg_match($shortnameRegEx, $className)) {
  43928. $class = new ReflectionClass($className);
  43929. if ($class->getFileName() == $filename) {
  43930. $newClasses = array($className);
  43931. unset($this->foundClasses[$i]);
  43932. break;
  43933. }
  43934. }
  43935. }
  43936. foreach ($newClasses as $className) {
  43937. $class = new ReflectionClass($className);
  43938. if (!$class->isAbstract()) {
  43939. if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) {
  43940. $method = $class->getMethod(
  43941. PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME
  43942. );
  43943. if ($method->isStatic()) {
  43944. $this->addTest($method->invoke(null, $className));
  43945. }
  43946. } elseif ($class->implementsInterface('PHPUnit_Framework_Test')) {
  43947. $this->addTestSuite($class);
  43948. }
  43949. }
  43950. }
  43951. $this->numTests = -1;
  43952. }
  43953. /**
  43954. * Wrapper for addTestFile() that adds multiple test files.
  43955. *
  43956. * @param array|Iterator $filenames
  43957. * @throws PHPUnit_Framework_Exception
  43958. * @since Method available since Release 2.3.0
  43959. */
  43960. public function addTestFiles($filenames)
  43961. {
  43962. if (!(is_array($filenames) ||
  43963. (is_object($filenames) && $filenames instanceof Iterator))) {
  43964. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  43965. 1,
  43966. 'array or iterator'
  43967. );
  43968. }
  43969. foreach ($filenames as $filename) {
  43970. $this->addTestFile((string) $filename);
  43971. }
  43972. }
  43973. /**
  43974. * Counts the number of test cases that will be run by this test.
  43975. *
  43976. * @param boolean $preferCache Indicates if cache is preferred.
  43977. * @return integer
  43978. */
  43979. public function count($preferCache = false)
  43980. {
  43981. if ($preferCache && $this->cachedNumTests != null) {
  43982. $numTests = $this->cachedNumTests;
  43983. } else {
  43984. $numTests = 0;
  43985. foreach ($this as $test) {
  43986. $numTests += count($test);
  43987. }
  43988. $this->cachedNumTests = $numTests;
  43989. }
  43990. return $numTests;
  43991. }
  43992. /**
  43993. * @param ReflectionClass $theClass
  43994. * @param string $name
  43995. * @return PHPUnit_Framework_Test
  43996. * @throws PHPUnit_Framework_Exception
  43997. */
  43998. public static function createTest(ReflectionClass $theClass, $name)
  43999. {
  44000. $className = $theClass->getName();
  44001. if (!$theClass->isInstantiable()) {
  44002. return self::warning(
  44003. sprintf('Cannot instantiate class "%s".', $className)
  44004. );
  44005. }
  44006. $backupSettings = PHPUnit_Util_Test::getBackupSettings(
  44007. $className,
  44008. $name
  44009. );
  44010. $preserveGlobalState = PHPUnit_Util_Test::getPreserveGlobalStateSettings(
  44011. $className,
  44012. $name
  44013. );
  44014. $runTestInSeparateProcess = PHPUnit_Util_Test::getProcessIsolationSettings(
  44015. $className,
  44016. $name
  44017. );
  44018. $constructor = $theClass->getConstructor();
  44019. if ($constructor !== null) {
  44020. $parameters = $constructor->getParameters();
  44021. // TestCase() or TestCase($name)
  44022. if (count($parameters) < 2) {
  44023. $test = new $className;
  44024. } // TestCase($name, $data)
  44025. else {
  44026. try {
  44027. $data = PHPUnit_Util_Test::getProvidedData(
  44028. $className,
  44029. $name
  44030. );
  44031. } catch (Exception $e) {
  44032. if (!($e instanceof PHPUnit_Framework_SkippedTestError || $e instanceof PHPUnit_Framework_IncompleteTestError)) {
  44033. $message = sprintf(
  44034. 'The data provider specified for %s::%s is invalid.',
  44035. $className,
  44036. $name
  44037. );
  44038. $_message = $e->getMessage();
  44039. if (!empty($_message)) {
  44040. $message .= "\n" . $_message;
  44041. }
  44042. $data = self::warning($message);
  44043. } elseif ($e instanceof PHPUnit_Framework_SkippedTestError) {
  44044. $message = sprintf(
  44045. 'Test for %s::%s skipped by data provider',
  44046. $className,
  44047. $name
  44048. );
  44049. $_message = $e->getMessage();
  44050. if (!empty($_message)) {
  44051. $message .= "\n" . $_message;
  44052. }
  44053. $data = self::skipTest($className, $name, $message);
  44054. } elseif ($e instanceof PHPUnit_Framework_IncompleteTestError) {
  44055. $message = sprintf(
  44056. 'Test for %s::%s marked incomplete by data provider',
  44057. $className,
  44058. $name
  44059. );
  44060. $_message = $e->getMessage();
  44061. if (!empty($_message)) {
  44062. $message .= "\n" . $_message;
  44063. }
  44064. $data = self::incompleteTest($className, $name, $message);
  44065. }
  44066. }
  44067. // Test method with @dataProvider.
  44068. if (isset($data)) {
  44069. $test = new PHPUnit_Framework_TestSuite_DataProvider(
  44070. $className . '::' . $name
  44071. );
  44072. if (empty($data)) {
  44073. $data = self::warning(
  44074. sprintf(
  44075. 'No tests found in suite "%s".',
  44076. $test->getName()
  44077. )
  44078. );
  44079. }
  44080. $groups = PHPUnit_Util_Test::getGroups($className, $name);
  44081. if ($data instanceof PHPUnit_Framework_Warning ||
  44082. $data instanceof PHPUnit_Framework_SkippedTestCase ||
  44083. $data instanceof PHPUnit_Framework_IncompleteTestCase) {
  44084. $test->addTest($data, $groups);
  44085. } else {
  44086. foreach ($data as $_dataName => $_data) {
  44087. $_test = new $className($name, $_data, $_dataName);
  44088. if ($runTestInSeparateProcess) {
  44089. $_test->setRunTestInSeparateProcess(true);
  44090. if ($preserveGlobalState !== null) {
  44091. $_test->setPreserveGlobalState($preserveGlobalState);
  44092. }
  44093. }
  44094. if ($backupSettings['backupGlobals'] !== null) {
  44095. $_test->setBackupGlobals(
  44096. $backupSettings['backupGlobals']
  44097. );
  44098. }
  44099. if ($backupSettings['backupStaticAttributes'] !== null) {
  44100. $_test->setBackupStaticAttributes(
  44101. $backupSettings['backupStaticAttributes']
  44102. );
  44103. }
  44104. $test->addTest($_test, $groups);
  44105. }
  44106. }
  44107. } else {
  44108. $test = new $className;
  44109. }
  44110. }
  44111. }
  44112. if (!isset($test)) {
  44113. throw new PHPUnit_Framework_Exception('No valid test provided.');
  44114. }
  44115. if ($test instanceof PHPUnit_Framework_TestCase) {
  44116. $test->setName($name);
  44117. if ($runTestInSeparateProcess) {
  44118. $test->setRunTestInSeparateProcess(true);
  44119. if ($preserveGlobalState !== null) {
  44120. $test->setPreserveGlobalState($preserveGlobalState);
  44121. }
  44122. }
  44123. if ($backupSettings['backupGlobals'] !== null) {
  44124. $test->setBackupGlobals($backupSettings['backupGlobals']);
  44125. }
  44126. if ($backupSettings['backupStaticAttributes'] !== null) {
  44127. $test->setBackupStaticAttributes(
  44128. $backupSettings['backupStaticAttributes']
  44129. );
  44130. }
  44131. }
  44132. return $test;
  44133. }
  44134. /**
  44135. * Creates a default TestResult object.
  44136. *
  44137. * @return PHPUnit_Framework_TestResult
  44138. */
  44139. protected function createResult()
  44140. {
  44141. return new PHPUnit_Framework_TestResult;
  44142. }
  44143. /**
  44144. * Returns the name of the suite.
  44145. *
  44146. * @return string
  44147. */
  44148. public function getName()
  44149. {
  44150. return $this->name;
  44151. }
  44152. /**
  44153. * Returns the test groups of the suite.
  44154. *
  44155. * @return array
  44156. * @since Method available since Release 3.2.0
  44157. */
  44158. public function getGroups()
  44159. {
  44160. return array_keys($this->groups);
  44161. }
  44162. public function getGroupDetails()
  44163. {
  44164. return $this->groups;
  44165. }
  44166. /**
  44167. * Set tests groups of the test case
  44168. *
  44169. * @param array $groups
  44170. * @since Method available since Release 4.0.0
  44171. */
  44172. public function setGroupDetails(array $groups)
  44173. {
  44174. $this->groups = $groups;
  44175. }
  44176. /**
  44177. * Runs the tests and collects their result in a TestResult.
  44178. *
  44179. * @param PHPUnit_Framework_TestResult $result
  44180. * @return PHPUnit_Framework_TestResult
  44181. */
  44182. public function run(PHPUnit_Framework_TestResult $result = null)
  44183. {
  44184. if ($result === null) {
  44185. $result = $this->createResult();
  44186. }
  44187. if (count($this) == 0) {
  44188. return $result;
  44189. }
  44190. $hookMethods = PHPUnit_Util_Test::getHookMethods($this->name);
  44191. $result->startTestSuite($this);
  44192. try {
  44193. $this->setUp();
  44194. foreach ($hookMethods['beforeClass'] as $beforeClassMethod) {
  44195. if ($this->testCase === true &&
  44196. class_exists($this->name, false) &&
  44197. method_exists($this->name, $beforeClassMethod)) {
  44198. if ($missingRequirements = PHPUnit_Util_Test::getMissingRequirements($this->name, $beforeClassMethod)) {
  44199. $this->markTestSuiteSkipped(implode(PHP_EOL, $missingRequirements));
  44200. }
  44201. call_user_func(array($this->name, $beforeClassMethod));
  44202. }
  44203. }
  44204. } catch (PHPUnit_Framework_SkippedTestSuiteError $e) {
  44205. $numTests = count($this);
  44206. for ($i = 0; $i < $numTests; $i++) {
  44207. $result->startTest($this);
  44208. $result->addFailure($this, $e, 0);
  44209. $result->endTest($this, 0);
  44210. }
  44211. $this->tearDown();
  44212. $result->endTestSuite($this);
  44213. return $result;
  44214. } catch (Exception $e) {
  44215. $numTests = count($this);
  44216. for ($i = 0; $i < $numTests; $i++) {
  44217. $result->startTest($this);
  44218. $result->addError($this, $e, 0);
  44219. $result->endTest($this, 0);
  44220. }
  44221. $this->tearDown();
  44222. $result->endTestSuite($this);
  44223. return $result;
  44224. }
  44225. foreach ($this as $test) {
  44226. if ($result->shouldStop()) {
  44227. break;
  44228. }
  44229. if ($test instanceof PHPUnit_Framework_TestCase ||
  44230. $test instanceof PHPUnit_Framework_TestSuite) {
  44231. $test->setDisallowChangesToGlobalState($this->disallowChangesToGlobalState);
  44232. $test->setBackupGlobals($this->backupGlobals);
  44233. $test->setBackupStaticAttributes($this->backupStaticAttributes);
  44234. $test->setRunTestInSeparateProcess($this->runTestInSeparateProcess);
  44235. }
  44236. $test->run($result);
  44237. }
  44238. foreach ($hookMethods['afterClass'] as $afterClassMethod) {
  44239. if ($this->testCase === true && class_exists($this->name, false) && method_exists($this->name, $afterClassMethod)) {
  44240. call_user_func(array($this->name, $afterClassMethod));
  44241. }
  44242. }
  44243. $this->tearDown();
  44244. $result->endTestSuite($this);
  44245. return $result;
  44246. }
  44247. /**
  44248. * @param boolean $runTestInSeparateProcess
  44249. * @throws PHPUnit_Framework_Exception
  44250. * @since Method available since Release 3.7.0
  44251. */
  44252. public function setRunTestInSeparateProcess($runTestInSeparateProcess)
  44253. {
  44254. if (is_bool($runTestInSeparateProcess)) {
  44255. $this->runTestInSeparateProcess = $runTestInSeparateProcess;
  44256. } else {
  44257. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  44258. }
  44259. }
  44260. /**
  44261. * Runs a test.
  44262. *
  44263. * @deprecated
  44264. * @param PHPUnit_Framework_Test $test
  44265. * @param PHPUnit_Framework_TestResult $result
  44266. */
  44267. public function runTest(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result)
  44268. {
  44269. $test->run($result);
  44270. }
  44271. /**
  44272. * Sets the name of the suite.
  44273. *
  44274. * @param string
  44275. */
  44276. public function setName($name)
  44277. {
  44278. $this->name = $name;
  44279. }
  44280. /**
  44281. * Returns the test at the given index.
  44282. *
  44283. * @param integer
  44284. * @return PHPUnit_Framework_Test
  44285. */
  44286. public function testAt($index)
  44287. {
  44288. if (isset($this->tests[$index])) {
  44289. return $this->tests[$index];
  44290. } else {
  44291. return false;
  44292. }
  44293. }
  44294. /**
  44295. * Returns the tests as an enumeration.
  44296. *
  44297. * @return array
  44298. */
  44299. public function tests()
  44300. {
  44301. return $this->tests;
  44302. }
  44303. /**
  44304. * Set tests of the test suite
  44305. *
  44306. * @param array $tests
  44307. * @since Method available since Release 4.0.0
  44308. */
  44309. public function setTests(array $tests)
  44310. {
  44311. $this->tests = $tests;
  44312. }
  44313. /**
  44314. * Mark the test suite as skipped.
  44315. *
  44316. * @param string $message
  44317. * @throws PHPUnit_Framework_SkippedTestSuiteError
  44318. * @since Method available since Release 3.0.0
  44319. */
  44320. public function markTestSuiteSkipped($message = '')
  44321. {
  44322. throw new PHPUnit_Framework_SkippedTestSuiteError($message);
  44323. }
  44324. /**
  44325. * @param ReflectionClass $class
  44326. * @param ReflectionMethod $method
  44327. */
  44328. protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
  44329. {
  44330. if (!$this->isTestMethod($method)) {
  44331. return;
  44332. }
  44333. $name = $method->getName();
  44334. if (!$method->isPublic()) {
  44335. $this->addTest(
  44336. self::warning(
  44337. sprintf(
  44338. 'Test method "%s" in test class "%s" is not public.',
  44339. $name,
  44340. $class->getName()
  44341. )
  44342. )
  44343. );
  44344. return;
  44345. }
  44346. $test = self::createTest($class, $name);
  44347. if ($test instanceof PHPUnit_Framework_TestCase ||
  44348. $test instanceof PHPUnit_Framework_TestSuite_DataProvider) {
  44349. $test->setDependencies(
  44350. PHPUnit_Util_Test::getDependencies($class->getName(), $name)
  44351. );
  44352. }
  44353. $this->addTest(
  44354. $test,
  44355. PHPUnit_Util_Test::getGroups($class->getName(), $name)
  44356. );
  44357. }
  44358. /**
  44359. * @param ReflectionMethod $method
  44360. * @return boolean
  44361. */
  44362. public static function isTestMethod(ReflectionMethod $method)
  44363. {
  44364. if (strpos($method->name, 'test') === 0) {
  44365. return true;
  44366. }
  44367. // @scenario on TestCase::testMethod()
  44368. // @test on TestCase::testMethod()
  44369. $doc_comment = $method->getDocComment();
  44370. return strpos($doc_comment, '@test') !== false ||
  44371. strpos($doc_comment, '@scenario') !== false;
  44372. }
  44373. /**
  44374. * @param string $message
  44375. * @return PHPUnit_Framework_Warning
  44376. */
  44377. protected static function warning($message)
  44378. {
  44379. return new PHPUnit_Framework_Warning($message);
  44380. }
  44381. /**
  44382. * @param string $class
  44383. * @param string $methodName
  44384. * @param string $message
  44385. * @return PHPUnit_Framework_SkippedTestCase
  44386. * @since Method available since Release 4.3.0
  44387. */
  44388. protected static function skipTest($class, $methodName, $message)
  44389. {
  44390. return new PHPUnit_Framework_SkippedTestCase($class, $methodName, $message);
  44391. }
  44392. /**
  44393. * @param string $class
  44394. * @param string $methodName
  44395. * @param string $message
  44396. * @return PHPUnit_Framework_IncompleteTestCase
  44397. * @since Method available since Release 4.3.0
  44398. */
  44399. protected static function incompleteTest($class, $methodName, $message)
  44400. {
  44401. return new PHPUnit_Framework_IncompleteTestCase($class, $methodName, $message);
  44402. }
  44403. /**
  44404. * @param boolean $disallowChangesToGlobalState
  44405. * @since Method available since Release 4.6.0
  44406. */
  44407. public function setDisallowChangesToGlobalState($disallowChangesToGlobalState)
  44408. {
  44409. if (is_null($this->disallowChangesToGlobalState) && is_bool($disallowChangesToGlobalState)) {
  44410. $this->disallowChangesToGlobalState = $disallowChangesToGlobalState;
  44411. }
  44412. }
  44413. /**
  44414. * @param boolean $backupGlobals
  44415. * @since Method available since Release 3.3.0
  44416. */
  44417. public function setBackupGlobals($backupGlobals)
  44418. {
  44419. if (is_null($this->backupGlobals) && is_bool($backupGlobals)) {
  44420. $this->backupGlobals = $backupGlobals;
  44421. }
  44422. }
  44423. /**
  44424. * @param boolean $backupStaticAttributes
  44425. * @since Method available since Release 3.4.0
  44426. */
  44427. public function setBackupStaticAttributes($backupStaticAttributes)
  44428. {
  44429. if (is_null($this->backupStaticAttributes) &&
  44430. is_bool($backupStaticAttributes)) {
  44431. $this->backupStaticAttributes = $backupStaticAttributes;
  44432. }
  44433. }
  44434. /**
  44435. * Returns an iterator for this test suite.
  44436. *
  44437. * @return RecursiveIteratorIterator
  44438. * @since Method available since Release 3.1.0
  44439. */
  44440. public function getIterator()
  44441. {
  44442. $iterator = new PHPUnit_Util_TestSuiteIterator($this);
  44443. if ($this->iteratorFilter !== null) {
  44444. $iterator = $this->iteratorFilter->factory($iterator, $this);
  44445. }
  44446. return $iterator;
  44447. }
  44448. public function injectFilter(PHPUnit_Runner_Filter_Factory $filter)
  44449. {
  44450. $this->iteratorFilter = $filter;
  44451. foreach ($this as $test) {
  44452. if ($test instanceof PHPUnit_Framework_TestSuite) {
  44453. $test->injectFilter($filter);
  44454. }
  44455. }
  44456. }
  44457. /**
  44458. * Template Method that is called before the tests
  44459. * of this test suite are run.
  44460. *
  44461. * @since Method available since Release 3.1.0
  44462. */
  44463. protected function setUp()
  44464. {
  44465. }
  44466. /**
  44467. * Template Method that is called after the tests
  44468. * of this test suite have finished running.
  44469. *
  44470. * @since Method available since Release 3.1.0
  44471. */
  44472. protected function tearDown()
  44473. {
  44474. }
  44475. }
  44476. <?php
  44477. /*
  44478. * This file is part of PHPUnit.
  44479. *
  44480. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44481. *
  44482. * For the full copyright and license information, please view the LICENSE
  44483. * file that was distributed with this source code.
  44484. */
  44485. /**
  44486. * A marker interface for marking any exception/error as result of an unit
  44487. * test as risky.
  44488. *
  44489. * @package PHPUnit
  44490. * @subpackage Framework
  44491. * @author Sebastian Bergmann <sebastian@phpunit.de>
  44492. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  44493. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  44494. * @link http://www.phpunit.de/
  44495. * @since Interface available since Release 4.0.0
  44496. */
  44497. interface PHPUnit_Framework_RiskyTest
  44498. {
  44499. }
  44500. <?php
  44501. /*
  44502. * This file is part of PHPUnit.
  44503. *
  44504. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44505. *
  44506. * For the full copyright and license information, please view the LICENSE
  44507. * file that was distributed with this source code.
  44508. */
  44509. /**
  44510. * Interface for classes that can return a description of itself.
  44511. *
  44512. * @package PHPUnit
  44513. * @subpackage Framework
  44514. * @author Sebastian Bergmann <sebastian@phpunit.de>
  44515. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  44516. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  44517. * @link http://www.phpunit.de/
  44518. * @since Interface available since Release 3.0.0
  44519. */
  44520. interface PHPUnit_Framework_SelfDescribing
  44521. {
  44522. /**
  44523. * Returns a string representation of the object.
  44524. *
  44525. * @return string
  44526. */
  44527. public function toString();
  44528. }
  44529. <?php
  44530. /*
  44531. * This file is part of PHPUnit.
  44532. *
  44533. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44534. *
  44535. * For the full copyright and license information, please view the LICENSE
  44536. * file that was distributed with this source code.
  44537. */
  44538. /**
  44539. * Returns a matcher that matches when the method is executed
  44540. * zero or more times.
  44541. *
  44542. * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount
  44543. * @since Method available since Release 3.0.0
  44544. */
  44545. function any()
  44546. {
  44547. return call_user_func_array(
  44548. 'PHPUnit_Framework_TestCase::any',
  44549. func_get_args()
  44550. );
  44551. }
  44552. /**
  44553. * Returns a PHPUnit_Framework_Constraint_IsAnything matcher object.
  44554. *
  44555. * @return PHPUnit_Framework_Constraint_IsAnything
  44556. * @since Method available since Release 3.0.0
  44557. */
  44558. function anything()
  44559. {
  44560. return call_user_func_array(
  44561. 'PHPUnit_Framework_Assert::anything',
  44562. func_get_args()
  44563. );
  44564. }
  44565. /**
  44566. * Returns a PHPUnit_Framework_Constraint_ArrayHasKey matcher object.
  44567. *
  44568. * @param mixed $key
  44569. * @return PHPUnit_Framework_Constraint_ArrayHasKey
  44570. * @since Method available since Release 3.0.0
  44571. */
  44572. function arrayHasKey($key)
  44573. {
  44574. return call_user_func_array(
  44575. 'PHPUnit_Framework_Assert::arrayHasKey',
  44576. func_get_args()
  44577. );
  44578. }
  44579. /**
  44580. * Asserts that an array has a specified key.
  44581. *
  44582. * @param mixed $key
  44583. * @param array|ArrayAccess $array
  44584. * @param string $message
  44585. * @since Method available since Release 3.0.0
  44586. */
  44587. function assertArrayHasKey($key, $array, $message = '')
  44588. {
  44589. return call_user_func_array(
  44590. 'PHPUnit_Framework_Assert::assertArrayHasKey',
  44591. func_get_args()
  44592. );
  44593. }
  44594. /**
  44595. * Asserts that an array has a specified subset.
  44596. *
  44597. * @param array|ArrayAccess $subset
  44598. * @param array|ArrayAccess $array
  44599. * @param boolean $strict Check for object identity
  44600. * @param string $message
  44601. * @since Method available since Release 4.4.0
  44602. */
  44603. function assertArraySubset($subset, $array, $strict = false, $message = '')
  44604. {
  44605. return call_user_func_array(
  44606. 'PHPUnit_Framework_Assert::assertArraySubset',
  44607. func_get_args()
  44608. );
  44609. }
  44610. /**
  44611. * Asserts that an array does not have a specified key.
  44612. *
  44613. * @param mixed $key
  44614. * @param array|ArrayAccess $array
  44615. * @param string $message
  44616. * @since Method available since Release 3.0.0
  44617. */
  44618. function assertArrayNotHasKey($key, $array, $message = '')
  44619. {
  44620. return call_user_func_array(
  44621. 'PHPUnit_Framework_Assert::assertArrayNotHasKey',
  44622. func_get_args()
  44623. );
  44624. }
  44625. /**
  44626. * Asserts that a haystack that is stored in a static attribute of a class
  44627. * or an attribute of an object contains a needle.
  44628. *
  44629. * @param mixed $needle
  44630. * @param string $haystackAttributeName
  44631. * @param mixed $haystackClassOrObject
  44632. * @param string $message
  44633. * @param boolean $ignoreCase
  44634. * @param boolean $checkForObjectIdentity
  44635. * @param boolean $checkForNonObjectIdentity
  44636. * @since Method available since Release 3.0.0
  44637. */
  44638. function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  44639. {
  44640. return call_user_func_array(
  44641. 'PHPUnit_Framework_Assert::assertAttributeContains',
  44642. func_get_args()
  44643. );
  44644. }
  44645. /**
  44646. * Asserts that a haystack that is stored in a static attribute of a class
  44647. * or an attribute of an object contains only values of a given type.
  44648. *
  44649. * @param string $type
  44650. * @param string $haystackAttributeName
  44651. * @param mixed $haystackClassOrObject
  44652. * @param boolean $isNativeType
  44653. * @param string $message
  44654. * @since Method available since Release 3.1.4
  44655. */
  44656. function assertAttributeContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
  44657. {
  44658. return call_user_func_array(
  44659. 'PHPUnit_Framework_Assert::assertAttributeContainsOnly',
  44660. func_get_args()
  44661. );
  44662. }
  44663. /**
  44664. * Asserts the number of elements of an array, Countable or Traversable
  44665. * that is stored in an attribute.
  44666. *
  44667. * @param integer $expectedCount
  44668. * @param string $haystackAttributeName
  44669. * @param mixed $haystackClassOrObject
  44670. * @param string $message
  44671. * @since Method available since Release 3.6.0
  44672. */
  44673. function assertAttributeCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
  44674. {
  44675. return call_user_func_array(
  44676. 'PHPUnit_Framework_Assert::assertAttributeCount',
  44677. func_get_args()
  44678. );
  44679. }
  44680. /**
  44681. * Asserts that a static attribute of a class or an attribute of an object
  44682. * is empty.
  44683. *
  44684. * @param string $haystackAttributeName
  44685. * @param mixed $haystackClassOrObject
  44686. * @param string $message
  44687. * @since Method available since Release 3.5.0
  44688. */
  44689. function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
  44690. {
  44691. return call_user_func_array(
  44692. 'PHPUnit_Framework_Assert::assertAttributeEmpty',
  44693. func_get_args()
  44694. );
  44695. }
  44696. /**
  44697. * Asserts that a variable is equal to an attribute of an object.
  44698. *
  44699. * @param mixed $expected
  44700. * @param string $actualAttributeName
  44701. * @param string $actualClassOrObject
  44702. * @param string $message
  44703. * @param float $delta
  44704. * @param integer $maxDepth
  44705. * @param boolean $canonicalize
  44706. * @param boolean $ignoreCase
  44707. */
  44708. function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  44709. {
  44710. return call_user_func_array(
  44711. 'PHPUnit_Framework_Assert::assertAttributeEquals',
  44712. func_get_args()
  44713. );
  44714. }
  44715. /**
  44716. * Asserts that an attribute is greater than another value.
  44717. *
  44718. * @param mixed $expected
  44719. * @param string $actualAttributeName
  44720. * @param string $actualClassOrObject
  44721. * @param string $message
  44722. * @since Method available since Release 3.1.0
  44723. */
  44724. function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44725. {
  44726. return call_user_func_array(
  44727. 'PHPUnit_Framework_Assert::assertAttributeGreaterThan',
  44728. func_get_args()
  44729. );
  44730. }
  44731. /**
  44732. * Asserts that an attribute is greater than or equal to another value.
  44733. *
  44734. * @param mixed $expected
  44735. * @param string $actualAttributeName
  44736. * @param string $actualClassOrObject
  44737. * @param string $message
  44738. * @since Method available since Release 3.1.0
  44739. */
  44740. function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44741. {
  44742. return call_user_func_array(
  44743. 'PHPUnit_Framework_Assert::assertAttributeGreaterThanOrEqual',
  44744. func_get_args()
  44745. );
  44746. }
  44747. /**
  44748. * Asserts that an attribute is of a given type.
  44749. *
  44750. * @param string $expected
  44751. * @param string $attributeName
  44752. * @param mixed $classOrObject
  44753. * @param string $message
  44754. * @since Method available since Release 3.5.0
  44755. */
  44756. function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '')
  44757. {
  44758. return call_user_func_array(
  44759. 'PHPUnit_Framework_Assert::assertAttributeInstanceOf',
  44760. func_get_args()
  44761. );
  44762. }
  44763. /**
  44764. * Asserts that an attribute is of a given type.
  44765. *
  44766. * @param string $expected
  44767. * @param string $attributeName
  44768. * @param mixed $classOrObject
  44769. * @param string $message
  44770. * @since Method available since Release 3.5.0
  44771. */
  44772. function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '')
  44773. {
  44774. return call_user_func_array(
  44775. 'PHPUnit_Framework_Assert::assertAttributeInternalType',
  44776. func_get_args()
  44777. );
  44778. }
  44779. /**
  44780. * Asserts that an attribute is smaller than another value.
  44781. *
  44782. * @param mixed $expected
  44783. * @param string $actualAttributeName
  44784. * @param string $actualClassOrObject
  44785. * @param string $message
  44786. * @since Method available since Release 3.1.0
  44787. */
  44788. function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44789. {
  44790. return call_user_func_array(
  44791. 'PHPUnit_Framework_Assert::assertAttributeLessThan',
  44792. func_get_args()
  44793. );
  44794. }
  44795. /**
  44796. * Asserts that an attribute is smaller than or equal to another value.
  44797. *
  44798. * @param mixed $expected
  44799. * @param string $actualAttributeName
  44800. * @param string $actualClassOrObject
  44801. * @param string $message
  44802. * @since Method available since Release 3.1.0
  44803. */
  44804. function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44805. {
  44806. return call_user_func_array(
  44807. 'PHPUnit_Framework_Assert::assertAttributeLessThanOrEqual',
  44808. func_get_args()
  44809. );
  44810. }
  44811. /**
  44812. * Asserts that a haystack that is stored in a static attribute of a class
  44813. * or an attribute of an object does not contain a needle.
  44814. *
  44815. * @param mixed $needle
  44816. * @param string $haystackAttributeName
  44817. * @param mixed $haystackClassOrObject
  44818. * @param string $message
  44819. * @param boolean $ignoreCase
  44820. * @param boolean $checkForObjectIdentity
  44821. * @param boolean $checkForNonObjectIdentity
  44822. * @since Method available since Release 3.0.0
  44823. */
  44824. function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  44825. {
  44826. return call_user_func_array(
  44827. 'PHPUnit_Framework_Assert::assertAttributeNotContains',
  44828. func_get_args()
  44829. );
  44830. }
  44831. /**
  44832. * Asserts that a haystack that is stored in a static attribute of a class
  44833. * or an attribute of an object does not contain only values of a given
  44834. * type.
  44835. *
  44836. * @param string $type
  44837. * @param string $haystackAttributeName
  44838. * @param mixed $haystackClassOrObject
  44839. * @param boolean $isNativeType
  44840. * @param string $message
  44841. * @since Method available since Release 3.1.4
  44842. */
  44843. function assertAttributeNotContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
  44844. {
  44845. return call_user_func_array(
  44846. 'PHPUnit_Framework_Assert::assertAttributeNotContainsOnly',
  44847. func_get_args()
  44848. );
  44849. }
  44850. /**
  44851. * Asserts the number of elements of an array, Countable or Traversable
  44852. * that is stored in an attribute.
  44853. *
  44854. * @param integer $expectedCount
  44855. * @param string $haystackAttributeName
  44856. * @param mixed $haystackClassOrObject
  44857. * @param string $message
  44858. * @since Method available since Release 3.6.0
  44859. */
  44860. function assertAttributeNotCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
  44861. {
  44862. return call_user_func_array(
  44863. 'PHPUnit_Framework_Assert::assertAttributeNotCount',
  44864. func_get_args()
  44865. );
  44866. }
  44867. /**
  44868. * Asserts that a static attribute of a class or an attribute of an object
  44869. * is not empty.
  44870. *
  44871. * @param string $haystackAttributeName
  44872. * @param mixed $haystackClassOrObject
  44873. * @param string $message
  44874. * @since Method available since Release 3.5.0
  44875. */
  44876. function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
  44877. {
  44878. return call_user_func_array(
  44879. 'PHPUnit_Framework_Assert::assertAttributeNotEmpty',
  44880. func_get_args()
  44881. );
  44882. }
  44883. /**
  44884. * Asserts that a variable is not equal to an attribute of an object.
  44885. *
  44886. * @param mixed $expected
  44887. * @param string $actualAttributeName
  44888. * @param string $actualClassOrObject
  44889. * @param string $message
  44890. * @param float $delta
  44891. * @param integer $maxDepth
  44892. * @param boolean $canonicalize
  44893. * @param boolean $ignoreCase
  44894. */
  44895. function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  44896. {
  44897. return call_user_func_array(
  44898. 'PHPUnit_Framework_Assert::assertAttributeNotEquals',
  44899. func_get_args()
  44900. );
  44901. }
  44902. /**
  44903. * Asserts that an attribute is of a given type.
  44904. *
  44905. * @param string $expected
  44906. * @param string $attributeName
  44907. * @param mixed $classOrObject
  44908. * @param string $message
  44909. * @since Method available since Release 3.5.0
  44910. */
  44911. function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '')
  44912. {
  44913. return call_user_func_array(
  44914. 'PHPUnit_Framework_Assert::assertAttributeNotInstanceOf',
  44915. func_get_args()
  44916. );
  44917. }
  44918. /**
  44919. * Asserts that an attribute is of a given type.
  44920. *
  44921. * @param string $expected
  44922. * @param string $attributeName
  44923. * @param mixed $classOrObject
  44924. * @param string $message
  44925. * @since Method available since Release 3.5.0
  44926. */
  44927. function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '')
  44928. {
  44929. return call_user_func_array(
  44930. 'PHPUnit_Framework_Assert::assertAttributeNotInternalType',
  44931. func_get_args()
  44932. );
  44933. }
  44934. /**
  44935. * Asserts that a variable and an attribute of an object do not have the
  44936. * same type and value.
  44937. *
  44938. * @param mixed $expected
  44939. * @param string $actualAttributeName
  44940. * @param object $actualClassOrObject
  44941. * @param string $message
  44942. */
  44943. function assertAttributeNotSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44944. {
  44945. return call_user_func_array(
  44946. 'PHPUnit_Framework_Assert::assertAttributeNotSame',
  44947. func_get_args()
  44948. );
  44949. }
  44950. /**
  44951. * Asserts that a variable and an attribute of an object have the same type
  44952. * and value.
  44953. *
  44954. * @param mixed $expected
  44955. * @param string $actualAttributeName
  44956. * @param object $actualClassOrObject
  44957. * @param string $message
  44958. */
  44959. function assertAttributeSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44960. {
  44961. return call_user_func_array(
  44962. 'PHPUnit_Framework_Assert::assertAttributeSame',
  44963. func_get_args()
  44964. );
  44965. }
  44966. /**
  44967. * Asserts that a class has a specified attribute.
  44968. *
  44969. * @param string $attributeName
  44970. * @param string $className
  44971. * @param string $message
  44972. * @since Method available since Release 3.1.0
  44973. */
  44974. function assertClassHasAttribute($attributeName, $className, $message = '')
  44975. {
  44976. return call_user_func_array(
  44977. 'PHPUnit_Framework_Assert::assertClassHasAttribute',
  44978. func_get_args()
  44979. );
  44980. }
  44981. /**
  44982. * Asserts that a class has a specified static attribute.
  44983. *
  44984. * @param string $attributeName
  44985. * @param string $className
  44986. * @param string $message
  44987. * @since Method available since Release 3.1.0
  44988. */
  44989. function assertClassHasStaticAttribute($attributeName, $className, $message = '')
  44990. {
  44991. return call_user_func_array(
  44992. 'PHPUnit_Framework_Assert::assertClassHasStaticAttribute',
  44993. func_get_args()
  44994. );
  44995. }
  44996. /**
  44997. * Asserts that a class does not have a specified attribute.
  44998. *
  44999. * @param string $attributeName
  45000. * @param string $className
  45001. * @param string $message
  45002. * @since Method available since Release 3.1.0
  45003. */
  45004. function assertClassNotHasAttribute($attributeName, $className, $message = '')
  45005. {
  45006. return call_user_func_array(
  45007. 'PHPUnit_Framework_Assert::assertClassNotHasAttribute',
  45008. func_get_args()
  45009. );
  45010. }
  45011. /**
  45012. * Asserts that a class does not have a specified static attribute.
  45013. *
  45014. * @param string $attributeName
  45015. * @param string $className
  45016. * @param string $message
  45017. * @since Method available since Release 3.1.0
  45018. */
  45019. function assertClassNotHasStaticAttribute($attributeName, $className, $message = '')
  45020. {
  45021. return call_user_func_array(
  45022. 'PHPUnit_Framework_Assert::assertClassNotHasStaticAttribute',
  45023. func_get_args()
  45024. );
  45025. }
  45026. /**
  45027. * Asserts that a haystack contains a needle.
  45028. *
  45029. * @param mixed $needle
  45030. * @param mixed $haystack
  45031. * @param string $message
  45032. * @param boolean $ignoreCase
  45033. * @param boolean $checkForObjectIdentity
  45034. * @param boolean $checkForNonObjectIdentity
  45035. * @since Method available since Release 2.1.0
  45036. */
  45037. function assertContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  45038. {
  45039. return call_user_func_array(
  45040. 'PHPUnit_Framework_Assert::assertContains',
  45041. func_get_args()
  45042. );
  45043. }
  45044. /**
  45045. * Asserts that a haystack contains only values of a given type.
  45046. *
  45047. * @param string $type
  45048. * @param mixed $haystack
  45049. * @param boolean $isNativeType
  45050. * @param string $message
  45051. * @since Method available since Release 3.1.4
  45052. */
  45053. function assertContainsOnly($type, $haystack, $isNativeType = null, $message = '')
  45054. {
  45055. return call_user_func_array(
  45056. 'PHPUnit_Framework_Assert::assertContainsOnly',
  45057. func_get_args()
  45058. );
  45059. }
  45060. /**
  45061. * Asserts that a haystack contains only instances of a given classname
  45062. *
  45063. * @param string $classname
  45064. * @param array|Traversable $haystack
  45065. * @param string $message
  45066. */
  45067. function assertContainsOnlyInstancesOf($classname, $haystack, $message = '')
  45068. {
  45069. return call_user_func_array(
  45070. 'PHPUnit_Framework_Assert::assertContainsOnlyInstancesOf',
  45071. func_get_args()
  45072. );
  45073. }
  45074. /**
  45075. * Asserts the number of elements of an array, Countable or Traversable.
  45076. *
  45077. * @param integer $expectedCount
  45078. * @param mixed $haystack
  45079. * @param string $message
  45080. */
  45081. function assertCount($expectedCount, $haystack, $message = '')
  45082. {
  45083. return call_user_func_array(
  45084. 'PHPUnit_Framework_Assert::assertCount',
  45085. func_get_args()
  45086. );
  45087. }
  45088. /**
  45089. * Asserts that a variable is empty.
  45090. *
  45091. * @param mixed $actual
  45092. * @param string $message
  45093. * @throws PHPUnit_Framework_AssertionFailedError
  45094. */
  45095. function assertEmpty($actual, $message = '')
  45096. {
  45097. return call_user_func_array(
  45098. 'PHPUnit_Framework_Assert::assertEmpty',
  45099. func_get_args()
  45100. );
  45101. }
  45102. /**
  45103. * Asserts that a hierarchy of DOMElements matches.
  45104. *
  45105. * @param DOMElement $expectedElement
  45106. * @param DOMElement $actualElement
  45107. * @param boolean $checkAttributes
  45108. * @param string $message
  45109. * @author Mattis Stordalen Flister <mattis@xait.no>
  45110. * @since Method available since Release 3.3.0
  45111. */
  45112. function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = false, $message = '')
  45113. {
  45114. return call_user_func_array(
  45115. 'PHPUnit_Framework_Assert::assertEqualXMLStructure',
  45116. func_get_args()
  45117. );
  45118. }
  45119. /**
  45120. * Asserts that two variables are equal.
  45121. *
  45122. * @param mixed $expected
  45123. * @param mixed $actual
  45124. * @param string $message
  45125. * @param float $delta
  45126. * @param integer $maxDepth
  45127. * @param boolean $canonicalize
  45128. * @param boolean $ignoreCase
  45129. */
  45130. function assertEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  45131. {
  45132. return call_user_func_array(
  45133. 'PHPUnit_Framework_Assert::assertEquals',
  45134. func_get_args()
  45135. );
  45136. }
  45137. /**
  45138. * Asserts that a condition is not true.
  45139. *
  45140. * @param boolean $condition
  45141. * @param string $message
  45142. * @throws PHPUnit_Framework_AssertionFailedError
  45143. */
  45144. function assertNotTrue($condition, $message = '')
  45145. {
  45146. return call_user_func_array(
  45147. 'PHPUnit_Framework_Assert::assertNotTrue',
  45148. func_get_args()
  45149. );
  45150. }
  45151. /**
  45152. * Asserts that a condition is false.
  45153. *
  45154. * @param boolean $condition
  45155. * @param string $message
  45156. * @throws PHPUnit_Framework_AssertionFailedError
  45157. */
  45158. function assertFalse($condition, $message = '')
  45159. {
  45160. return call_user_func_array(
  45161. 'PHPUnit_Framework_Assert::assertFalse',
  45162. func_get_args()
  45163. );
  45164. }
  45165. /**
  45166. * Asserts that the contents of one file is equal to the contents of another
  45167. * file.
  45168. *
  45169. * @param string $expected
  45170. * @param string $actual
  45171. * @param string $message
  45172. * @param boolean $canonicalize
  45173. * @param boolean $ignoreCase
  45174. * @since Method available since Release 3.2.14
  45175. */
  45176. function assertFileEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
  45177. {
  45178. return call_user_func_array(
  45179. 'PHPUnit_Framework_Assert::assertFileEquals',
  45180. func_get_args()
  45181. );
  45182. }
  45183. /**
  45184. * Asserts that a file exists.
  45185. *
  45186. * @param string $filename
  45187. * @param string $message
  45188. * @since Method available since Release 3.0.0
  45189. */
  45190. function assertFileExists($filename, $message = '')
  45191. {
  45192. return call_user_func_array(
  45193. 'PHPUnit_Framework_Assert::assertFileExists',
  45194. func_get_args()
  45195. );
  45196. }
  45197. /**
  45198. * Asserts that the contents of one file is not equal to the contents of
  45199. * another file.
  45200. *
  45201. * @param string $expected
  45202. * @param string $actual
  45203. * @param string $message
  45204. * @param boolean $canonicalize
  45205. * @param boolean $ignoreCase
  45206. * @since Method available since Release 3.2.14
  45207. */
  45208. function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
  45209. {
  45210. return call_user_func_array(
  45211. 'PHPUnit_Framework_Assert::assertFileNotEquals',
  45212. func_get_args()
  45213. );
  45214. }
  45215. /**
  45216. * Asserts that a file does not exist.
  45217. *
  45218. * @param string $filename
  45219. * @param string $message
  45220. * @since Method available since Release 3.0.0
  45221. */
  45222. function assertFileNotExists($filename, $message = '')
  45223. {
  45224. return call_user_func_array(
  45225. 'PHPUnit_Framework_Assert::assertFileNotExists',
  45226. func_get_args()
  45227. );
  45228. }
  45229. /**
  45230. * Asserts that a value is greater than another value.
  45231. *
  45232. * @param mixed $expected
  45233. * @param mixed $actual
  45234. * @param string $message
  45235. * @since Method available since Release 3.1.0
  45236. */
  45237. function assertGreaterThan($expected, $actual, $message = '')
  45238. {
  45239. return call_user_func_array(
  45240. 'PHPUnit_Framework_Assert::assertGreaterThan',
  45241. func_get_args()
  45242. );
  45243. }
  45244. /**
  45245. * Asserts that a value is greater than or equal to another value.
  45246. *
  45247. * @param mixed $expected
  45248. * @param mixed $actual
  45249. * @param string $message
  45250. * @since Method available since Release 3.1.0
  45251. */
  45252. function assertGreaterThanOrEqual($expected, $actual, $message = '')
  45253. {
  45254. return call_user_func_array(
  45255. 'PHPUnit_Framework_Assert::assertGreaterThanOrEqual',
  45256. func_get_args()
  45257. );
  45258. }
  45259. /**
  45260. * Asserts that a variable is of a given type.
  45261. *
  45262. * @param string $expected
  45263. * @param mixed $actual
  45264. * @param string $message
  45265. * @since Method available since Release 3.5.0
  45266. */
  45267. function assertInstanceOf($expected, $actual, $message = '')
  45268. {
  45269. return call_user_func_array(
  45270. 'PHPUnit_Framework_Assert::assertInstanceOf',
  45271. func_get_args()
  45272. );
  45273. }
  45274. /**
  45275. * Asserts that a variable is of a given type.
  45276. *
  45277. * @param string $expected
  45278. * @param mixed $actual
  45279. * @param string $message
  45280. * @since Method available since Release 3.5.0
  45281. */
  45282. function assertInternalType($expected, $actual, $message = '')
  45283. {
  45284. return call_user_func_array(
  45285. 'PHPUnit_Framework_Assert::assertInternalType',
  45286. func_get_args()
  45287. );
  45288. }
  45289. /**
  45290. * Asserts that a string is a valid JSON string.
  45291. *
  45292. * @param string $filename
  45293. * @param string $message
  45294. * @since Method available since Release 3.7.20
  45295. */
  45296. function assertJson($expectedJson, $message = '')
  45297. {
  45298. return call_user_func_array(
  45299. 'PHPUnit_Framework_Assert::assertJson',
  45300. func_get_args()
  45301. );
  45302. }
  45303. /**
  45304. * Asserts that two JSON files are equal.
  45305. *
  45306. * @param string $expectedFile
  45307. * @param string $actualFile
  45308. * @param string $message
  45309. */
  45310. function assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message = '')
  45311. {
  45312. return call_user_func_array(
  45313. 'PHPUnit_Framework_Assert::assertJsonFileEqualsJsonFile',
  45314. func_get_args()
  45315. );
  45316. }
  45317. /**
  45318. * Asserts that two JSON files are not equal.
  45319. *
  45320. * @param string $expectedFile
  45321. * @param string $actualFile
  45322. * @param string $message
  45323. */
  45324. function assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message = '')
  45325. {
  45326. return call_user_func_array(
  45327. 'PHPUnit_Framework_Assert::assertJsonFileNotEqualsJsonFile',
  45328. func_get_args()
  45329. );
  45330. }
  45331. /**
  45332. * Asserts that the generated JSON encoded object and the content of the given file are equal.
  45333. *
  45334. * @param string $expectedFile
  45335. * @param string $actualJson
  45336. * @param string $message
  45337. */
  45338. function assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message = '')
  45339. {
  45340. return call_user_func_array(
  45341. 'PHPUnit_Framework_Assert::assertJsonStringEqualsJsonFile',
  45342. func_get_args()
  45343. );
  45344. }
  45345. /**
  45346. * Asserts that two given JSON encoded objects or arrays are equal.
  45347. *
  45348. * @param string $expectedJson
  45349. * @param string $actualJson
  45350. * @param string $message
  45351. */
  45352. function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = '')
  45353. {
  45354. return call_user_func_array(
  45355. 'PHPUnit_Framework_Assert::assertJsonStringEqualsJsonString',
  45356. func_get_args()
  45357. );
  45358. }
  45359. /**
  45360. * Asserts that the generated JSON encoded object and the content of the given file are not equal.
  45361. *
  45362. * @param string $expectedFile
  45363. * @param string $actualJson
  45364. * @param string $message
  45365. */
  45366. function assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message = '')
  45367. {
  45368. return call_user_func_array(
  45369. 'PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonFile',
  45370. func_get_args()
  45371. );
  45372. }
  45373. /**
  45374. * Asserts that two given JSON encoded objects or arrays are not equal.
  45375. *
  45376. * @param string $expectedJson
  45377. * @param string $actualJson
  45378. * @param string $message
  45379. */
  45380. function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message = '')
  45381. {
  45382. return call_user_func_array(
  45383. 'PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonString',
  45384. func_get_args()
  45385. );
  45386. }
  45387. /**
  45388. * Asserts that a value is smaller than another value.
  45389. *
  45390. * @param mixed $expected
  45391. * @param mixed $actual
  45392. * @param string $message
  45393. * @since Method available since Release 3.1.0
  45394. */
  45395. function assertLessThan($expected, $actual, $message = '')
  45396. {
  45397. return call_user_func_array(
  45398. 'PHPUnit_Framework_Assert::assertLessThan',
  45399. func_get_args()
  45400. );
  45401. }
  45402. /**
  45403. * Asserts that a value is smaller than or equal to another value.
  45404. *
  45405. * @param mixed $expected
  45406. * @param mixed $actual
  45407. * @param string $message
  45408. * @since Method available since Release 3.1.0
  45409. */
  45410. function assertLessThanOrEqual($expected, $actual, $message = '')
  45411. {
  45412. return call_user_func_array(
  45413. 'PHPUnit_Framework_Assert::assertLessThanOrEqual',
  45414. func_get_args()
  45415. );
  45416. }
  45417. /**
  45418. * Asserts that a haystack does not contain a needle.
  45419. *
  45420. * @param mixed $needle
  45421. * @param mixed $haystack
  45422. * @param string $message
  45423. * @param boolean $ignoreCase
  45424. * @param boolean $checkForObjectIdentity
  45425. * @param boolean $checkForNonObjectIdentity
  45426. * @since Method available since Release 2.1.0
  45427. */
  45428. function assertNotContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  45429. {
  45430. return call_user_func_array(
  45431. 'PHPUnit_Framework_Assert::assertNotContains',
  45432. func_get_args()
  45433. );
  45434. }
  45435. /**
  45436. * Asserts that a haystack does not contain only values of a given type.
  45437. *
  45438. * @param string $type
  45439. * @param mixed $haystack
  45440. * @param boolean $isNativeType
  45441. * @param string $message
  45442. * @since Method available since Release 3.1.4
  45443. */
  45444. function assertNotContainsOnly($type, $haystack, $isNativeType = null, $message = '')
  45445. {
  45446. return call_user_func_array(
  45447. 'PHPUnit_Framework_Assert::assertNotContainsOnly',
  45448. func_get_args()
  45449. );
  45450. }
  45451. /**
  45452. * Asserts the number of elements of an array, Countable or Traversable.
  45453. *
  45454. * @param integer $expectedCount
  45455. * @param mixed $haystack
  45456. * @param string $message
  45457. */
  45458. function assertNotCount($expectedCount, $haystack, $message = '')
  45459. {
  45460. return call_user_func_array(
  45461. 'PHPUnit_Framework_Assert::assertNotCount',
  45462. func_get_args()
  45463. );
  45464. }
  45465. /**
  45466. * Asserts that a variable is not empty.
  45467. *
  45468. * @param mixed $actual
  45469. * @param string $message
  45470. * @throws PHPUnit_Framework_AssertionFailedError
  45471. */
  45472. function assertNotEmpty($actual, $message = '')
  45473. {
  45474. return call_user_func_array(
  45475. 'PHPUnit_Framework_Assert::assertNotEmpty',
  45476. func_get_args()
  45477. );
  45478. }
  45479. /**
  45480. * Asserts that two variables are not equal.
  45481. *
  45482. * @param mixed $expected
  45483. * @param mixed $actual
  45484. * @param string $message
  45485. * @param float $delta
  45486. * @param integer $maxDepth
  45487. * @param boolean $canonicalize
  45488. * @param boolean $ignoreCase
  45489. * @since Method available since Release 2.3.0
  45490. */
  45491. function assertNotEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  45492. {
  45493. return call_user_func_array(
  45494. 'PHPUnit_Framework_Assert::assertNotEquals',
  45495. func_get_args()
  45496. );
  45497. }
  45498. /**
  45499. * Asserts that a variable is not of a given type.
  45500. *
  45501. * @param string $expected
  45502. * @param mixed $actual
  45503. * @param string $message
  45504. * @since Method available since Release 3.5.0
  45505. */
  45506. function assertNotInstanceOf($expected, $actual, $message = '')
  45507. {
  45508. return call_user_func_array(
  45509. 'PHPUnit_Framework_Assert::assertNotInstanceOf',
  45510. func_get_args()
  45511. );
  45512. }
  45513. /**
  45514. * Asserts that a variable is not of a given type.
  45515. *
  45516. * @param string $expected
  45517. * @param mixed $actual
  45518. * @param string $message
  45519. * @since Method available since Release 3.5.0
  45520. */
  45521. function assertNotInternalType($expected, $actual, $message = '')
  45522. {
  45523. return call_user_func_array(
  45524. 'PHPUnit_Framework_Assert::assertNotInternalType',
  45525. func_get_args()
  45526. );
  45527. }
  45528. /**
  45529. * Asserts that a condition is not false.
  45530. *
  45531. * @param boolean $condition
  45532. * @param string $message
  45533. * @throws PHPUnit_Framework_AssertionFailedError
  45534. */
  45535. function assertNotFalse($condition, $message = '')
  45536. {
  45537. return call_user_func_array(
  45538. 'PHPUnit_Framework_Assert::assertNotFalse',
  45539. func_get_args()
  45540. );
  45541. }
  45542. /**
  45543. * Asserts that a variable is not null.
  45544. *
  45545. * @param mixed $actual
  45546. * @param string $message
  45547. */
  45548. function assertNotNull($actual, $message = '')
  45549. {
  45550. return call_user_func_array(
  45551. 'PHPUnit_Framework_Assert::assertNotNull',
  45552. func_get_args()
  45553. );
  45554. }
  45555. /**
  45556. * Asserts that a string does not match a given regular expression.
  45557. *
  45558. * @param string $pattern
  45559. * @param string $string
  45560. * @param string $message
  45561. * @since Method available since Release 2.1.0
  45562. */
  45563. function assertNotRegExp($pattern, $string, $message = '')
  45564. {
  45565. return call_user_func_array(
  45566. 'PHPUnit_Framework_Assert::assertNotRegExp',
  45567. func_get_args()
  45568. );
  45569. }
  45570. /**
  45571. * Asserts that two variables do not have the same type and value.
  45572. * Used on objects, it asserts that two variables do not reference
  45573. * the same object.
  45574. *
  45575. * @param mixed $expected
  45576. * @param mixed $actual
  45577. * @param string $message
  45578. */
  45579. function assertNotSame($expected, $actual, $message = '')
  45580. {
  45581. return call_user_func_array(
  45582. 'PHPUnit_Framework_Assert::assertNotSame',
  45583. func_get_args()
  45584. );
  45585. }
  45586. /**
  45587. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  45588. * is not the same.
  45589. *
  45590. * @param array|Countable|Traversable $expected
  45591. * @param array|Countable|Traversable $actual
  45592. * @param string $message
  45593. */
  45594. function assertNotSameSize($expected, $actual, $message = '')
  45595. {
  45596. return call_user_func_array(
  45597. 'PHPUnit_Framework_Assert::assertNotSameSize',
  45598. func_get_args()
  45599. );
  45600. }
  45601. /**
  45602. * This assertion is the exact opposite of assertTag().
  45603. *
  45604. * Rather than asserting that $matcher results in a match, it asserts that
  45605. * $matcher does not match.
  45606. *
  45607. * @param array $matcher
  45608. * @param string $actual
  45609. * @param string $message
  45610. * @param boolean $isHtml
  45611. * @since Method available since Release 3.3.0
  45612. * @author Mike Naberezny <mike@maintainable.com>
  45613. * @author Derek DeVries <derek@maintainable.com>
  45614. */
  45615. function assertNotTag($matcher, $actual, $message = '', $isHtml = true)
  45616. {
  45617. return call_user_func_array(
  45618. 'PHPUnit_Framework_Assert::assertNotTag',
  45619. func_get_args()
  45620. );
  45621. }
  45622. /**
  45623. * Asserts that a variable is null.
  45624. *
  45625. * @param mixed $actual
  45626. * @param string $message
  45627. */
  45628. function assertNull($actual, $message = '')
  45629. {
  45630. return call_user_func_array(
  45631. 'PHPUnit_Framework_Assert::assertNull',
  45632. func_get_args()
  45633. );
  45634. }
  45635. /**
  45636. * Asserts that an object has a specified attribute.
  45637. *
  45638. * @param string $attributeName
  45639. * @param object $object
  45640. * @param string $message
  45641. * @since Method available since Release 3.0.0
  45642. */
  45643. function assertObjectHasAttribute($attributeName, $object, $message = '')
  45644. {
  45645. return call_user_func_array(
  45646. 'PHPUnit_Framework_Assert::assertObjectHasAttribute',
  45647. func_get_args()
  45648. );
  45649. }
  45650. /**
  45651. * Asserts that an object does not have a specified attribute.
  45652. *
  45653. * @param string $attributeName
  45654. * @param object $object
  45655. * @param string $message
  45656. * @since Method available since Release 3.0.0
  45657. */
  45658. function assertObjectNotHasAttribute($attributeName, $object, $message = '')
  45659. {
  45660. return call_user_func_array(
  45661. 'PHPUnit_Framework_Assert::assertObjectNotHasAttribute',
  45662. func_get_args()
  45663. );
  45664. }
  45665. /**
  45666. * Asserts that a string matches a given regular expression.
  45667. *
  45668. * @param string $pattern
  45669. * @param string $string
  45670. * @param string $message
  45671. */
  45672. function assertRegExp($pattern, $string, $message = '')
  45673. {
  45674. return call_user_func_array(
  45675. 'PHPUnit_Framework_Assert::assertRegExp',
  45676. func_get_args()
  45677. );
  45678. }
  45679. /**
  45680. * Asserts that two variables have the same type and value.
  45681. * Used on objects, it asserts that two variables reference
  45682. * the same object.
  45683. *
  45684. * @param mixed $expected
  45685. * @param mixed $actual
  45686. * @param string $message
  45687. */
  45688. function assertSame($expected, $actual, $message = '')
  45689. {
  45690. return call_user_func_array(
  45691. 'PHPUnit_Framework_Assert::assertSame',
  45692. func_get_args()
  45693. );
  45694. }
  45695. /**
  45696. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  45697. * is the same.
  45698. *
  45699. * @param array|Countable|Traversable $expected
  45700. * @param array|Countable|Traversable $actual
  45701. * @param string $message
  45702. */
  45703. function assertSameSize($expected, $actual, $message = '')
  45704. {
  45705. return call_user_func_array(
  45706. 'PHPUnit_Framework_Assert::assertSameSize',
  45707. func_get_args()
  45708. );
  45709. }
  45710. /**
  45711. * Assert the presence, absence, or count of elements in a document matching
  45712. * the CSS $selector, regardless of the contents of those elements.
  45713. *
  45714. * The first argument, $selector, is the CSS selector used to match
  45715. * the elements in the $actual document.
  45716. *
  45717. * The second argument, $count, can be either boolean or numeric.
  45718. * When boolean, it asserts for presence of elements matching the selector
  45719. * (true) or absence of elements (false).
  45720. * When numeric, it asserts the count of elements.
  45721. *
  45722. * assertSelectCount("#binder", true, $xml); // any?
  45723. * assertSelectCount(".binder", 3, $xml); // exactly 3?
  45724. *
  45725. * @param array $selector
  45726. * @param integer $count
  45727. * @param mixed $actual
  45728. * @param string $message
  45729. * @param boolean $isHtml
  45730. * @since Method available since Release 3.3.0
  45731. * @author Mike Naberezny <mike@maintainable.com>
  45732. * @author Derek DeVries <derek@maintainable.com>
  45733. */
  45734. function assertSelectCount($selector, $count, $actual, $message = '', $isHtml = true)
  45735. {
  45736. return call_user_func_array(
  45737. 'PHPUnit_Framework_Assert::assertSelectCount',
  45738. func_get_args()
  45739. );
  45740. }
  45741. /**
  45742. * assertSelectEquals("#binder .name", "Chuck", true, $xml); // any?
  45743. * assertSelectEquals("#binder .name", "Chuck", false, $xml); // none?
  45744. *
  45745. * @param array $selector
  45746. * @param string $content
  45747. * @param integer $count
  45748. * @param mixed $actual
  45749. * @param string $message
  45750. * @param boolean $isHtml
  45751. * @since Method available since Release 3.3.0
  45752. * @author Mike Naberezny <mike@maintainable.com>
  45753. * @author Derek DeVries <derek@maintainable.com>
  45754. */
  45755. function assertSelectEquals($selector, $content, $count, $actual, $message = '', $isHtml = true)
  45756. {
  45757. return call_user_func_array(
  45758. 'PHPUnit_Framework_Assert::assertSelectEquals',
  45759. func_get_args()
  45760. );
  45761. }
  45762. /**
  45763. * assertSelectRegExp("#binder .name", "/Mike|Derek/", true, $xml); // any?
  45764. * assertSelectRegExp("#binder .name", "/Mike|Derek/", 3, $xml);// 3?
  45765. *
  45766. * @param array $selector
  45767. * @param string $pattern
  45768. * @param integer $count
  45769. * @param mixed $actual
  45770. * @param string $message
  45771. * @param boolean $isHtml
  45772. * @since Method available since Release 3.3.0
  45773. * @author Mike Naberezny <mike@maintainable.com>
  45774. * @author Derek DeVries <derek@maintainable.com>
  45775. */
  45776. function assertSelectRegExp($selector, $pattern, $count, $actual, $message = '', $isHtml = true)
  45777. {
  45778. return call_user_func_array(
  45779. 'PHPUnit_Framework_Assert::assertSelectRegExp',
  45780. func_get_args()
  45781. );
  45782. }
  45783. /**
  45784. * Asserts that a string ends not with a given prefix.
  45785. *
  45786. * @param string $suffix
  45787. * @param string $string
  45788. * @param string $message
  45789. * @since Method available since Release 3.4.0
  45790. */
  45791. function assertStringEndsNotWith($suffix, $string, $message = '')
  45792. {
  45793. return call_user_func_array(
  45794. 'PHPUnit_Framework_Assert::assertStringEndsNotWith',
  45795. func_get_args()
  45796. );
  45797. }
  45798. /**
  45799. * Asserts that a string ends with a given prefix.
  45800. *
  45801. * @param string $suffix
  45802. * @param string $string
  45803. * @param string $message
  45804. * @since Method available since Release 3.4.0
  45805. */
  45806. function assertStringEndsWith($suffix, $string, $message = '')
  45807. {
  45808. return call_user_func_array(
  45809. 'PHPUnit_Framework_Assert::assertStringEndsWith',
  45810. func_get_args()
  45811. );
  45812. }
  45813. /**
  45814. * Asserts that the contents of a string is equal
  45815. * to the contents of a file.
  45816. *
  45817. * @param string $expectedFile
  45818. * @param string $actualString
  45819. * @param string $message
  45820. * @param boolean $canonicalize
  45821. * @param boolean $ignoreCase
  45822. * @since Method available since Release 3.3.0
  45823. */
  45824. function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
  45825. {
  45826. return call_user_func_array(
  45827. 'PHPUnit_Framework_Assert::assertStringEqualsFile',
  45828. func_get_args()
  45829. );
  45830. }
  45831. /**
  45832. * Asserts that a string matches a given format string.
  45833. *
  45834. * @param string $format
  45835. * @param string $string
  45836. * @param string $message
  45837. * @since Method available since Release 3.5.0
  45838. */
  45839. function assertStringMatchesFormat($format, $string, $message = '')
  45840. {
  45841. return call_user_func_array(
  45842. 'PHPUnit_Framework_Assert::assertStringMatchesFormat',
  45843. func_get_args()
  45844. );
  45845. }
  45846. /**
  45847. * Asserts that a string matches a given format file.
  45848. *
  45849. * @param string $formatFile
  45850. * @param string $string
  45851. * @param string $message
  45852. * @since Method available since Release 3.5.0
  45853. */
  45854. function assertStringMatchesFormatFile($formatFile, $string, $message = '')
  45855. {
  45856. return call_user_func_array(
  45857. 'PHPUnit_Framework_Assert::assertStringMatchesFormatFile',
  45858. func_get_args()
  45859. );
  45860. }
  45861. /**
  45862. * Asserts that the contents of a string is not equal
  45863. * to the contents of a file.
  45864. *
  45865. * @param string $expectedFile
  45866. * @param string $actualString
  45867. * @param string $message
  45868. * @param boolean $canonicalize
  45869. * @param boolean $ignoreCase
  45870. * @since Method available since Release 3.3.0
  45871. */
  45872. function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
  45873. {
  45874. return call_user_func_array(
  45875. 'PHPUnit_Framework_Assert::assertStringNotEqualsFile',
  45876. func_get_args()
  45877. );
  45878. }
  45879. /**
  45880. * Asserts that a string does not match a given format string.
  45881. *
  45882. * @param string $format
  45883. * @param string $string
  45884. * @param string $message
  45885. * @since Method available since Release 3.5.0
  45886. */
  45887. function assertStringNotMatchesFormat($format, $string, $message = '')
  45888. {
  45889. return call_user_func_array(
  45890. 'PHPUnit_Framework_Assert::assertStringNotMatchesFormat',
  45891. func_get_args()
  45892. );
  45893. }
  45894. /**
  45895. * Asserts that a string does not match a given format string.
  45896. *
  45897. * @param string $formatFile
  45898. * @param string $string
  45899. * @param string $message
  45900. * @since Method available since Release 3.5.0
  45901. */
  45902. function assertStringNotMatchesFormatFile($formatFile, $string, $message = '')
  45903. {
  45904. return call_user_func_array(
  45905. 'PHPUnit_Framework_Assert::assertStringNotMatchesFormatFile',
  45906. func_get_args()
  45907. );
  45908. }
  45909. /**
  45910. * Asserts that a string starts not with a given prefix.
  45911. *
  45912. * @param string $prefix
  45913. * @param string $string
  45914. * @param string $message
  45915. * @since Method available since Release 3.4.0
  45916. */
  45917. function assertStringStartsNotWith($prefix, $string, $message = '')
  45918. {
  45919. return call_user_func_array(
  45920. 'PHPUnit_Framework_Assert::assertStringStartsNotWith',
  45921. func_get_args()
  45922. );
  45923. }
  45924. /**
  45925. * Asserts that a string starts with a given prefix.
  45926. *
  45927. * @param string $prefix
  45928. * @param string $string
  45929. * @param string $message
  45930. * @since Method available since Release 3.4.0
  45931. */
  45932. function assertStringStartsWith($prefix, $string, $message = '')
  45933. {
  45934. return call_user_func_array(
  45935. 'PHPUnit_Framework_Assert::assertStringStartsWith',
  45936. func_get_args()
  45937. );
  45938. }
  45939. /**
  45940. * Evaluate an HTML or XML string and assert its structure and/or contents.
  45941. *
  45942. * The first argument ($matcher) is an associative array that specifies the
  45943. * match criteria for the assertion:
  45944. *
  45945. * - `id` : the node with the given id attribute must match the
  45946. * corresponding value.
  45947. * - `tag` : the node type must match the corresponding value.
  45948. * - `attributes` : a hash. The node's attributes must match the
  45949. * corresponding values in the hash.
  45950. * - `content` : The text content must match the given value.
  45951. * - `parent` : a hash. The node's parent must match the
  45952. * corresponding hash.
  45953. * - `child`: a hash. At least one of the node's immediate children
  45954. * must meet the criteria described by the hash.
  45955. * - `ancestor` : a hash. At least one of the node's ancestors must
  45956. * meet the criteria described by the hash.
  45957. * - `descendant` : a hash. At least one of the node's descendants must
  45958. * meet the criteria described by the hash.
  45959. * - `children` : a hash, for counting children of a node.
  45960. * Accepts the keys:
  45961. *- `count`: a number which must equal the number of children
  45962. * that match
  45963. *- `less_than`: the number of matching children must be greater
  45964. * than this number
  45965. *- `greater_than` : the number of matching children must be less than
  45966. * this number
  45967. *- `only` : another hash consisting of the keys to use to match
  45968. * on the children, and only matching children will be
  45969. * counted
  45970. *
  45971. * <code>
  45972. * // Matcher that asserts that there is an element with an id="my_id".
  45973. * $matcher = array('id' => 'my_id');
  45974. *
  45975. * // Matcher that asserts that there is a "span" tag.
  45976. * $matcher = array('tag' => 'span');
  45977. *
  45978. * // Matcher that asserts that there is a "span" tag with the content
  45979. * // "Hello World".
  45980. * $matcher = array('tag' => 'span', 'content' => 'Hello World');
  45981. *
  45982. * // Matcher that asserts that there is a "span" tag with content matching
  45983. * // the regular expression pattern.
  45984. * $matcher = array('tag' => 'span', 'content' => 'regexp:/Try P(HP|ython)/');
  45985. *
  45986. * // Matcher that asserts that there is a "span" with an "list" class
  45987. * // attribute.
  45988. * $matcher = array(
  45989. * 'tag'=> 'span',
  45990. * 'attributes' => array('class' => 'list')
  45991. * );
  45992. *
  45993. * // Matcher that asserts that there is a "span" inside of a "div".
  45994. * $matcher = array(
  45995. * 'tag'=> 'span',
  45996. * 'parent' => array('tag' => 'div')
  45997. * );
  45998. *
  45999. * // Matcher that asserts that there is a "span" somewhere inside a
  46000. * // "table".
  46001. * $matcher = array(
  46002. * 'tag' => 'span',
  46003. * 'ancestor' => array('tag' => 'table')
  46004. * );
  46005. *
  46006. * // Matcher that asserts that there is a "span" with at least one "em"
  46007. * // child.
  46008. * $matcher = array(
  46009. * 'tag' => 'span',
  46010. * 'child' => array('tag' => 'em')
  46011. * );
  46012. *
  46013. * // Matcher that asserts that there is a "span" containing a (possibly
  46014. * // nested) "strong" tag.
  46015. * $matcher = array(
  46016. * 'tag'=> 'span',
  46017. * 'descendant' => array('tag' => 'strong')
  46018. * );
  46019. *
  46020. * // Matcher that asserts that there is a "span" containing 5-10 "em" tags
  46021. * // as immediate children.
  46022. * $matcher = array(
  46023. * 'tag' => 'span',
  46024. * 'children' => array(
  46025. * 'less_than'=> 11,
  46026. * 'greater_than' => 4,
  46027. * 'only' => array('tag' => 'em')
  46028. * )
  46029. * );
  46030. *
  46031. * // Matcher that asserts that there is a "div", with an "ul" ancestor and
  46032. * // a "li" parent (with class="enum"), and containing a "span" descendant
  46033. * // that contains an element with id="my_test" and the text "Hello World".
  46034. * $matcher = array(
  46035. * 'tag'=> 'div',
  46036. * 'ancestor' => array('tag' => 'ul'),
  46037. * 'parent' => array(
  46038. * 'tag'=> 'li',
  46039. * 'attributes' => array('class' => 'enum')
  46040. * ),
  46041. * 'descendant' => array(
  46042. * 'tag' => 'span',
  46043. * 'child' => array(
  46044. * 'id' => 'my_test',
  46045. * 'content' => 'Hello World'
  46046. * )
  46047. * )
  46048. * );
  46049. *
  46050. * // Use assertTag() to apply a $matcher to a piece of $html.
  46051. * $this->assertTag($matcher, $html);
  46052. *
  46053. * // Use assertTag() to apply a $matcher to a piece of $xml.
  46054. * $this->assertTag($matcher, $xml, '', false);
  46055. * </code>
  46056. *
  46057. * The second argument ($actual) is a string containing either HTML or
  46058. * XML text to be tested.
  46059. *
  46060. * The third argument ($message) is an optional message that will be
  46061. * used if the assertion fails.
  46062. *
  46063. * The fourth argument ($html) is an optional flag specifying whether
  46064. * to load the $actual string into a DOMDocument using the HTML or
  46065. * XML load strategy. It is true by default, which assumes the HTML
  46066. * load strategy. In many cases, this will be acceptable for XML as well.
  46067. *
  46068. * @param array $matcher
  46069. * @param string $actual
  46070. * @param string $message
  46071. * @param boolean $isHtml
  46072. * @since Method available since Release 3.3.0
  46073. * @author Mike Naberezny <mike@maintainable.com>
  46074. * @author Derek DeVries <derek@maintainable.com>
  46075. */
  46076. function assertTag($matcher, $actual, $message = '', $isHtml = true)
  46077. {
  46078. return call_user_func_array(
  46079. 'PHPUnit_Framework_Assert::assertTag',
  46080. func_get_args()
  46081. );
  46082. }
  46083. /**
  46084. * Evaluates a PHPUnit_Framework_Constraint matcher object.
  46085. *
  46086. * @param mixed$value
  46087. * @param PHPUnit_Framework_Constraint $constraint
  46088. * @param string $message
  46089. * @since Method available since Release 3.0.0
  46090. */
  46091. function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '')
  46092. {
  46093. return call_user_func_array(
  46094. 'PHPUnit_Framework_Assert::assertThat',
  46095. func_get_args()
  46096. );
  46097. }
  46098. /**
  46099. * Asserts that a condition is true.
  46100. *
  46101. * @param boolean $condition
  46102. * @param string $message
  46103. * @throws PHPUnit_Framework_AssertionFailedError
  46104. */
  46105. function assertTrue($condition, $message = '')
  46106. {
  46107. return call_user_func_array(
  46108. 'PHPUnit_Framework_Assert::assertTrue',
  46109. func_get_args()
  46110. );
  46111. }
  46112. /**
  46113. * Asserts that two XML files are equal.
  46114. *
  46115. * @param string $expectedFile
  46116. * @param string $actualFile
  46117. * @param string $message
  46118. * @since Method available since Release 3.1.0
  46119. */
  46120. function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '')
  46121. {
  46122. return call_user_func_array(
  46123. 'PHPUnit_Framework_Assert::assertXmlFileEqualsXmlFile',
  46124. func_get_args()
  46125. );
  46126. }
  46127. /**
  46128. * Asserts that two XML files are not equal.
  46129. *
  46130. * @param string $expectedFile
  46131. * @param string $actualFile
  46132. * @param string $message
  46133. * @since Method available since Release 3.1.0
  46134. */
  46135. function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '')
  46136. {
  46137. return call_user_func_array(
  46138. 'PHPUnit_Framework_Assert::assertXmlFileNotEqualsXmlFile',
  46139. func_get_args()
  46140. );
  46141. }
  46142. /**
  46143. * Asserts that two XML documents are equal.
  46144. *
  46145. * @param string $expectedFile
  46146. * @param string $actualXml
  46147. * @param string $message
  46148. * @since Method available since Release 3.3.0
  46149. */
  46150. function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '')
  46151. {
  46152. return call_user_func_array(
  46153. 'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlFile',
  46154. func_get_args()
  46155. );
  46156. }
  46157. /**
  46158. * Asserts that two XML documents are equal.
  46159. *
  46160. * @param string $expectedXml
  46161. * @param string $actualXml
  46162. * @param string $message
  46163. * @since Method available since Release 3.1.0
  46164. */
  46165. function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '')
  46166. {
  46167. return call_user_func_array(
  46168. 'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlString',
  46169. func_get_args()
  46170. );
  46171. }
  46172. /**
  46173. * Asserts that two XML documents are not equal.
  46174. *
  46175. * @param string $expectedFile
  46176. * @param string $actualXml
  46177. * @param string $message
  46178. * @since Method available since Release 3.3.0
  46179. */
  46180. function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '')
  46181. {
  46182. return call_user_func_array(
  46183. 'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlFile',
  46184. func_get_args()
  46185. );
  46186. }
  46187. /**
  46188. * Asserts that two XML documents are not equal.
  46189. *
  46190. * @param string $expectedXml
  46191. * @param string $actualXml
  46192. * @param string $message
  46193. * @since Method available since Release 3.1.0
  46194. */
  46195. function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '')
  46196. {
  46197. return call_user_func_array(
  46198. 'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlString',
  46199. func_get_args()
  46200. );
  46201. }
  46202. /**
  46203. * Returns a matcher that matches when the method is executed
  46204. * at the given $index.
  46205. *
  46206. * @param integer $index
  46207. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex
  46208. * @since Method available since Release 3.0.0
  46209. */
  46210. function at($index)
  46211. {
  46212. return call_user_func_array(
  46213. 'PHPUnit_Framework_TestCase::at',
  46214. func_get_args()
  46215. );
  46216. }
  46217. /**
  46218. * Returns a matcher that matches when the method is executed at least once.
  46219. *
  46220. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce
  46221. * @since Method available since Release 3.0.0
  46222. */
  46223. function atLeastOnce()
  46224. {
  46225. return call_user_func_array(
  46226. 'PHPUnit_Framework_TestCase::atLeastOnce',
  46227. func_get_args()
  46228. );
  46229. }
  46230. /**
  46231. * Returns a PHPUnit_Framework_Constraint_Attribute matcher object.
  46232. *
  46233. * @param PHPUnit_Framework_Constraint $constraint
  46234. * @param string $attributeName
  46235. * @return PHPUnit_Framework_Constraint_Attribute
  46236. * @since Method available since Release 3.1.0
  46237. */
  46238. function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName)
  46239. {
  46240. return call_user_func_array(
  46241. 'PHPUnit_Framework_Assert::attribute',
  46242. func_get_args()
  46243. );
  46244. }
  46245. /**
  46246. * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object
  46247. * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher
  46248. * object.
  46249. *
  46250. * @param string $attributeName
  46251. * @param mixed $value
  46252. * @param float $delta
  46253. * @param integer $maxDepth
  46254. * @param boolean $canonicalize
  46255. * @param boolean $ignoreCase
  46256. * @return PHPUnit_Framework_Constraint_Attribute
  46257. * @since Method available since Release 3.1.0
  46258. */
  46259. function attributeEqualTo($attributeName, $value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  46260. {
  46261. return call_user_func_array(
  46262. 'PHPUnit_Framework_Assert::attributeEqualTo',
  46263. func_get_args()
  46264. );
  46265. }
  46266. /**
  46267. * Returns a PHPUnit_Framework_Constraint_Callback matcher object.
  46268. *
  46269. * @param callable $callback
  46270. * @return PHPUnit_Framework_Constraint_Callback
  46271. */
  46272. function callback($callback)
  46273. {
  46274. return call_user_func_array(
  46275. 'PHPUnit_Framework_Assert::callback',
  46276. func_get_args()
  46277. );
  46278. }
  46279. /**
  46280. * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object.
  46281. *
  46282. * @param string $attributeName
  46283. * @return PHPUnit_Framework_Constraint_ClassHasAttribute
  46284. * @since Method available since Release 3.1.0
  46285. */
  46286. function classHasAttribute($attributeName)
  46287. {
  46288. return call_user_func_array(
  46289. 'PHPUnit_Framework_Assert::classHasAttribute',
  46290. func_get_args()
  46291. );
  46292. }
  46293. /**
  46294. * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher
  46295. * object.
  46296. *
  46297. * @param string $attributeName
  46298. * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute
  46299. * @since Method available since Release 3.1.0
  46300. */
  46301. function classHasStaticAttribute($attributeName)
  46302. {
  46303. return call_user_func_array(
  46304. 'PHPUnit_Framework_Assert::classHasStaticAttribute',
  46305. func_get_args()
  46306. );
  46307. }
  46308. /**
  46309. * Returns a PHPUnit_Framework_Constraint_TraversableContains matcher
  46310. * object.
  46311. *
  46312. * @param mixed $value
  46313. * @param boolean $checkForObjectIdentity
  46314. * @param boolean $checkForNonObjectIdentity
  46315. * @return PHPUnit_Framework_Constraint_TraversableContains
  46316. * @since Method available since Release 3.0.0
  46317. */
  46318. function contains($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  46319. {
  46320. return call_user_func_array(
  46321. 'PHPUnit_Framework_Assert::contains',
  46322. func_get_args()
  46323. );
  46324. }
  46325. /**
  46326. * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
  46327. * object.
  46328. *
  46329. * @param string $type
  46330. * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
  46331. * @since Method available since Release 3.1.4
  46332. */
  46333. function containsOnly($type)
  46334. {
  46335. return call_user_func_array(
  46336. 'PHPUnit_Framework_Assert::containsOnly',
  46337. func_get_args()
  46338. );
  46339. }
  46340. /**
  46341. * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
  46342. * object.
  46343. *
  46344. * @param string $classname
  46345. * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
  46346. */
  46347. function containsOnlyInstancesOf($classname)
  46348. {
  46349. return call_user_func_array(
  46350. 'PHPUnit_Framework_Assert::containsOnlyInstancesOf',
  46351. func_get_args()
  46352. );
  46353. }
  46354. /**
  46355. * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object.
  46356. *
  46357. * @param mixed $value
  46358. * @param float $delta
  46359. * @param integer $maxDepth
  46360. * @param boolean $canonicalize
  46361. * @param boolean $ignoreCase
  46362. * @return PHPUnit_Framework_Constraint_IsEqual
  46363. * @since Method available since Release 3.0.0
  46364. */
  46365. function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  46366. {
  46367. return call_user_func_array(
  46368. 'PHPUnit_Framework_Assert::equalTo',
  46369. func_get_args()
  46370. );
  46371. }
  46372. /**
  46373. * Returns a matcher that matches when the method is executed
  46374. * exactly $count times.
  46375. *
  46376. * @param integer $count
  46377. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  46378. * @since Method available since Release 3.0.0
  46379. */
  46380. function exactly($count)
  46381. {
  46382. return call_user_func_array(
  46383. 'PHPUnit_Framework_TestCase::exactly',
  46384. func_get_args()
  46385. );
  46386. }
  46387. /**
  46388. * Returns a PHPUnit_Framework_Constraint_FileExists matcher object.
  46389. *
  46390. * @return PHPUnit_Framework_Constraint_FileExists
  46391. * @since Method available since Release 3.0.0
  46392. */
  46393. function fileExists()
  46394. {
  46395. return call_user_func_array(
  46396. 'PHPUnit_Framework_Assert::fileExists',
  46397. func_get_args()
  46398. );
  46399. }
  46400. /**
  46401. * Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object.
  46402. *
  46403. * @param mixed $value
  46404. * @return PHPUnit_Framework_Constraint_GreaterThan
  46405. * @since Method available since Release 3.0.0
  46406. */
  46407. function greaterThan($value)
  46408. {
  46409. return call_user_func_array(
  46410. 'PHPUnit_Framework_Assert::greaterThan',
  46411. func_get_args()
  46412. );
  46413. }
  46414. /**
  46415. * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
  46416. * a PHPUnit_Framework_Constraint_IsEqual and a
  46417. * PHPUnit_Framework_Constraint_GreaterThan matcher object.
  46418. *
  46419. * @param mixed $value
  46420. * @return PHPUnit_Framework_Constraint_Or
  46421. * @since Method available since Release 3.1.0
  46422. */
  46423. function greaterThanOrEqual($value)
  46424. {
  46425. return call_user_func_array(
  46426. 'PHPUnit_Framework_Assert::greaterThanOrEqual',
  46427. func_get_args()
  46428. );
  46429. }
  46430. /**
  46431. * Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object.
  46432. *
  46433. * @param mixed $value
  46434. * @return PHPUnit_Framework_Constraint_IsIdentical
  46435. * @since Method available since Release 3.0.0
  46436. */
  46437. function identicalTo($value)
  46438. {
  46439. return call_user_func_array(
  46440. 'PHPUnit_Framework_Assert::identicalTo',
  46441. func_get_args()
  46442. );
  46443. }
  46444. /**
  46445. * Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object.
  46446. *
  46447. * @return PHPUnit_Framework_Constraint_IsEmpty
  46448. * @since Method available since Release 3.5.0
  46449. */
  46450. function isEmpty()
  46451. {
  46452. return call_user_func_array(
  46453. 'PHPUnit_Framework_Assert::isEmpty',
  46454. func_get_args()
  46455. );
  46456. }
  46457. /**
  46458. * Returns a PHPUnit_Framework_Constraint_IsFalse matcher object.
  46459. *
  46460. * @return PHPUnit_Framework_Constraint_IsFalse
  46461. * @since Method available since Release 3.3.0
  46462. */
  46463. function isFalse()
  46464. {
  46465. return call_user_func_array(
  46466. 'PHPUnit_Framework_Assert::isFalse',
  46467. func_get_args()
  46468. );
  46469. }
  46470. /**
  46471. * Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object.
  46472. *
  46473. * @param string $className
  46474. * @return PHPUnit_Framework_Constraint_IsInstanceOf
  46475. * @since Method available since Release 3.0.0
  46476. */
  46477. function isInstanceOf($className)
  46478. {
  46479. return call_user_func_array(
  46480. 'PHPUnit_Framework_Assert::isInstanceOf',
  46481. func_get_args()
  46482. );
  46483. }
  46484. /**
  46485. * Returns a PHPUnit_Framework_Constraint_IsJson matcher object.
  46486. *
  46487. * @return PHPUnit_Framework_Constraint_IsJson
  46488. * @since Method available since Release 3.7.20
  46489. */
  46490. function isJson()
  46491. {
  46492. return call_user_func_array(
  46493. 'PHPUnit_Framework_Assert::isJson',
  46494. func_get_args()
  46495. );
  46496. }
  46497. /**
  46498. * Returns a PHPUnit_Framework_Constraint_IsNull matcher object.
  46499. *
  46500. * @return PHPUnit_Framework_Constraint_IsNull
  46501. * @since Method available since Release 3.3.0
  46502. */
  46503. function isNull()
  46504. {
  46505. return call_user_func_array(
  46506. 'PHPUnit_Framework_Assert::isNull',
  46507. func_get_args()
  46508. );
  46509. }
  46510. /**
  46511. * Returns a PHPUnit_Framework_Constraint_IsTrue matcher object.
  46512. *
  46513. * @return PHPUnit_Framework_Constraint_IsTrue
  46514. * @since Method available since Release 3.3.0
  46515. */
  46516. function isTrue()
  46517. {
  46518. return call_user_func_array(
  46519. 'PHPUnit_Framework_Assert::isTrue',
  46520. func_get_args()
  46521. );
  46522. }
  46523. /**
  46524. * Returns a PHPUnit_Framework_Constraint_IsType matcher object.
  46525. *
  46526. * @param string $type
  46527. * @return PHPUnit_Framework_Constraint_IsType
  46528. * @since Method available since Release 3.0.0
  46529. */
  46530. function isType($type)
  46531. {
  46532. return call_user_func_array(
  46533. 'PHPUnit_Framework_Assert::isType',
  46534. func_get_args()
  46535. );
  46536. }
  46537. /**
  46538. * Returns a PHPUnit_Framework_Constraint_LessThan matcher object.
  46539. *
  46540. * @param mixed $value
  46541. * @return PHPUnit_Framework_Constraint_LessThan
  46542. * @since Method available since Release 3.0.0
  46543. */
  46544. function lessThan($value)
  46545. {
  46546. return call_user_func_array(
  46547. 'PHPUnit_Framework_Assert::lessThan',
  46548. func_get_args()
  46549. );
  46550. }
  46551. /**
  46552. * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
  46553. * a PHPUnit_Framework_Constraint_IsEqual and a
  46554. * PHPUnit_Framework_Constraint_LessThan matcher object.
  46555. *
  46556. * @param mixed $value
  46557. * @return PHPUnit_Framework_Constraint_Or
  46558. * @since Method available since Release 3.1.0
  46559. */
  46560. function lessThanOrEqual($value)
  46561. {
  46562. return call_user_func_array(
  46563. 'PHPUnit_Framework_Assert::lessThanOrEqual',
  46564. func_get_args()
  46565. );
  46566. }
  46567. /**
  46568. * Returns a PHPUnit_Framework_Constraint_And matcher object.
  46569. *
  46570. * @return PHPUnit_Framework_Constraint_And
  46571. * @since Method available since Release 3.0.0
  46572. */
  46573. function logicalAnd()
  46574. {
  46575. return call_user_func_array(
  46576. 'PHPUnit_Framework_Assert::logicalAnd',
  46577. func_get_args()
  46578. );
  46579. }
  46580. /**
  46581. * Returns a PHPUnit_Framework_Constraint_Not matcher object.
  46582. *
  46583. * @param PHPUnit_Framework_Constraint $constraint
  46584. * @return PHPUnit_Framework_Constraint_Not
  46585. * @since Method available since Release 3.0.0
  46586. */
  46587. function logicalNot(PHPUnit_Framework_Constraint $constraint)
  46588. {
  46589. return call_user_func_array(
  46590. 'PHPUnit_Framework_Assert::logicalNot',
  46591. func_get_args()
  46592. );
  46593. }
  46594. /**
  46595. * Returns a PHPUnit_Framework_Constraint_Or matcher object.
  46596. *
  46597. * @return PHPUnit_Framework_Constraint_Or
  46598. * @since Method available since Release 3.0.0
  46599. */
  46600. function logicalOr()
  46601. {
  46602. return call_user_func_array(
  46603. 'PHPUnit_Framework_Assert::logicalOr',
  46604. func_get_args()
  46605. );
  46606. }
  46607. /**
  46608. * Returns a PHPUnit_Framework_Constraint_Xor matcher object.
  46609. *
  46610. * @return PHPUnit_Framework_Constraint_Xor
  46611. * @since Method available since Release 3.0.0
  46612. */
  46613. function logicalXor()
  46614. {
  46615. return call_user_func_array(
  46616. 'PHPUnit_Framework_Assert::logicalXor',
  46617. func_get_args()
  46618. );
  46619. }
  46620. /**
  46621. * Returns a PHPUnit_Framework_Constraint_StringMatches matcher object.
  46622. *
  46623. * @param string $string
  46624. * @return PHPUnit_Framework_Constraint_StringMatches
  46625. * @since Method available since Release 3.5.0
  46626. */
  46627. function matches($string)
  46628. {
  46629. return call_user_func_array(
  46630. 'PHPUnit_Framework_Assert::matches',
  46631. func_get_args()
  46632. );
  46633. }
  46634. /**
  46635. * Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object.
  46636. *
  46637. * @param string $pattern
  46638. * @return PHPUnit_Framework_Constraint_PCREMatch
  46639. * @since Method available since Release 3.0.0
  46640. */
  46641. function matchesRegularExpression($pattern)
  46642. {
  46643. return call_user_func_array(
  46644. 'PHPUnit_Framework_Assert::matchesRegularExpression',
  46645. func_get_args()
  46646. );
  46647. }
  46648. /**
  46649. * Returns a matcher that matches when the method is never executed.
  46650. *
  46651. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  46652. * @since Method available since Release 3.0.0
  46653. */
  46654. function never()
  46655. {
  46656. return call_user_func_array(
  46657. 'PHPUnit_Framework_TestCase::never',
  46658. func_get_args()
  46659. );
  46660. }
  46661. /**
  46662. * Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object.
  46663. *
  46664. * @param string $attributeName
  46665. * @return PHPUnit_Framework_Constraint_ObjectHasAttribute
  46666. * @since Method available since Release 3.0.0
  46667. */
  46668. function objectHasAttribute($attributeName)
  46669. {
  46670. return call_user_func_array(
  46671. 'PHPUnit_Framework_Assert::objectHasAttribute',
  46672. func_get_args()
  46673. );
  46674. }
  46675. /**
  46676. * @param mixed $value, ...
  46677. * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls
  46678. * @since Method available since Release 3.0.0
  46679. */
  46680. function onConsecutiveCalls()
  46681. {
  46682. return call_user_func_array(
  46683. 'PHPUnit_Framework_TestCase::onConsecutiveCalls',
  46684. func_get_args()
  46685. );
  46686. }
  46687. /**
  46688. * Returns a matcher that matches when the method is executed exactly once.
  46689. *
  46690. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  46691. * @since Method available since Release 3.0.0
  46692. */
  46693. function once()
  46694. {
  46695. return call_user_func_array(
  46696. 'PHPUnit_Framework_TestCase::once',
  46697. func_get_args()
  46698. );
  46699. }
  46700. /**
  46701. *
  46702. *
  46703. * @param integer $argumentIndex
  46704. * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument
  46705. * @since Method available since Release 3.3.0
  46706. */
  46707. function returnArgument($argumentIndex)
  46708. {
  46709. return call_user_func_array(
  46710. 'PHPUnit_Framework_TestCase::returnArgument',
  46711. func_get_args()
  46712. );
  46713. }
  46714. /**
  46715. *
  46716. *
  46717. * @param mixed $callback
  46718. * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback
  46719. * @since Method available since Release 3.3.0
  46720. */
  46721. function returnCallback($callback)
  46722. {
  46723. return call_user_func_array(
  46724. 'PHPUnit_Framework_TestCase::returnCallback',
  46725. func_get_args()
  46726. );
  46727. }
  46728. /**
  46729. * Returns the current object.
  46730. *
  46731. * This method is useful when mocking a fluent interface.
  46732. *
  46733. * @return PHPUnit_Framework_MockObject_Stub_ReturnSelf
  46734. * @since Method available since Release 3.6.0
  46735. */
  46736. function returnSelf()
  46737. {
  46738. return call_user_func_array(
  46739. 'PHPUnit_Framework_TestCase::returnSelf',
  46740. func_get_args()
  46741. );
  46742. }
  46743. /**
  46744. *
  46745. *
  46746. * @param mixed $value
  46747. * @return PHPUnit_Framework_MockObject_Stub_Return
  46748. * @since Method available since Release 3.0.0
  46749. */
  46750. function returnValue($value)
  46751. {
  46752. return call_user_func_array(
  46753. 'PHPUnit_Framework_TestCase::returnValue',
  46754. func_get_args()
  46755. );
  46756. }
  46757. /**
  46758. *
  46759. *
  46760. * @param array $valueMap
  46761. * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap
  46762. * @since Method available since Release 3.6.0
  46763. */
  46764. function returnValueMap(array $valueMap)
  46765. {
  46766. return call_user_func_array(
  46767. 'PHPUnit_Framework_TestCase::returnValueMap',
  46768. func_get_args()
  46769. );
  46770. }
  46771. /**
  46772. * Returns a PHPUnit_Framework_Constraint_StringContains matcher object.
  46773. *
  46774. * @param string $string
  46775. * @param boolean $case
  46776. * @return PHPUnit_Framework_Constraint_StringContains
  46777. * @since Method available since Release 3.0.0
  46778. */
  46779. function stringContains($string, $case = true)
  46780. {
  46781. return call_user_func_array(
  46782. 'PHPUnit_Framework_Assert::stringContains',
  46783. func_get_args()
  46784. );
  46785. }
  46786. /**
  46787. * Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object.
  46788. *
  46789. * @param mixed $suffix
  46790. * @return PHPUnit_Framework_Constraint_StringEndsWith
  46791. * @since Method available since Release 3.4.0
  46792. */
  46793. function stringEndsWith($suffix)
  46794. {
  46795. return call_user_func_array(
  46796. 'PHPUnit_Framework_Assert::stringEndsWith',
  46797. func_get_args()
  46798. );
  46799. }
  46800. /**
  46801. * Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object.
  46802. *
  46803. * @param mixed $prefix
  46804. * @return PHPUnit_Framework_Constraint_StringStartsWith
  46805. * @since Method available since Release 3.4.0
  46806. */
  46807. function stringStartsWith($prefix)
  46808. {
  46809. return call_user_func_array(
  46810. 'PHPUnit_Framework_Assert::stringStartsWith',
  46811. func_get_args()
  46812. );
  46813. }
  46814. /**
  46815. *
  46816. *
  46817. * @param Exception $exception
  46818. * @return PHPUnit_Framework_MockObject_Stub_Exception
  46819. * @since Method available since Release 3.1.0
  46820. */
  46821. function throwException(Exception $exception)
  46822. {
  46823. return call_user_func_array(
  46824. 'PHPUnit_Framework_TestCase::throwException',
  46825. func_get_args()
  46826. );
  46827. }
  46828. <?php
  46829. /*
  46830. * This file is part of PHPUnit.
  46831. *
  46832. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  46833. *
  46834. * For the full copyright and license information, please view the LICENSE
  46835. * file that was distributed with this source code.
  46836. */
  46837. /**
  46838. * Creates a synthetic failed assertion.
  46839. *
  46840. * @package PHPUnit
  46841. * @subpackage Framework
  46842. * @author Sebastian Bergmann <sebastian@phpunit.de>
  46843. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  46844. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  46845. * @link http://www.phpunit.de/
  46846. * @since Class available since Release 3.5.0
  46847. */
  46848. class PHPUnit_Framework_SyntheticError extends PHPUnit_Framework_AssertionFailedError
  46849. {
  46850. /**
  46851. * The synthetic file.
  46852. *
  46853. * @var string
  46854. */
  46855. protected $syntheticFile = '';
  46856. /**
  46857. * The synthetic line number.
  46858. *
  46859. * @var integer
  46860. */
  46861. protected $syntheticLine = 0;
  46862. /**
  46863. * The synthetic trace.
  46864. *
  46865. * @var array
  46866. */
  46867. protected $syntheticTrace = array();
  46868. /**
  46869. * Constructor.
  46870. *
  46871. * @param string $message
  46872. * @param integer $code
  46873. * @param string $file
  46874. * @param integer $line
  46875. * @param array $trace
  46876. */
  46877. public function __construct($message, $code, $file, $line, $trace)
  46878. {
  46879. parent::__construct($message, $code);
  46880. $this->syntheticFile = $file;
  46881. $this->syntheticLine = $line;
  46882. $this->syntheticTrace = $trace;
  46883. }
  46884. /**
  46885. * @return string
  46886. */
  46887. public function getSyntheticFile()
  46888. {
  46889. return $this->syntheticFile;
  46890. }
  46891. /**
  46892. * @return integer
  46893. */
  46894. public function getSyntheticLine()
  46895. {
  46896. return $this->syntheticLine;
  46897. }
  46898. /**
  46899. * @return array
  46900. */
  46901. public function getSyntheticTrace()
  46902. {
  46903. return $this->syntheticTrace;
  46904. }
  46905. }
  46906. <?php
  46907. /*
  46908. * This file is part of PHPUnit.
  46909. *
  46910. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  46911. *
  46912. * For the full copyright and license information, please view the LICENSE
  46913. * file that was distributed with this source code.
  46914. */
  46915. /**
  46916. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  46917. * case of a risky test.
  46918. *
  46919. * @package PHPUnit
  46920. * @subpackage Framework
  46921. * @author Sebastian Bergmann <sebastian@phpunit.de>
  46922. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  46923. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  46924. * @link http://www.phpunit.de/
  46925. * @since Class available since Release 4.0.0
  46926. */
  46927. class PHPUnit_Framework_RiskyTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_RiskyTest
  46928. {
  46929. }
  46930. <?php
  46931. /*
  46932. * This file is part of PHPUnit.
  46933. *
  46934. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  46935. *
  46936. * For the full copyright and license information, please view the LICENSE
  46937. * file that was distributed with this source code.
  46938. */
  46939. /**
  46940. * A Listener for test progress.
  46941. *
  46942. * @package PHPUnit
  46943. * @subpackage Framework
  46944. * @author Sebastian Bergmann <sebastian@phpunit.de>
  46945. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  46946. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  46947. * @link http://www.phpunit.de/
  46948. * @since Interface available since Release 2.0.0
  46949. */
  46950. interface PHPUnit_Framework_TestListener
  46951. {
  46952. /**
  46953. * An error occurred.
  46954. *
  46955. * @param PHPUnit_Framework_Test $test
  46956. * @param Exception $e
  46957. * @param float $time
  46958. */
  46959. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time);
  46960. /**
  46961. * A failure occurred.
  46962. *
  46963. * @param PHPUnit_Framework_Test $test
  46964. * @param PHPUnit_Framework_AssertionFailedError $e
  46965. * @param float $time
  46966. */
  46967. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time);
  46968. /**
  46969. * Incomplete test.
  46970. *
  46971. * @param PHPUnit_Framework_Test $test
  46972. * @param Exception $e
  46973. * @param float $time
  46974. */
  46975. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time);
  46976. /**
  46977. * Risky test.
  46978. *
  46979. * @param PHPUnit_Framework_Test $test
  46980. * @param Exception $e
  46981. * @param float $time
  46982. * @since Method available since Release 4.0.0
  46983. */
  46984. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time);
  46985. /**
  46986. * Skipped test.
  46987. *
  46988. * @param PHPUnit_Framework_Test $test
  46989. * @param Exception $e
  46990. * @param float $time
  46991. * @since Method available since Release 3.0.0
  46992. */
  46993. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time);
  46994. /**
  46995. * A test suite started.
  46996. *
  46997. * @param PHPUnit_Framework_TestSuite $suite
  46998. * @since Method available since Release 2.2.0
  46999. */
  47000. public function startTestSuite(PHPUnit_Framework_TestSuite $suite);
  47001. /**
  47002. * A test suite ended.
  47003. *
  47004. * @param PHPUnit_Framework_TestSuite $suite
  47005. * @since Method available since Release 2.2.0
  47006. */
  47007. public function endTestSuite(PHPUnit_Framework_TestSuite $suite);
  47008. /**
  47009. * A test started.
  47010. *
  47011. * @param PHPUnit_Framework_Test $test
  47012. */
  47013. public function startTest(PHPUnit_Framework_Test $test);
  47014. /**
  47015. * A test ended.
  47016. *
  47017. * @param PHPUnit_Framework_Test $test
  47018. * @param float $time
  47019. */
  47020. public function endTest(PHPUnit_Framework_Test $test, $time);
  47021. }
  47022. <?php
  47023. /*
  47024. * This file is part of PHPUnit.
  47025. *
  47026. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  47027. *
  47028. * For the full copyright and license information, please view the LICENSE
  47029. * file that was distributed with this source code.
  47030. */
  47031. /**
  47032. * Wraps Exceptions thrown by code under test.
  47033. *
  47034. * Re-instantiates Exceptions thrown by user-space code to retain their original
  47035. * class names, properties, and stack traces (but without arguments).
  47036. *
  47037. * Unlike PHPUnit_Framework_Exception, the complete stack of previous Exceptions
  47038. * is processed.
  47039. *
  47040. * @package PHPUnit
  47041. * @subpackage Framework
  47042. * @author Daniel F. Kudwien <sun@unleashedmind.com>
  47043. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  47044. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  47045. * @link http://www.phpunit.de/
  47046. * @since Class available since Release 4.3.0
  47047. */
  47048. class PHPUnit_Framework_ExceptionWrapper extends PHPUnit_Framework_Exception
  47049. {
  47050. /**
  47051. * @var string
  47052. */
  47053. protected $classname;
  47054. /**
  47055. * @var PHPUnit_Framework_ExceptionWrapper|null
  47056. */
  47057. protected $previous;
  47058. public function __construct(Exception $e)
  47059. {
  47060. // PDOException::getCode() is a string.
  47061. // @see http://php.net/manual/en/class.pdoexception.php#95812
  47062. parent::__construct($e->getMessage(), (int) $e->getCode());
  47063. $this->classname = get_class($e);
  47064. $this->file = $e->getFile();
  47065. $this->line = $e->getLine();
  47066. $this->serializableTrace = $e->getTrace();
  47067. foreach ($this->serializableTrace as $i => $call) {
  47068. unset($this->serializableTrace[$i]['args']);
  47069. }
  47070. if ($e->getPrevious()) {
  47071. $this->previous = new self($e->getPrevious());
  47072. }
  47073. }
  47074. /**
  47075. * @return string
  47076. */
  47077. public function getClassname()
  47078. {
  47079. return $this->classname;
  47080. }
  47081. /**
  47082. * @return PHPUnit_Framework_ExceptionWrapper
  47083. */
  47084. public function getPreviousWrapped()
  47085. {
  47086. return $this->previous;
  47087. }
  47088. /**
  47089. * @return string
  47090. */
  47091. public function __toString()
  47092. {
  47093. $string = PHPUnit_Framework_TestFailure::exceptionToString($this);
  47094. if ($trace = PHPUnit_Util_Filter::getFilteredStacktrace($this)) {
  47095. $string .= "\n" . $trace;
  47096. }
  47097. if ($this->previous) {
  47098. $string .= "\nCaused by\n" . $this->previous;
  47099. }
  47100. return $string;
  47101. }
  47102. }
  47103. <?php
  47104. /*
  47105. * This file is part of PHPUnit.
  47106. *
  47107. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  47108. *
  47109. * For the full copyright and license information, please view the LICENSE
  47110. * file that was distributed with this source code.
  47111. */
  47112. /**
  47113. * A marker interface for marking a unit test as being skipped.
  47114. *
  47115. * @package PHPUnit
  47116. * @subpackage Framework
  47117. * @author Sebastian Bergmann <sebastian@phpunit.de>
  47118. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  47119. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  47120. * @link http://www.phpunit.de/
  47121. * @since Interface available since Release 3.0.0
  47122. */
  47123. interface PHPUnit_Framework_SkippedTest
  47124. {
  47125. }
  47126. <?php
  47127. /*
  47128. * This file is part of PHPUnit.
  47129. *
  47130. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  47131. *
  47132. * For the full copyright and license information, please view the LICENSE
  47133. * file that was distributed with this source code.
  47134. */
  47135. /**
  47136. * @package PHPUnit
  47137. * @subpackage Framework
  47138. * @author Sebastian Bergmann <sebastian@phpunit.de>
  47139. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  47140. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  47141. * @link http://www.phpunit.de/
  47142. * @since Class available since Release 4.0.0
  47143. */
  47144. class PHPUnit_Framework_InvalidCoversTargetException extends PHPUnit_Framework_CodeCoverageException
  47145. {
  47146. }
  47147. <?php
  47148. /*
  47149. * This file is part of PHPUnit.
  47150. *
  47151. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  47152. *
  47153. * For the full copyright and license information, please view the LICENSE
  47154. * file that was distributed with this source code.
  47155. */
  47156. use SebastianBergmann\GlobalState\Snapshot;
  47157. use SebastianBergmann\GlobalState\Restorer;
  47158. use SebastianBergmann\GlobalState\Blacklist;
  47159. use SebastianBergmann\Diff\Differ;
  47160. use SebastianBergmann\Exporter\Exporter;
  47161. use Prophecy\Exception\Prediction\PredictionException;
  47162. use Prophecy\Prophet;
  47163. /**
  47164. * A TestCase defines the fixture to run multiple tests.
  47165. *
  47166. * To define a TestCase
  47167. *
  47168. * 1) Implement a subclass of PHPUnit_Framework_TestCase.
  47169. * 2) Define instance variables that store the state of the fixture.
  47170. * 3) Initialize the fixture state by overriding setUp().
  47171. * 4) Clean-up after a test by overriding tearDown().
  47172. *
  47173. * Each test runs in its own fixture so there can be no side effects
  47174. * among test runs.
  47175. *
  47176. * Here is an example:
  47177. *
  47178. * <code>
  47179. * <?php
  47180. * class MathTest extends PHPUnit_Framework_TestCase
  47181. * {
  47182. * public $value1;
  47183. * public $value2;
  47184. *
  47185. * protected function setUp()
  47186. * {
  47187. * $this->value1 = 2;
  47188. * $this->value2 = 3;
  47189. * }
  47190. * }
  47191. * ?>
  47192. * </code>
  47193. *
  47194. * For each test implement a method which interacts with the fixture.
  47195. * Verify the expected results with assertions specified by calling
  47196. * assert with a boolean.
  47197. *
  47198. * <code>
  47199. * <?php
  47200. * public function testPass()
  47201. * {
  47202. * $this->assertTrue($this->value1 + $this->value2 == 5);
  47203. * }
  47204. * ?>
  47205. * </code>
  47206. *
  47207. * @package PHPUnit
  47208. * @subpackage Framework
  47209. * @author Sebastian Bergmann <sebastian@phpunit.de>
  47210. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  47211. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  47212. * @link http://www.phpunit.de/
  47213. * @since Class available since Release 2.0.0
  47214. */
  47215. abstract class PHPUnit_Framework_TestCase extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing
  47216. {
  47217. /**
  47218. * Enable or disable the backup and restoration of the $GLOBALS array.
  47219. * Overwrite this attribute in a child class of TestCase.
  47220. * Setting this attribute in setUp() has no effect!
  47221. *
  47222. * @var boolean
  47223. */
  47224. protected $backupGlobals = null;
  47225. /**
  47226. * @var array
  47227. */
  47228. protected $backupGlobalsBlacklist = array();
  47229. /**
  47230. * Enable or disable the backup and restoration of static attributes.
  47231. * Overwrite this attribute in a child class of TestCase.
  47232. * Setting this attribute in setUp() has no effect!
  47233. *
  47234. * @var boolean
  47235. */
  47236. protected $backupStaticAttributes = null;
  47237. /**
  47238. * @var array
  47239. */
  47240. protected $backupStaticAttributesBlacklist = array();
  47241. /**
  47242. * Whether or not this test is to be run in a separate PHP process.
  47243. *
  47244. * @var boolean
  47245. */
  47246. protected $runTestInSeparateProcess = null;
  47247. /**
  47248. * Whether or not this test should preserve the global state when
  47249. * running in a separate PHP process.
  47250. *
  47251. * @var boolean
  47252. */
  47253. protected $preserveGlobalState = true;
  47254. /**
  47255. * Whether or not this test is running in a separate PHP process.
  47256. *
  47257. * @var boolean
  47258. */
  47259. private $inIsolation = false;
  47260. /**
  47261. * @var array
  47262. */
  47263. private $data = array();
  47264. /**
  47265. * @var string
  47266. */
  47267. private $dataName = '';
  47268. /**
  47269. * @var boolean
  47270. */
  47271. private $useErrorHandler = null;
  47272. /**
  47273. * The name of the expected Exception.
  47274. *
  47275. * @var mixed
  47276. */
  47277. private $expectedException = null;
  47278. /**
  47279. * The message of the expected Exception.
  47280. *
  47281. * @var string
  47282. */
  47283. private $expectedExceptionMessage = '';
  47284. /**
  47285. * The regex pattern to validate the expected Exception message.
  47286. *
  47287. * @var string
  47288. */
  47289. private $expectedExceptionMessageRegExp = '';
  47290. /**
  47291. * The code of the expected Exception.
  47292. *
  47293. * @var integer
  47294. */
  47295. private $expectedExceptionCode;
  47296. /**
  47297. * The name of the test case.
  47298. *
  47299. * @var string
  47300. */
  47301. private $name = null;
  47302. /**
  47303. * @var array
  47304. */
  47305. private $dependencies = array();
  47306. /**
  47307. * @var array
  47308. */
  47309. private $dependencyInput = array();
  47310. /**
  47311. * @var array
  47312. */
  47313. private $iniSettings = array();
  47314. /**
  47315. * @var array
  47316. */
  47317. private $locale = array();
  47318. /**
  47319. * @var array
  47320. */
  47321. private $mockObjects = array();
  47322. /**
  47323. * @var array
  47324. */
  47325. private $mockObjectGenerator = null;
  47326. /**
  47327. * @var integer
  47328. */
  47329. private $status;
  47330. /**
  47331. * @var string
  47332. */
  47333. private $statusMessage = '';
  47334. /**
  47335. * @var integer
  47336. */
  47337. private $numAssertions = 0;
  47338. /**
  47339. * @var PHPUnit_Framework_TestResult
  47340. */
  47341. private $result;
  47342. /**
  47343. * @var mixed
  47344. */
  47345. private $testResult;
  47346. /**
  47347. * @var string
  47348. */
  47349. private $output = '';
  47350. /**
  47351. * @var string
  47352. */
  47353. private $outputExpectedRegex = null;
  47354. /**
  47355. * @var string
  47356. */
  47357. private $outputExpectedString = null;
  47358. /**
  47359. * @var mixed
  47360. */
  47361. private $outputCallback = false;
  47362. /**
  47363. * @var boolean
  47364. */
  47365. private $outputBufferingActive = false;
  47366. /**
  47367. * @var integer
  47368. */
  47369. private $outputBufferingLevel;
  47370. /**
  47371. * @var SebastianBergmann\GlobalState\Snapshot
  47372. */
  47373. private $snapshot;
  47374. /**
  47375. * @var Prophecy\Prophet
  47376. */
  47377. private $prophet;
  47378. /**
  47379. * @var boolean
  47380. */
  47381. private $disallowChangesToGlobalState = false;
  47382. /**
  47383. * Constructs a test case with the given name.
  47384. *
  47385. * @param string $name
  47386. * @param array $data
  47387. * @param string $dataName
  47388. */
  47389. public function __construct($name = null, array $data = array(), $dataName = '')
  47390. {
  47391. if ($name !== null) {
  47392. $this->setName($name);
  47393. }
  47394. $this->data = $data;
  47395. $this->dataName = $dataName;
  47396. }
  47397. /**
  47398. * Returns a string representation of the test case.
  47399. *
  47400. * @return string
  47401. */
  47402. public function toString()
  47403. {
  47404. $class = new ReflectionClass($this);
  47405. $buffer = sprintf(
  47406. '%s::%s',
  47407. $class->name,
  47408. $this->getName(false)
  47409. );
  47410. return $buffer . $this->getDataSetAsString();
  47411. }
  47412. /**
  47413. * Counts the number of test cases executed by run(TestResult result).
  47414. *
  47415. * @return integer
  47416. */
  47417. public function count()
  47418. {
  47419. return 1;
  47420. }
  47421. /**
  47422. * Returns the annotations for this test.
  47423. *
  47424. * @return array
  47425. * @since Method available since Release 3.4.0
  47426. */
  47427. public function getAnnotations()
  47428. {
  47429. return PHPUnit_Util_Test::parseTestMethodAnnotations(
  47430. get_class($this),
  47431. $this->name
  47432. );
  47433. }
  47434. /**
  47435. * Gets the name of a TestCase.
  47436. *
  47437. * @param boolean $withDataSet
  47438. * @return string
  47439. */
  47440. public function getName($withDataSet = true)
  47441. {
  47442. if ($withDataSet) {
  47443. return $this->name . $this->getDataSetAsString(false);
  47444. } else {
  47445. return $this->name;
  47446. }
  47447. }
  47448. /**
  47449. * Returns the size of the test.
  47450. *
  47451. * @return integer
  47452. * @since Method available since Release 3.6.0
  47453. */
  47454. public function getSize()
  47455. {
  47456. return PHPUnit_Util_Test::getSize(
  47457. get_class($this),
  47458. $this->getName(false)
  47459. );
  47460. }
  47461. /**
  47462. * @return string
  47463. * @since Method available since Release 3.6.0
  47464. */
  47465. public function getActualOutput()
  47466. {
  47467. if (!$this->outputBufferingActive) {
  47468. return $this->output;
  47469. } else {
  47470. return ob_get_contents();
  47471. }
  47472. }
  47473. /**
  47474. * @return boolean
  47475. * @since Method available since Release 3.6.0
  47476. */
  47477. public function hasOutput()
  47478. {
  47479. if (strlen($this->output) === 0) {
  47480. return false;
  47481. }
  47482. if ($this->hasExpectationOnOutput()) {
  47483. return false;
  47484. }
  47485. return true;
  47486. }
  47487. /**
  47488. * @param string $expectedRegex
  47489. * @since Method available since Release 3.6.0
  47490. * @throws PHPUnit_Framework_Exception
  47491. */
  47492. public function expectOutputRegex($expectedRegex)
  47493. {
  47494. if ($this->outputExpectedString !== null) {
  47495. throw new PHPUnit_Framework_Exception;
  47496. }
  47497. if (is_string($expectedRegex) || is_null($expectedRegex)) {
  47498. $this->outputExpectedRegex = $expectedRegex;
  47499. }
  47500. }
  47501. /**
  47502. * @param string $expectedString
  47503. * @since Method available since Release 3.6.0
  47504. */
  47505. public function expectOutputString($expectedString)
  47506. {
  47507. if ($this->outputExpectedRegex !== null) {
  47508. throw new PHPUnit_Framework_Exception;
  47509. }
  47510. if (is_string($expectedString) || is_null($expectedString)) {
  47511. $this->outputExpectedString = $expectedString;
  47512. }
  47513. }
  47514. /**
  47515. * @return bool
  47516. * @since Method available since Release 3.6.5
  47517. * @deprecated
  47518. */
  47519. public function hasPerformedExpectationsOnOutput()
  47520. {
  47521. return $this->hasExpectationOnOutput();
  47522. }
  47523. /**
  47524. * @return bool
  47525. * @since Method available since Release 4.3.3
  47526. */
  47527. public function hasExpectationOnOutput()
  47528. {
  47529. return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex);
  47530. }
  47531. /**
  47532. * @return string
  47533. * @since Method available since Release 3.2.0
  47534. */
  47535. public function getExpectedException()
  47536. {
  47537. return $this->expectedException;
  47538. }
  47539. /**
  47540. * @param mixed $exceptionName
  47541. * @param string $exceptionMessage
  47542. * @param integer $exceptionCode
  47543. * @since Method available since Release 3.2.0
  47544. */
  47545. public function setExpectedException($exceptionName, $exceptionMessage = '', $exceptionCode = null)
  47546. {
  47547. $this->expectedException = $exceptionName;
  47548. $this->expectedExceptionMessage = $exceptionMessage;
  47549. $this->expectedExceptionCode = $exceptionCode;
  47550. }
  47551. /**
  47552. * @param mixed $exceptionName
  47553. * @param string $exceptionMessageRegExp
  47554. * @param integer $exceptionCode
  47555. * @since Method available since Release 4.3.0
  47556. */
  47557. public function setExpectedExceptionRegExp($exceptionName, $exceptionMessageRegExp = '', $exceptionCode = null)
  47558. {
  47559. $this->expectedException = $exceptionName;
  47560. $this->expectedExceptionMessageRegExp = $exceptionMessageRegExp;
  47561. $this->expectedExceptionCode = $exceptionCode;
  47562. }
  47563. /**
  47564. * @since Method available since Release 3.4.0
  47565. */
  47566. protected function setExpectedExceptionFromAnnotation()
  47567. {
  47568. try {
  47569. $expectedException = PHPUnit_Util_Test::getExpectedException(
  47570. get_class($this),
  47571. $this->name
  47572. );
  47573. if ($expectedException !== false) {
  47574. $this->setExpectedException(
  47575. $expectedException['class'],
  47576. $expectedException['message'],
  47577. $expectedException['code']
  47578. );
  47579. if (!empty($expectedException['message_regex'])) {
  47580. $this->setExpectedExceptionRegExp(
  47581. $expectedException['class'],
  47582. $expectedException['message_regex'],
  47583. $expectedException['code']
  47584. );
  47585. }
  47586. }
  47587. } catch (ReflectionException $e) {
  47588. }
  47589. }
  47590. /**
  47591. * @param boolean $useErrorHandler
  47592. * @since Method available since Release 3.4.0
  47593. */
  47594. public function setUseErrorHandler($useErrorHandler)
  47595. {
  47596. $this->useErrorHandler = $useErrorHandler;
  47597. }
  47598. /**
  47599. * @since Method available since Release 3.4.0
  47600. */
  47601. protected function setUseErrorHandlerFromAnnotation()
  47602. {
  47603. try {
  47604. $useErrorHandler = PHPUnit_Util_Test::getErrorHandlerSettings(
  47605. get_class($this),
  47606. $this->name
  47607. );
  47608. if ($useErrorHandler !== null) {
  47609. $this->setUseErrorHandler($useErrorHandler);
  47610. }
  47611. } catch (ReflectionException $e) {
  47612. }
  47613. }
  47614. /**
  47615. * @since Method available since Release 3.6.0
  47616. */
  47617. protected function checkRequirements()
  47618. {
  47619. if (!$this->name || !method_exists($this, $this->name)) {
  47620. return;
  47621. }
  47622. $missingRequirements = PHPUnit_Util_Test::getMissingRequirements(
  47623. get_class($this),
  47624. $this->name
  47625. );
  47626. if ($missingRequirements) {
  47627. $this->markTestSkipped(implode(PHP_EOL, $missingRequirements));
  47628. }
  47629. }
  47630. /**
  47631. * Returns the status of this test.
  47632. *
  47633. * @return integer
  47634. * @since Method available since Release 3.1.0
  47635. */
  47636. public function getStatus()
  47637. {
  47638. return $this->status;
  47639. }
  47640. /**
  47641. * Returns the status message of this test.
  47642. *
  47643. * @return string
  47644. * @since Method available since Release 3.3.0
  47645. */
  47646. public function getStatusMessage()
  47647. {
  47648. return $this->statusMessage;
  47649. }
  47650. /**
  47651. * Returns whether or not this test has failed.
  47652. *
  47653. * @return boolean
  47654. * @since Method available since Release 3.0.0
  47655. */
  47656. public function hasFailed()
  47657. {
  47658. $status = $this->getStatus();
  47659. return $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE ||
  47660. $status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
  47661. }
  47662. /**
  47663. * Runs the test case and collects the results in a TestResult object.
  47664. * If no TestResult object is passed a new one will be created.
  47665. *
  47666. * @param PHPUnit_Framework_TestResult $result
  47667. * @return PHPUnit_Framework_TestResult
  47668. * @throws PHPUnit_Framework_Exception
  47669. */
  47670. public function run(PHPUnit_Framework_TestResult $result = null)
  47671. {
  47672. if ($result === null) {
  47673. $result = $this->createResult();
  47674. }
  47675. if (!$this instanceof PHPUnit_Framework_Warning) {
  47676. $this->setTestResultObject($result);
  47677. $this->setUseErrorHandlerFromAnnotation();
  47678. }
  47679. if ($this->useErrorHandler !== null) {
  47680. $oldErrorHandlerSetting = $result->getConvertErrorsToExceptions();
  47681. $result->convertErrorsToExceptions($this->useErrorHandler);
  47682. }
  47683. if (!$this instanceof PHPUnit_Framework_Warning && !$this->handleDependencies()) {
  47684. return;
  47685. }
  47686. if ($this->runTestInSeparateProcess === true &&
  47687. $this->inIsolation !== true &&
  47688. !$this instanceof PHPUnit_Extensions_SeleniumTestCase &&
  47689. !$this instanceof PHPUnit_Extensions_PhptTestCase) {
  47690. $class = new ReflectionClass($this);
  47691. $template = new Text_Template(
  47692. __DIR__ . '/../Util/PHP/Template/TestCaseMethod.tpl'
  47693. );
  47694. if ($this->preserveGlobalState) {
  47695. $constants = PHPUnit_Util_GlobalState::getConstantsAsString();
  47696. $globals = PHPUnit_Util_GlobalState::getGlobalsAsString();
  47697. $includedFiles = PHPUnit_Util_GlobalState::getIncludedFilesAsString();
  47698. $iniSettings = PHPUnit_Util_GlobalState::getIniSettingsAsString();
  47699. } else {
  47700. $constants = '';
  47701. if (!empty($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
  47702. $globals = '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = ' . var_export($GLOBALS['__PHPUNIT_BOOTSTRAP'], true) . ";\n";
  47703. } else {
  47704. $globals = '';
  47705. }
  47706. $includedFiles = '';
  47707. $iniSettings = '';
  47708. }
  47709. $coverage = $result->getCollectCodeCoverageInformation() ? 'true' : 'false';
  47710. $isStrictAboutTestsThatDoNotTestAnything = $result->isStrictAboutTestsThatDoNotTestAnything() ? 'true' : 'false';
  47711. $isStrictAboutOutputDuringTests = $result->isStrictAboutOutputDuringTests() ? 'true' : 'false';
  47712. $isStrictAboutTestSize = $result->isStrictAboutTestSize() ? 'true' : 'false';
  47713. $isStrictAboutTodoAnnotatedTests = $result->isStrictAboutTodoAnnotatedTests() ? 'true' : 'false';
  47714. if (defined('PHPUNIT_COMPOSER_INSTALL')) {
  47715. $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, true);
  47716. } else {
  47717. $composerAutoload = '\'\'';
  47718. }
  47719. if (defined('__PHPUNIT_PHAR__')) {
  47720. $phar = var_export(__PHPUNIT_PHAR__, true);
  47721. } else {
  47722. $phar = '\'\'';
  47723. }
  47724. $data = var_export(serialize($this->data), true);
  47725. $dataName = var_export($this->dataName, true);
  47726. $dependencyInput = var_export(serialize($this->dependencyInput), true);
  47727. $includePath = var_export(get_include_path(), true);
  47728. // must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC
  47729. // the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences
  47730. $data = "'." . $data . ".'";
  47731. $dataName = "'.(" . $dataName . ").'";
  47732. $dependencyInput = "'." . $dependencyInput . ".'";
  47733. $includePath = "'." . $includePath . ".'";
  47734. $template->setVar(
  47735. array(
  47736. 'composerAutoload' => $composerAutoload,
  47737. 'phar' => $phar,
  47738. 'filename' => $class->getFileName(),
  47739. 'className' => $class->getName(),
  47740. 'methodName' => $this->name,
  47741. 'collectCodeCoverageInformation' => $coverage,
  47742. 'data' => $data,
  47743. 'dataName' => $dataName,
  47744. 'dependencyInput' => $dependencyInput,
  47745. 'constants' => $constants,
  47746. 'globals' => $globals,
  47747. 'include_path' => $includePath,
  47748. 'included_files' => $includedFiles,
  47749. 'iniSettings' => $iniSettings,
  47750. 'isStrictAboutTestsThatDoNotTestAnything' => $isStrictAboutTestsThatDoNotTestAnything,
  47751. 'isStrictAboutOutputDuringTests' => $isStrictAboutOutputDuringTests,
  47752. 'isStrictAboutTestSize' => $isStrictAboutTestSize,
  47753. 'isStrictAboutTodoAnnotatedTests' => $isStrictAboutTodoAnnotatedTests
  47754. )
  47755. );
  47756. $this->prepareTemplate($template);
  47757. $php = PHPUnit_Util_PHP::factory();
  47758. $php->runTestJob($template->render(), $this, $result);
  47759. } else {
  47760. $result->run($this);
  47761. }
  47762. if ($this->useErrorHandler !== null) {
  47763. $result->convertErrorsToExceptions($oldErrorHandlerSetting);
  47764. }
  47765. $this->result = null;
  47766. return $result;
  47767. }
  47768. /**
  47769. * Runs the bare test sequence.
  47770. */
  47771. public function runBare()
  47772. {
  47773. $this->numAssertions = 0;
  47774. $this->snapshotGlobalState();
  47775. $this->startOutputBuffering();
  47776. clearstatcache();
  47777. $currentWorkingDirectory = getcwd();
  47778. $hookMethods = PHPUnit_Util_Test::getHookMethods(get_class($this));
  47779. try {
  47780. $hasMetRequirements = false;
  47781. $this->checkRequirements();
  47782. $hasMetRequirements = true;
  47783. if ($this->inIsolation) {
  47784. foreach ($hookMethods['beforeClass'] as $method) {
  47785. $this->$method();
  47786. }
  47787. }
  47788. $this->setExpectedExceptionFromAnnotation();
  47789. foreach ($hookMethods['before'] as $method) {
  47790. $this->$method();
  47791. }
  47792. $this->assertPreConditions();
  47793. $this->testResult = $this->runTest();
  47794. $this->verifyMockObjects();
  47795. $this->assertPostConditions();
  47796. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED;
  47797. } catch (PHPUnit_Framework_IncompleteTest $e) {
  47798. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE;
  47799. $this->statusMessage = $e->getMessage();
  47800. } catch (PHPUnit_Framework_SkippedTest $e) {
  47801. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED;
  47802. $this->statusMessage = $e->getMessage();
  47803. } catch (PHPUnit_Framework_AssertionFailedError $e) {
  47804. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
  47805. $this->statusMessage = $e->getMessage();
  47806. } catch (PredictionException $e) {
  47807. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
  47808. $this->statusMessage = $e->getMessage();
  47809. } catch (Exception $e) {
  47810. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
  47811. $this->statusMessage = $e->getMessage();
  47812. }
  47813. // Clean up the mock objects.
  47814. $this->mockObjects = array();
  47815. $this->prophet = null;
  47816. // Tear down the fixture. An exception raised in tearDown() will be
  47817. // caught and passed on when no exception was raised before.
  47818. try {
  47819. if ($hasMetRequirements) {
  47820. foreach ($hookMethods['after'] as $method) {
  47821. $this->$method();
  47822. }
  47823. if ($this->inIsolation) {
  47824. foreach ($hookMethods['afterClass'] as $method) {
  47825. $this->$method();
  47826. }
  47827. }
  47828. }
  47829. } catch (Exception $_e) {
  47830. if (!isset($e)) {
  47831. $e = $_e;
  47832. }
  47833. }
  47834. try {
  47835. $this->stopOutputBuffering();
  47836. } catch (PHPUnit_Framework_RiskyTestError $_e) {
  47837. if (!isset($e)) {
  47838. $e = $_e;
  47839. }
  47840. }
  47841. clearstatcache();
  47842. if ($currentWorkingDirectory != getcwd()) {
  47843. chdir($currentWorkingDirectory);
  47844. }
  47845. $this->restoreGlobalState();
  47846. // Clean up INI settings.
  47847. foreach ($this->iniSettings as $varName => $oldValue) {
  47848. ini_set($varName, $oldValue);
  47849. }
  47850. $this->iniSettings = array();
  47851. // Clean up locale settings.
  47852. foreach ($this->locale as $category => $locale) {
  47853. setlocale($category, $locale);
  47854. }
  47855. // Perform assertion on output.
  47856. if (!isset($e)) {
  47857. try {
  47858. if ($this->outputExpectedRegex !== null) {
  47859. $this->assertRegExp($this->outputExpectedRegex, $this->output);
  47860. } elseif ($this->outputExpectedString !== null) {
  47861. $this->assertEquals($this->outputExpectedString, $this->output);
  47862. }
  47863. } catch (Exception $_e) {
  47864. $e = $_e;
  47865. }
  47866. }
  47867. // Workaround for missing "finally".
  47868. if (isset($e)) {
  47869. if ($e instanceof PredictionException) {
  47870. $e = new PHPUnit_Framework_AssertionFailedError($e->getMessage());
  47871. }
  47872. $this->onNotSuccessfulTest($e);
  47873. }
  47874. }
  47875. /**
  47876. * Override to run the test and assert its state.
  47877. *
  47878. * @return mixed
  47879. * @throws Exception|PHPUnit_Framework_Exception
  47880. * @throws PHPUnit_Framework_Exception
  47881. */
  47882. protected function runTest()
  47883. {
  47884. if ($this->name === null) {
  47885. throw new PHPUnit_Framework_Exception(
  47886. 'PHPUnit_Framework_TestCase::$name must not be null.'
  47887. );
  47888. }
  47889. try {
  47890. $class = new ReflectionClass($this);
  47891. $method = $class->getMethod($this->name);
  47892. } catch (ReflectionException $e) {
  47893. $this->fail($e->getMessage());
  47894. }
  47895. try {
  47896. $testResult = $method->invokeArgs(
  47897. $this,
  47898. array_merge($this->data, $this->dependencyInput)
  47899. );
  47900. } catch (Exception $e) {
  47901. $checkException = false;
  47902. if (is_string($this->expectedException)) {
  47903. $checkException = true;
  47904. if ($e instanceof PHPUnit_Framework_Exception) {
  47905. $checkException = false;
  47906. }
  47907. $reflector = new ReflectionClass($this->expectedException);
  47908. if ($this->expectedException == 'PHPUnit_Framework_Exception' ||
  47909. $reflector->isSubclassOf('PHPUnit_Framework_Exception')) {
  47910. $checkException = true;
  47911. }
  47912. }
  47913. if ($checkException) {
  47914. $this->assertThat(
  47915. $e,
  47916. new PHPUnit_Framework_Constraint_Exception(
  47917. $this->expectedException
  47918. )
  47919. );
  47920. if (is_string($this->expectedExceptionMessage) &&
  47921. !empty($this->expectedExceptionMessage)) {
  47922. $this->assertThat(
  47923. $e,
  47924. new PHPUnit_Framework_Constraint_ExceptionMessage(
  47925. $this->expectedExceptionMessage
  47926. )
  47927. );
  47928. }
  47929. if (is_string($this->expectedExceptionMessageRegExp) &&
  47930. !empty($this->expectedExceptionMessageRegExp)) {
  47931. $this->assertThat(
  47932. $e,
  47933. new PHPUnit_Framework_Constraint_ExceptionMessageRegExp(
  47934. $this->expectedExceptionMessageRegExp
  47935. )
  47936. );
  47937. }
  47938. if ($this->expectedExceptionCode !== null) {
  47939. $this->assertThat(
  47940. $e,
  47941. new PHPUnit_Framework_Constraint_ExceptionCode(
  47942. $this->expectedExceptionCode
  47943. )
  47944. );
  47945. }
  47946. return;
  47947. } else {
  47948. throw $e;
  47949. }
  47950. }
  47951. if ($this->expectedException !== null) {
  47952. $this->assertThat(
  47953. null,
  47954. new PHPUnit_Framework_Constraint_Exception(
  47955. $this->expectedException
  47956. )
  47957. );
  47958. }
  47959. return $testResult;
  47960. }
  47961. /**
  47962. * Verifies the mock object expectations.
  47963. *
  47964. * @since Method available since Release 3.5.0
  47965. */
  47966. protected function verifyMockObjects()
  47967. {
  47968. foreach ($this->mockObjects as $mockObject) {
  47969. if ($mockObject->__phpunit_hasMatchers()) {
  47970. $this->numAssertions++;
  47971. }
  47972. $mockObject->__phpunit_verify();
  47973. }
  47974. if ($this->prophet !== null) {
  47975. try {
  47976. $this->prophet->checkPredictions();
  47977. } catch (Exception $e) {
  47978. /** Intentionally left empty */
  47979. }
  47980. foreach ($this->prophet->getProphecies() as $objectProphecy) {
  47981. foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) {
  47982. foreach ($methodProphecies as $methodProphecy) {
  47983. $this->numAssertions += count($methodProphecy->getCheckedPredictions());
  47984. }
  47985. }
  47986. }
  47987. if (isset($e)) {
  47988. throw $e;
  47989. }
  47990. }
  47991. }
  47992. /**
  47993. * Sets the name of a TestCase.
  47994. *
  47995. * @param string
  47996. */
  47997. public function setName($name)
  47998. {
  47999. $this->name = $name;
  48000. }
  48001. /**
  48002. * Sets the dependencies of a TestCase.
  48003. *
  48004. * @param array $dependencies
  48005. * @since Method available since Release 3.4.0
  48006. */
  48007. public function setDependencies(array $dependencies)
  48008. {
  48009. $this->dependencies = $dependencies;
  48010. }
  48011. /**
  48012. * Returns true if the tests has dependencies
  48013. *
  48014. * @return boolean
  48015. * @since Method available since Release 4.0.0
  48016. */
  48017. public function hasDependencies()
  48018. {
  48019. return count($this->dependencies) > 0;
  48020. }
  48021. /**
  48022. * Sets
  48023. *
  48024. * @param array $dependencyInput
  48025. * @since Method available since Release 3.4.0
  48026. */
  48027. public function setDependencyInput(array $dependencyInput)
  48028. {
  48029. $this->dependencyInput = $dependencyInput;
  48030. }
  48031. /**
  48032. * @param boolean $disallowChangesToGlobalState
  48033. * @since Method available since Release 4.6.0
  48034. */
  48035. public function setDisallowChangesToGlobalState($disallowChangesToGlobalState)
  48036. {
  48037. $this->disallowChangesToGlobalState = $disallowChangesToGlobalState;
  48038. }
  48039. /**
  48040. * Calling this method in setUp() has no effect!
  48041. *
  48042. * @param boolean $backupGlobals
  48043. * @since Method available since Release 3.3.0
  48044. */
  48045. public function setBackupGlobals($backupGlobals)
  48046. {
  48047. if (is_null($this->backupGlobals) && is_bool($backupGlobals)) {
  48048. $this->backupGlobals = $backupGlobals;
  48049. }
  48050. }
  48051. /**
  48052. * Calling this method in setUp() has no effect!
  48053. *
  48054. * @param boolean $backupStaticAttributes
  48055. * @since Method available since Release 3.4.0
  48056. */
  48057. public function setBackupStaticAttributes($backupStaticAttributes)
  48058. {
  48059. if (is_null($this->backupStaticAttributes) &&
  48060. is_bool($backupStaticAttributes)) {
  48061. $this->backupStaticAttributes = $backupStaticAttributes;
  48062. }
  48063. }
  48064. /**
  48065. * @param boolean $runTestInSeparateProcess
  48066. * @throws PHPUnit_Framework_Exception
  48067. * @since Method available since Release 3.4.0
  48068. */
  48069. public function setRunTestInSeparateProcess($runTestInSeparateProcess)
  48070. {
  48071. if (is_bool($runTestInSeparateProcess)) {
  48072. if ($this->runTestInSeparateProcess === null) {
  48073. $this->runTestInSeparateProcess = $runTestInSeparateProcess;
  48074. }
  48075. } else {
  48076. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  48077. }
  48078. }
  48079. /**
  48080. * @param boolean $preserveGlobalState
  48081. * @throws PHPUnit_Framework_Exception
  48082. * @since Method available since Release 3.4.0
  48083. */
  48084. public function setPreserveGlobalState($preserveGlobalState)
  48085. {
  48086. if (is_bool($preserveGlobalState)) {
  48087. $this->preserveGlobalState = $preserveGlobalState;
  48088. } else {
  48089. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  48090. }
  48091. }
  48092. /**
  48093. * @param boolean $inIsolation
  48094. * @throws PHPUnit_Framework_Exception
  48095. * @since Method available since Release 3.4.0
  48096. */
  48097. public function setInIsolation($inIsolation)
  48098. {
  48099. if (is_bool($inIsolation)) {
  48100. $this->inIsolation = $inIsolation;
  48101. } else {
  48102. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  48103. }
  48104. }
  48105. /**
  48106. * @return boolean
  48107. * @since Method available since Release 4.3.0
  48108. */
  48109. public function isInIsolation()
  48110. {
  48111. return $this->inIsolation;
  48112. }
  48113. /**
  48114. * @return mixed
  48115. * @since Method available since Release 3.4.0
  48116. */
  48117. public function getResult()
  48118. {
  48119. return $this->testResult;
  48120. }
  48121. /**
  48122. * @param mixed $result
  48123. * @since Method available since Release 3.4.0
  48124. */
  48125. public function setResult($result)
  48126. {
  48127. $this->testResult = $result;
  48128. }
  48129. /**
  48130. * @param callable $callback
  48131. * @throws PHPUnit_Framework_Exception
  48132. * @since Method available since Release 3.6.0
  48133. */
  48134. public function setOutputCallback($callback)
  48135. {
  48136. if (!is_callable($callback)) {
  48137. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'callback');
  48138. }
  48139. $this->outputCallback = $callback;
  48140. }
  48141. /**
  48142. * @return PHPUnit_Framework_TestResult
  48143. * @since Method available since Release 3.5.7
  48144. */
  48145. public function getTestResultObject()
  48146. {
  48147. return $this->result;
  48148. }
  48149. /**
  48150. * @param PHPUnit_Framework_TestResult $result
  48151. * @since Method available since Release 3.6.0
  48152. */
  48153. public function setTestResultObject(PHPUnit_Framework_TestResult $result)
  48154. {
  48155. $this->result = $result;
  48156. }
  48157. /**
  48158. * This method is a wrapper for the ini_set() function that automatically
  48159. * resets the modified php.ini setting to its original value after the
  48160. * test is run.
  48161. *
  48162. * @param string $varName
  48163. * @param string $newValue
  48164. * @throws PHPUnit_Framework_Exception
  48165. * @since Method available since Release 3.0.0
  48166. */
  48167. protected function iniSet($varName, $newValue)
  48168. {
  48169. if (!is_string($varName)) {
  48170. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  48171. }
  48172. $currentValue = ini_set($varName, $newValue);
  48173. if ($currentValue !== false) {
  48174. $this->iniSettings[$varName] = $currentValue;
  48175. } else {
  48176. throw new PHPUnit_Framework_Exception(
  48177. sprintf(
  48178. 'INI setting "%s" could not be set to "%s".',
  48179. $varName,
  48180. $newValue
  48181. )
  48182. );
  48183. }
  48184. }
  48185. /**
  48186. * This method is a wrapper for the setlocale() function that automatically
  48187. * resets the locale to its original value after the test is run.
  48188. *
  48189. * @param integer $category
  48190. * @param string $locale
  48191. * @throws PHPUnit_Framework_Exception
  48192. * @since Method available since Release 3.1.0
  48193. */
  48194. protected function setLocale()
  48195. {
  48196. $args = func_get_args();
  48197. if (count($args) < 2) {
  48198. throw new PHPUnit_Framework_Exception;
  48199. }
  48200. $category = $args[0];
  48201. $locale = $args[1];
  48202. $categories = array(
  48203. LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME
  48204. );
  48205. if (defined('LC_MESSAGES')) {
  48206. $categories[] = LC_MESSAGES;
  48207. }
  48208. if (!in_array($category, $categories)) {
  48209. throw new PHPUnit_Framework_Exception;
  48210. }
  48211. if (!is_array($locale) && !is_string($locale)) {
  48212. throw new PHPUnit_Framework_Exception;
  48213. }
  48214. $this->locale[$category] = setlocale($category, null);
  48215. $result = call_user_func_array('setlocale', $args);
  48216. if ($result === false) {
  48217. throw new PHPUnit_Framework_Exception(
  48218. 'The locale functionality is not implemented on your platform, ' .
  48219. 'the specified locale does not exist or the category name is ' .
  48220. 'invalid.'
  48221. );
  48222. }
  48223. }
  48224. /**
  48225. * Returns a mock object for the specified class.
  48226. *
  48227. * @param string $originalClassName Name of the class to mock.
  48228. * @param array|null $methods When provided, only methods whose names are in the array
  48229. * are replaced with a configurable test double. The behavior
  48230. * of the other methods is not changed.
  48231. * Providing null means that no methods will be replaced.
  48232. * @param array $arguments Parameters to pass to the original class' constructor.
  48233. * @param string $mockClassName Class name for the generated test double class.
  48234. * @param boolean $callOriginalConstructor Can be used to disable the call to the original class' constructor.
  48235. * @param boolean $callOriginalClone Can be used to disable the call to the original class' clone constructor.
  48236. * @param boolean $callAutoload Can be used to disable __autoload() during the generation of the test double class.
  48237. * @param boolean $cloneArguments
  48238. * @param boolean $callOriginalMethods
  48239. * @return PHPUnit_Framework_MockObject_MockObject
  48240. * @throws PHPUnit_Framework_Exception
  48241. * @since Method available since Release 3.0.0
  48242. */
  48243. public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false, $callOriginalMethods = false)
  48244. {
  48245. $mockObject = $this->getMockObjectGenerator()->getMock(
  48246. $originalClassName,
  48247. $methods,
  48248. $arguments,
  48249. $mockClassName,
  48250. $callOriginalConstructor,
  48251. $callOriginalClone,
  48252. $callAutoload,
  48253. $cloneArguments,
  48254. $callOriginalMethods
  48255. );
  48256. $this->mockObjects[] = $mockObject;
  48257. return $mockObject;
  48258. }
  48259. /**
  48260. * Returns a builder object to create mock objects using a fluent interface.
  48261. *
  48262. * @param string $className
  48263. * @return PHPUnit_Framework_MockObject_MockBuilder
  48264. * @since Method available since Release 3.5.0
  48265. */
  48266. public function getMockBuilder($className)
  48267. {
  48268. return new PHPUnit_Framework_MockObject_MockBuilder($this, $className);
  48269. }
  48270. /**
  48271. * Mocks the specified class and returns the name of the mocked class.
  48272. *
  48273. * @param string $originalClassName
  48274. * @param array $methods
  48275. * @param array $arguments
  48276. * @param string $mockClassName
  48277. * @param boolean $callOriginalConstructor
  48278. * @param boolean $callOriginalClone
  48279. * @param boolean $callAutoload
  48280. * @param boolean $cloneArguments
  48281. * @return string
  48282. * @throws PHPUnit_Framework_Exception
  48283. * @since Method available since Release 3.5.0
  48284. */
  48285. protected function getMockClass($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = false, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false)
  48286. {
  48287. $mock = $this->getMock(
  48288. $originalClassName,
  48289. $methods,
  48290. $arguments,
  48291. $mockClassName,
  48292. $callOriginalConstructor,
  48293. $callOriginalClone,
  48294. $callAutoload,
  48295. $cloneArguments
  48296. );
  48297. return get_class($mock);
  48298. }
  48299. /**
  48300. * Returns a mock object for the specified abstract class with all abstract
  48301. * methods of the class mocked. Concrete methods are not mocked by default.
  48302. * To mock concrete methods, use the 7th parameter ($mockedMethods).
  48303. *
  48304. * @param string $originalClassName
  48305. * @param array $arguments
  48306. * @param string $mockClassName
  48307. * @param boolean $callOriginalConstructor
  48308. * @param boolean $callOriginalClone
  48309. * @param boolean $callAutoload
  48310. * @param array $mockedMethods
  48311. * @param boolean $cloneArguments
  48312. * @return PHPUnit_Framework_MockObject_MockObject
  48313. * @since Method available since Release 3.4.0
  48314. * @throws PHPUnit_Framework_Exception
  48315. */
  48316. public function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = false)
  48317. {
  48318. $mockObject = $this->getMockObjectGenerator()->getMockForAbstractClass(
  48319. $originalClassName,
  48320. $arguments,
  48321. $mockClassName,
  48322. $callOriginalConstructor,
  48323. $callOriginalClone,
  48324. $callAutoload,
  48325. $mockedMethods,
  48326. $cloneArguments
  48327. );
  48328. $this->mockObjects[] = $mockObject;
  48329. return $mockObject;
  48330. }
  48331. /**
  48332. * Returns a mock object based on the given WSDL file.
  48333. *
  48334. * @param string $wsdlFile
  48335. * @param string $originalClassName
  48336. * @param string $mockClassName
  48337. * @param array $methods
  48338. * @param boolean $callOriginalConstructor
  48339. * @param array $options An array of options passed to SOAPClient::_construct
  48340. * @return PHPUnit_Framework_MockObject_MockObject
  48341. * @since Method available since Release 3.4.0
  48342. */
  48343. protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = array(), $callOriginalConstructor = true, array $options = array())
  48344. {
  48345. if ($originalClassName === '') {
  48346. $originalClassName = str_replace('.wsdl', '', basename($wsdlFile));
  48347. }
  48348. if (!class_exists($originalClassName)) {
  48349. eval(
  48350. $this->getMockObjectGenerator()->generateClassFromWsdl(
  48351. $wsdlFile,
  48352. $originalClassName,
  48353. $methods,
  48354. $options
  48355. )
  48356. );
  48357. }
  48358. return $this->getMock(
  48359. $originalClassName,
  48360. $methods,
  48361. array('', $options),
  48362. $mockClassName,
  48363. $callOriginalConstructor,
  48364. false,
  48365. false
  48366. );
  48367. }
  48368. /**
  48369. * Returns a mock object for the specified trait with all abstract methods
  48370. * of the trait mocked. Concrete methods to mock can be specified with the
  48371. * `$mockedMethods` parameter.
  48372. *
  48373. * @param string $traitName
  48374. * @param array $arguments
  48375. * @param string $mockClassName
  48376. * @param boolean $callOriginalConstructor
  48377. * @param boolean $callOriginalClone
  48378. * @param boolean $callAutoload
  48379. * @param array $mockedMethods
  48380. * @param boolean $cloneArguments
  48381. * @return PHPUnit_Framework_MockObject_MockObject
  48382. * @since Method available since Release 4.0.0
  48383. * @throws PHPUnit_Framework_Exception
  48384. */
  48385. public function getMockForTrait($traitName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = false)
  48386. {
  48387. $mockObject = $this->getMockObjectGenerator()->getMockForTrait(
  48388. $traitName,
  48389. $arguments,
  48390. $mockClassName,
  48391. $callOriginalConstructor,
  48392. $callOriginalClone,
  48393. $callAutoload,
  48394. $mockedMethods,
  48395. $cloneArguments
  48396. );
  48397. $this->mockObjects[] = $mockObject;
  48398. return $mockObject;
  48399. }
  48400. /**
  48401. * Returns an object for the specified trait.
  48402. *
  48403. * @param string $traitName
  48404. * @param array $arguments
  48405. * @param string $traitClassName
  48406. * @param boolean $callOriginalConstructor
  48407. * @param boolean $callOriginalClone
  48408. * @param boolean $callAutoload
  48409. * @param boolean $cloneArguments
  48410. * @return object
  48411. * @since Method available since Release 3.6.0
  48412. * @throws PHPUnit_Framework_Exception
  48413. */
  48414. protected function getObjectForTrait($traitName, array $arguments = array(), $traitClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false)
  48415. {
  48416. return $this->getMockObjectGenerator()->getObjectForTrait(
  48417. $traitName,
  48418. $arguments,
  48419. $traitClassName,
  48420. $callOriginalConstructor,
  48421. $callOriginalClone,
  48422. $callAutoload,
  48423. $cloneArguments
  48424. );
  48425. }
  48426. /**
  48427. * @param string|null $classOrInterface
  48428. * @return \Prophecy\Prophecy\ObjectProphecy
  48429. * @throws \LogicException
  48430. * @since Method available since Release 4.5.0
  48431. */
  48432. protected function prophesize($classOrInterface = null)
  48433. {
  48434. return $this->getProphet()->prophesize($classOrInterface);
  48435. }
  48436. /**
  48437. * Adds a value to the assertion counter.
  48438. *
  48439. * @param integer $count
  48440. * @since Method available since Release 3.3.3
  48441. */
  48442. public function addToAssertionCount($count)
  48443. {
  48444. $this->numAssertions += $count;
  48445. }
  48446. /**
  48447. * Returns the number of assertions performed by this test.
  48448. *
  48449. * @return integer
  48450. * @since Method available since Release 3.3.0
  48451. */
  48452. public function getNumAssertions()
  48453. {
  48454. return $this->numAssertions;
  48455. }
  48456. /**
  48457. * Returns a matcher that matches when the method is executed
  48458. * zero or more times.
  48459. *
  48460. * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount
  48461. * @since Method available since Release 3.0.0
  48462. */
  48463. public static function any()
  48464. {
  48465. return new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
  48466. }
  48467. /**
  48468. * Returns a matcher that matches when the method is never executed.
  48469. *
  48470. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  48471. * @since Method available since Release 3.0.0
  48472. */
  48473. public static function never()
  48474. {
  48475. return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(0);
  48476. }
  48477. /**
  48478. * Returns a matcher that matches when the method is executed
  48479. * at least N times.
  48480. *
  48481. * @param integer $requiredInvocations
  48482. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount
  48483. * @since Method available since Release 4.2.0
  48484. */
  48485. public static function atLeast($requiredInvocations)
  48486. {
  48487. return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount(
  48488. $requiredInvocations
  48489. );
  48490. }
  48491. /**
  48492. * Returns a matcher that matches when the method is executed at least once.
  48493. *
  48494. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce
  48495. * @since Method available since Release 3.0.0
  48496. */
  48497. public static function atLeastOnce()
  48498. {
  48499. return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce;
  48500. }
  48501. /**
  48502. * Returns a matcher that matches when the method is executed exactly once.
  48503. *
  48504. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  48505. * @since Method available since Release 3.0.0
  48506. */
  48507. public static function once()
  48508. {
  48509. return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(1);
  48510. }
  48511. /**
  48512. * Returns a matcher that matches when the method is executed
  48513. * exactly $count times.
  48514. *
  48515. * @param integer $count
  48516. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  48517. * @since Method available since Release 3.0.0
  48518. */
  48519. public static function exactly($count)
  48520. {
  48521. return new PHPUnit_Framework_MockObject_Matcher_InvokedCount($count);
  48522. }
  48523. /**
  48524. * Returns a matcher that matches when the method is executed
  48525. * at most N times.
  48526. *
  48527. * @param integer $allowedInvocations
  48528. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount
  48529. * @since Method available since Release 4.2.0
  48530. */
  48531. public static function atMost($allowedInvocations)
  48532. {
  48533. return new PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount(
  48534. $allowedInvocations
  48535. );
  48536. }
  48537. /**
  48538. * Returns a matcher that matches when the method is executed
  48539. * at the given index.
  48540. *
  48541. * @param integer $index
  48542. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex
  48543. * @since Method available since Release 3.0.0
  48544. */
  48545. public static function at($index)
  48546. {
  48547. return new PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex($index);
  48548. }
  48549. /**
  48550. *
  48551. *
  48552. * @param mixed $value
  48553. * @return PHPUnit_Framework_MockObject_Stub_Return
  48554. * @since Method available since Release 3.0.0
  48555. */
  48556. public static function returnValue($value)
  48557. {
  48558. return new PHPUnit_Framework_MockObject_Stub_Return($value);
  48559. }
  48560. /**
  48561. *
  48562. *
  48563. * @param array $valueMap
  48564. * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap
  48565. * @since Method available since Release 3.6.0
  48566. */
  48567. public static function returnValueMap(array $valueMap)
  48568. {
  48569. return new PHPUnit_Framework_MockObject_Stub_ReturnValueMap($valueMap);
  48570. }
  48571. /**
  48572. *
  48573. *
  48574. * @param integer $argumentIndex
  48575. * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument
  48576. * @since Method available since Release 3.3.0
  48577. */
  48578. public static function returnArgument($argumentIndex)
  48579. {
  48580. return new PHPUnit_Framework_MockObject_Stub_ReturnArgument(
  48581. $argumentIndex
  48582. );
  48583. }
  48584. /**
  48585. *
  48586. *
  48587. * @param mixed $callback
  48588. * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback
  48589. * @since Method available since Release 3.3.0
  48590. */
  48591. public static function returnCallback($callback)
  48592. {
  48593. return new PHPUnit_Framework_MockObject_Stub_ReturnCallback($callback);
  48594. }
  48595. /**
  48596. * Returns the current object.
  48597. *
  48598. * This method is useful when mocking a fluent interface.
  48599. *
  48600. * @return PHPUnit_Framework_MockObject_Stub_ReturnSelf
  48601. * @since Method available since Release 3.6.0
  48602. */
  48603. public static function returnSelf()
  48604. {
  48605. return new PHPUnit_Framework_MockObject_Stub_ReturnSelf();
  48606. }
  48607. /**
  48608. *
  48609. *
  48610. * @param Exception $exception
  48611. * @return PHPUnit_Framework_MockObject_Stub_Exception
  48612. * @since Method available since Release 3.1.0
  48613. */
  48614. public static function throwException(Exception $exception)
  48615. {
  48616. return new PHPUnit_Framework_MockObject_Stub_Exception($exception);
  48617. }
  48618. /**
  48619. * @param mixed $value, ...
  48620. * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls
  48621. * @since Method available since Release 3.0.0
  48622. */
  48623. public static function onConsecutiveCalls()
  48624. {
  48625. $args = func_get_args();
  48626. return new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args);
  48627. }
  48628. /**
  48629. * Gets the data set description of a TestCase.
  48630. *
  48631. * @param boolean $includeData
  48632. * @return string
  48633. * @since Method available since Release 3.3.0
  48634. */
  48635. protected function getDataSetAsString($includeData = true)
  48636. {
  48637. $buffer = '';
  48638. if (!empty($this->data)) {
  48639. if (is_int($this->dataName)) {
  48640. $buffer .= sprintf(' with data set #%d', $this->dataName);
  48641. } else {
  48642. $buffer .= sprintf(' with data set "%s"', $this->dataName);
  48643. }
  48644. $exporter = new Exporter;
  48645. if ($includeData) {
  48646. $buffer .= sprintf(' (%s)', $exporter->shortenedRecursiveExport($this->data));
  48647. }
  48648. }
  48649. return $buffer;
  48650. }
  48651. /**
  48652. * Creates a default TestResult object.
  48653. *
  48654. * @return PHPUnit_Framework_TestResult
  48655. */
  48656. protected function createResult()
  48657. {
  48658. return new PHPUnit_Framework_TestResult;
  48659. }
  48660. /**
  48661. * @since Method available since Release 3.5.4
  48662. */
  48663. protected function handleDependencies()
  48664. {
  48665. if (!empty($this->dependencies) && !$this->inIsolation) {
  48666. $className = get_class($this);
  48667. $passed = $this->result->passed();
  48668. $passedKeys = array_keys($passed);
  48669. $numKeys = count($passedKeys);
  48670. for ($i = 0; $i < $numKeys; $i++) {
  48671. $pos = strpos($passedKeys[$i], ' with data set');
  48672. if ($pos !== false) {
  48673. $passedKeys[$i] = substr($passedKeys[$i], 0, $pos);
  48674. }
  48675. }
  48676. $passedKeys = array_flip(array_unique($passedKeys));
  48677. foreach ($this->dependencies as $dependency) {
  48678. if (strpos($dependency, '::') === false) {
  48679. $dependency = $className . '::' . $dependency;
  48680. }
  48681. if (!isset($passedKeys[$dependency])) {
  48682. $this->result->addError(
  48683. $this,
  48684. new PHPUnit_Framework_SkippedTestError(
  48685. sprintf(
  48686. 'This test depends on "%s" to pass.',
  48687. $dependency
  48688. )
  48689. ),
  48690. 0
  48691. );
  48692. return false;
  48693. }
  48694. if (isset($passed[$dependency])) {
  48695. if ($passed[$dependency]['size'] != PHPUnit_Util_Test::UNKNOWN &&
  48696. $this->getSize() != PHPUnit_Util_Test::UNKNOWN &&
  48697. $passed[$dependency]['size'] > $this->getSize()) {
  48698. $this->result->addError(
  48699. $this,
  48700. new PHPUnit_Framework_SkippedTestError(
  48701. 'This test depends on a test that is larger than itself.'
  48702. ),
  48703. 0
  48704. );
  48705. return false;
  48706. }
  48707. $this->dependencyInput[$dependency] = $passed[$dependency]['result'];
  48708. } else {
  48709. $this->dependencyInput[$dependency] = null;
  48710. }
  48711. }
  48712. }
  48713. return true;
  48714. }
  48715. /**
  48716. * This method is called before the first test of this test class is run.
  48717. *
  48718. * @since Method available since Release 3.4.0
  48719. */
  48720. public static function setUpBeforeClass()
  48721. {
  48722. }
  48723. /**
  48724. * Sets up the fixture, for example, open a network connection.
  48725. * This method is called before a test is executed.
  48726. *
  48727. */
  48728. protected function setUp()
  48729. {
  48730. }
  48731. /**
  48732. * Performs assertions shared by all tests of a test case.
  48733. *
  48734. * This method is called before the execution of a test starts
  48735. * and after setUp() is called.
  48736. *
  48737. * @since Method available since Release 3.2.8
  48738. */
  48739. protected function assertPreConditions()
  48740. {
  48741. }
  48742. /**
  48743. * Performs assertions shared by all tests of a test case.
  48744. *
  48745. * This method is called before the execution of a test ends
  48746. * and before tearDown() is called.
  48747. *
  48748. * @since Method available since Release 3.2.8
  48749. */
  48750. protected function assertPostConditions()
  48751. {
  48752. }
  48753. /**
  48754. * Tears down the fixture, for example, close a network connection.
  48755. * This method is called after a test is executed.
  48756. */
  48757. protected function tearDown()
  48758. {
  48759. }
  48760. /**
  48761. * This method is called after the last test of this test class is run.
  48762. *
  48763. * @since Method available since Release 3.4.0
  48764. */
  48765. public static function tearDownAfterClass()
  48766. {
  48767. }
  48768. /**
  48769. * This method is called when a test method did not execute successfully.
  48770. *
  48771. * @param Exception $e
  48772. * @since Method available since Release 3.4.0
  48773. * @throws Exception
  48774. */
  48775. protected function onNotSuccessfulTest(Exception $e)
  48776. {
  48777. throw $e;
  48778. }
  48779. /**
  48780. * Performs custom preparations on the process isolation template.
  48781. *
  48782. * @param Text_Template $template
  48783. * @since Method available since Release 3.4.0
  48784. */
  48785. protected function prepareTemplate(Text_Template $template)
  48786. {
  48787. }
  48788. /**
  48789. * Get the mock object generator, creating it if it doesn't exist.
  48790. *
  48791. * @return PHPUnit_Framework_MockObject_Generator
  48792. */
  48793. protected function getMockObjectGenerator()
  48794. {
  48795. if (null === $this->mockObjectGenerator) {
  48796. $this->mockObjectGenerator = new PHPUnit_Framework_MockObject_Generator;
  48797. }
  48798. return $this->mockObjectGenerator;
  48799. }
  48800. /**
  48801. * @since Method available since Release 4.2.0
  48802. */
  48803. private function startOutputBuffering()
  48804. {
  48805. while (!defined('PHPUNIT_TESTSUITE') && ob_get_level() > 0) {
  48806. ob_end_clean();
  48807. }
  48808. ob_start();
  48809. $this->outputBufferingActive = true;
  48810. $this->outputBufferingLevel = ob_get_level();
  48811. }
  48812. /**
  48813. * @since Method available since Release 4.2.0
  48814. */
  48815. private function stopOutputBuffering()
  48816. {
  48817. if (ob_get_level() != $this->outputBufferingLevel) {
  48818. while (ob_get_level() > 0) {
  48819. ob_end_clean();
  48820. }
  48821. throw new PHPUnit_Framework_RiskyTestError(
  48822. 'Test code or tested code did not (only) close its own output buffers'
  48823. );
  48824. }
  48825. $output = ob_get_contents();
  48826. if ($this->outputCallback === false) {
  48827. $this->output = $output;
  48828. } else {
  48829. $this->output = call_user_func_array(
  48830. $this->outputCallback,
  48831. array($output)
  48832. );
  48833. }
  48834. ob_end_clean();
  48835. $this->outputBufferingActive = false;
  48836. $this->outputBufferingLevel = ob_get_level();
  48837. }
  48838. private function snapshotGlobalState()
  48839. {
  48840. $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
  48841. if ($this->runTestInSeparateProcess || $this->inIsolation ||
  48842. (!$backupGlobals && !$this->backupStaticAttributes)) {
  48843. return;
  48844. }
  48845. $this->snapshot = $this->createGlobalStateSnapshot($backupGlobals);
  48846. }
  48847. private function restoreGlobalState()
  48848. {
  48849. if (!$this->snapshot instanceof Snapshot) {
  48850. return;
  48851. }
  48852. $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
  48853. if ($this->disallowChangesToGlobalState) {
  48854. $this->compareGlobalStateSnapshots(
  48855. $this->snapshot,
  48856. $this->createGlobalStateSnapshot($backupGlobals)
  48857. );
  48858. }
  48859. $restorer = new Restorer;
  48860. if ($backupGlobals) {
  48861. $restorer->restoreGlobalVariables($this->snapshot);
  48862. }
  48863. if ($this->backupStaticAttributes) {
  48864. $restorer->restoreStaticAttributes($this->snapshot);
  48865. }
  48866. $this->snapshot = null;
  48867. }
  48868. /**
  48869. * @param boolean $backupGlobals
  48870. * @return Snapshot
  48871. */
  48872. private function createGlobalStateSnapshot($backupGlobals)
  48873. {
  48874. $blacklist = new Blacklist;
  48875. foreach ($this->backupGlobalsBlacklist as $globalVariable) {
  48876. $blacklist->addGlobalVariable($globalVariable);
  48877. }
  48878. if (!defined('PHPUNIT_TESTSUITE')) {
  48879. $blacklist->addClassNamePrefix('PHPUnit');
  48880. $blacklist->addClassNamePrefix('File_Iterator');
  48881. $blacklist->addClassNamePrefix('PHP_CodeCoverage');
  48882. $blacklist->addClassNamePrefix('PHP_Invoker');
  48883. $blacklist->addClassNamePrefix('PHP_Timer');
  48884. $blacklist->addClassNamePrefix('PHP_Token');
  48885. $blacklist->addClassNamePrefix('Symfony');
  48886. $blacklist->addClassNamePrefix('Text_Template');
  48887. $blacklist->addClassNamePrefix('Doctrine\Instantiator');
  48888. foreach ($this->backupStaticAttributesBlacklist as $class => $attributes) {
  48889. foreach ($attributes as $attribute) {
  48890. $blacklist->addStaticAttribute($class, $attribute);
  48891. }
  48892. }
  48893. }
  48894. return new Snapshot(
  48895. $blacklist,
  48896. $backupGlobals,
  48897. $this->backupStaticAttributes,
  48898. false,
  48899. false,
  48900. false,
  48901. false,
  48902. false,
  48903. false,
  48904. false
  48905. );
  48906. }
  48907. /**
  48908. * @param Snapshot $before
  48909. * @param Snapshot $after
  48910. * @throws PHPUnit_Framework_RiskyTestError
  48911. */
  48912. private function compareGlobalStateSnapshots(Snapshot $before, Snapshot $after)
  48913. {
  48914. $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
  48915. if ($backupGlobals) {
  48916. $this->compareGlobalStateSnapshotPart(
  48917. $before->globalVariables(),
  48918. $after->globalVariables(),
  48919. "--- Global variables before the test\n+++ Global variables after the test\n"
  48920. );
  48921. $this->compareGlobalStateSnapshotPart(
  48922. $before->superGlobalVariables(),
  48923. $after->superGlobalVariables(),
  48924. "--- Super-global variables before the test\n+++ Super-global variables after the test\n"
  48925. );
  48926. }
  48927. if ($this->backupStaticAttributes) {
  48928. $this->compareGlobalStateSnapshotPart(
  48929. $before->staticAttributes(),
  48930. $after->staticAttributes(),
  48931. "--- Static attributes before the test\n+++ Static attributes after the test\n"
  48932. );
  48933. }
  48934. }
  48935. /**
  48936. * @param array $before
  48937. * @param array $after
  48938. * @param string $header
  48939. * @throws PHPUnit_Framework_RiskyTestError
  48940. */
  48941. private function compareGlobalStateSnapshotPart(array $before, array $after, $header)
  48942. {
  48943. if ($before != $after) {
  48944. $differ = new Differ($header);
  48945. $exporter = new Exporter;
  48946. $diff = $differ->diff(
  48947. $exporter->export($before),
  48948. $exporter->export($after)
  48949. );
  48950. throw new PHPUnit_Framework_RiskyTestError(
  48951. $diff
  48952. );
  48953. }
  48954. }
  48955. /**
  48956. * @return Prophecy\Prophet
  48957. * @since Method available since Release 4.5.0
  48958. */
  48959. private function getProphet()
  48960. {
  48961. if ($this->prophet === null) {
  48962. $this->prophet = new Prophet;
  48963. }
  48964. return $this->prophet;
  48965. }
  48966. }
  48967. <?php
  48968. /*
  48969. * This file is part of PHPUnit.
  48970. *
  48971. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48972. *
  48973. * For the full copyright and license information, please view the LICENSE
  48974. * file that was distributed with this source code.
  48975. */
  48976. /**
  48977. * Exception for expectations which failed their check.
  48978. *
  48979. * The exception contains the error message and optionally a
  48980. * SebastianBergmann\Comparator\ComparisonFailure which is used to
  48981. * generate diff output of the failed expectations.
  48982. *
  48983. * @package PHPUnit
  48984. * @subpackage Framework
  48985. * @author Sebastian Bergmann <sebastian@phpunit.de>
  48986. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  48987. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  48988. * @link http://www.phpunit.de/
  48989. * @since Class available since Release 3.0.0
  48990. */
  48991. class PHPUnit_Framework_ExpectationFailedException extends PHPUnit_Framework_AssertionFailedError
  48992. {
  48993. /**
  48994. * @var SebastianBergmann\Comparator\ComparisonFailure
  48995. */
  48996. protected $comparisonFailure;
  48997. public function __construct($message, SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure = null, Exception $previous = null)
  48998. {
  48999. $this->comparisonFailure = $comparisonFailure;
  49000. parent::__construct($message, 0, $previous);
  49001. }
  49002. /**
  49003. * @return SebastianBergmann\Comparator\ComparisonFailure
  49004. */
  49005. public function getComparisonFailure()
  49006. {
  49007. return $this->comparisonFailure;
  49008. }
  49009. }
  49010. <?php
  49011. /*
  49012. * This file is part of PHPUnit.
  49013. *
  49014. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49015. *
  49016. * For the full copyright and license information, please view the LICENSE
  49017. * file that was distributed with this source code.
  49018. */
  49019. /**
  49020. * Wrapper for PHP errors.
  49021. *
  49022. * @package PHPUnit
  49023. * @subpackage Framework
  49024. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49025. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49026. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49027. * @link http://www.phpunit.de/
  49028. * @since Class available since Release 2.2.0
  49029. */
  49030. class PHPUnit_Framework_Error extends PHPUnit_Framework_Exception
  49031. {
  49032. /**
  49033. * Constructor.
  49034. *
  49035. * @param string $message
  49036. * @param integer $code
  49037. * @param string $file
  49038. * @param integer $line
  49039. * @param Exception $previous
  49040. */
  49041. public function __construct($message, $code, $file, $line, Exception $previous = null)
  49042. {
  49043. parent::__construct($message, $code, $previous);
  49044. $this->file = $file;
  49045. $this->line = $line;
  49046. }
  49047. }
  49048. <?php
  49049. /*
  49050. * This file is part of PHPUnit.
  49051. *
  49052. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49053. *
  49054. * For the full copyright and license information, please view the LICENSE
  49055. * file that was distributed with this source code.
  49056. */
  49057. use SebastianBergmann\Exporter\Exporter;
  49058. /**
  49059. * Abstract base class for constraints. which are placed upon any value.
  49060. *
  49061. * @package PHPUnit
  49062. * @subpackage Framework
  49063. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49064. * @author Bernhard Schussek <bschussek@2bepublished.at>
  49065. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49066. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49067. * @link http://www.phpunit.de/
  49068. * @since Interface available since Release 3.0.0
  49069. */
  49070. abstract class PHPUnit_Framework_Constraint implements Countable, PHPUnit_Framework_SelfDescribing
  49071. {
  49072. protected $exporter;
  49073. public function __construct()
  49074. {
  49075. $this->exporter = new Exporter;
  49076. }
  49077. /**
  49078. * Evaluates the constraint for parameter $other
  49079. *
  49080. * If $returnResult is set to false (the default), an exception is thrown
  49081. * in case of a failure. null is returned otherwise.
  49082. *
  49083. * If $returnResult is true, the result of the evaluation is returned as
  49084. * a boolean value instead: true in case of success, false in case of a
  49085. * failure.
  49086. *
  49087. * @param mixed $other Value or object to evaluate.
  49088. * @param string $description Additional information about the test
  49089. * @param bool $returnResult Whether to return a result or throw an exception
  49090. * @return mixed
  49091. * @throws PHPUnit_Framework_ExpectationFailedException
  49092. */
  49093. public function evaluate($other, $description = '', $returnResult = false)
  49094. {
  49095. $success = false;
  49096. if ($this->matches($other)) {
  49097. $success = true;
  49098. }
  49099. if ($returnResult) {
  49100. return $success;
  49101. }
  49102. if (!$success) {
  49103. $this->fail($other, $description);
  49104. }
  49105. }
  49106. /**
  49107. * Evaluates the constraint for parameter $other. Returns true if the
  49108. * constraint is met, false otherwise.
  49109. *
  49110. * This method can be overridden to implement the evaluation algorithm.
  49111. *
  49112. * @param mixed $other Value or object to evaluate.
  49113. * @return bool
  49114. */
  49115. protected function matches($other)
  49116. {
  49117. return false;
  49118. }
  49119. /**
  49120. * Counts the number of constraint elements.
  49121. *
  49122. * @return integer
  49123. * @since Method available since Release 3.4.0
  49124. */
  49125. public function count()
  49126. {
  49127. return 1;
  49128. }
  49129. /**
  49130. * Throws an exception for the given compared value and test description
  49131. *
  49132. * @param mixed $other Evaluated value or object.
  49133. * @param string $description Additional information about the test
  49134. * @param SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure
  49135. * @throws PHPUnit_Framework_ExpectationFailedException
  49136. */
  49137. protected function fail($other, $description, SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure = null)
  49138. {
  49139. $failureDescription = sprintf(
  49140. 'Failed asserting that %s.',
  49141. $this->failureDescription($other)
  49142. );
  49143. $additionalFailureDescription = $this->additionalFailureDescription($other);
  49144. if ($additionalFailureDescription) {
  49145. $failureDescription .= "\n" . $additionalFailureDescription;
  49146. }
  49147. if (!empty($description)) {
  49148. $failureDescription = $description . "\n" . $failureDescription;
  49149. }
  49150. throw new PHPUnit_Framework_ExpectationFailedException(
  49151. $failureDescription,
  49152. $comparisonFailure
  49153. );
  49154. }
  49155. /**
  49156. * Return additional failure description where needed
  49157. *
  49158. * The function can be overridden to provide additional failure
  49159. * information like a diff
  49160. *
  49161. * @param mixed $other Evaluated value or object.
  49162. * @return string
  49163. */
  49164. protected function additionalFailureDescription($other)
  49165. {
  49166. return '';
  49167. }
  49168. /**
  49169. * Returns the description of the failure
  49170. *
  49171. * The beginning of failure messages is "Failed asserting that" in most
  49172. * cases. This method should return the second part of that sentence.
  49173. *
  49174. * To provide additional failure information additionalFailureDescription
  49175. * can be used.
  49176. *
  49177. * @param mixed $other Evaluated value or object.
  49178. * @return string
  49179. */
  49180. protected function failureDescription($other)
  49181. {
  49182. return $this->exporter->export($other) . ' ' . $this->toString();
  49183. }
  49184. }
  49185. <?php
  49186. /*
  49187. * This file is part of PHPUnit.
  49188. *
  49189. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49190. *
  49191. * For the full copyright and license information, please view the LICENSE
  49192. * file that was distributed with this source code.
  49193. */
  49194. /**
  49195. * Thrown when an assertion failed.
  49196. *
  49197. * @package PHPUnit
  49198. * @subpackage Framework
  49199. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49200. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49201. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49202. * @link http://www.phpunit.de/
  49203. * @since Class available since Release 2.0.0
  49204. */
  49205. class PHPUnit_Framework_AssertionFailedError extends PHPUnit_Framework_Exception implements PHPUnit_Framework_SelfDescribing
  49206. {
  49207. /**
  49208. * Wrapper for getMessage() which is declared as final.
  49209. *
  49210. * @return string
  49211. */
  49212. public function toString()
  49213. {
  49214. return $this->getMessage();
  49215. }
  49216. }
  49217. <?php
  49218. /*
  49219. * This file is part of PHPUnit.
  49220. *
  49221. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49222. *
  49223. * For the full copyright and license information, please view the LICENSE
  49224. * file that was distributed with this source code.
  49225. */
  49226. /**
  49227. * An incomplete test case
  49228. *
  49229. * @package PHPUnit
  49230. * @subpackage Framework
  49231. * @author Davey Shafik <me@daveyshafik.com>
  49232. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49233. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49234. * @link http://www.phpunit.de/
  49235. * @since Class available since Release 4.3.0
  49236. */
  49237. class PHPUnit_Framework_IncompleteTestCase extends PHPUnit_Framework_TestCase
  49238. {
  49239. /**
  49240. * @var string
  49241. */
  49242. protected $message = '';
  49243. /**
  49244. * @var boolean
  49245. */
  49246. protected $backupGlobals = false;
  49247. /**
  49248. * @var boolean
  49249. */
  49250. protected $backupStaticAttributes = false;
  49251. /**
  49252. * @var boolean
  49253. */
  49254. protected $runTestInSeparateProcess = false;
  49255. /**
  49256. * @var boolean
  49257. */
  49258. protected $useErrorHandler = false;
  49259. /**
  49260. * @var boolean
  49261. */
  49262. protected $useOutputBuffering = false;
  49263. /**
  49264. * @param string $className
  49265. * @param string $methodName
  49266. * @param string $message
  49267. */
  49268. public function __construct($className, $methodName, $message = '')
  49269. {
  49270. $this->message = $message;
  49271. parent::__construct($className . '::' . $methodName);
  49272. }
  49273. /**
  49274. * @throws PHPUnit_Framework_Exception
  49275. */
  49276. protected function runTest()
  49277. {
  49278. $this->markTestIncomplete($this->message);
  49279. }
  49280. /**
  49281. * @return string
  49282. */
  49283. public function getMessage()
  49284. {
  49285. return $this->message;
  49286. }
  49287. /**
  49288. * Returns a string representation of the test case.
  49289. *
  49290. * @return string
  49291. */
  49292. public function toString()
  49293. {
  49294. return $this->getName();
  49295. }
  49296. }
  49297. <?php
  49298. /*
  49299. * This file is part of PHPUnit.
  49300. *
  49301. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49302. *
  49303. * For the full copyright and license information, please view the LICENSE
  49304. * file that was distributed with this source code.
  49305. */
  49306. /**
  49307. *
  49308. *
  49309. * @package PHPUnit
  49310. * @subpackage Framework_TestSuite
  49311. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49312. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49313. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49314. * @link http://www.phpunit.de/
  49315. * @since Class available since Release 3.4.0
  49316. */
  49317. class PHPUnit_Framework_TestSuite_DataProvider extends PHPUnit_Framework_TestSuite
  49318. {
  49319. /**
  49320. * Sets the dependencies of a TestCase.
  49321. *
  49322. * @param array $dependencies
  49323. */
  49324. public function setDependencies(array $dependencies)
  49325. {
  49326. foreach ($this->tests as $test) {
  49327. $test->setDependencies($dependencies);
  49328. }
  49329. }
  49330. }
  49331. <?php
  49332. /*
  49333. * This file is part of PHPUnit.
  49334. *
  49335. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49336. *
  49337. * For the full copyright and license information, please view the LICENSE
  49338. * file that was distributed with this source code.
  49339. */
  49340. /**
  49341. * Wrapper for PHP deprecated errors.
  49342. * You can disable deprecated-to-exception conversion by setting
  49343. *
  49344. * <code>
  49345. * PHPUnit_Framework_Error_Deprecated::$enabled = false;
  49346. * </code>
  49347. *
  49348. * @package PHPUnit
  49349. * @subpackage Framework_Error
  49350. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49351. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49352. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49353. * @link http://www.phpunit.de/
  49354. * @since Class available since Release 3.3.0
  49355. */
  49356. class PHPUnit_Framework_Error_Deprecated extends PHPUnit_Framework_Error
  49357. {
  49358. public static $enabled = true;
  49359. }
  49360. <?php
  49361. /*
  49362. * This file is part of PHPUnit.
  49363. *
  49364. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49365. *
  49366. * For the full copyright and license information, please view the LICENSE
  49367. * file that was distributed with this source code.
  49368. */
  49369. /**
  49370. * Wrapper for PHP notices.
  49371. * You can disable notice-to-exception conversion by setting
  49372. *
  49373. * <code>
  49374. * PHPUnit_Framework_Error_Notice::$enabled = false;
  49375. * </code>
  49376. *
  49377. * @package PHPUnit
  49378. * @subpackage Framework_Error
  49379. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49380. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49381. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49382. * @link http://www.phpunit.de/
  49383. * @since Class available since Release 3.3.0
  49384. */
  49385. class PHPUnit_Framework_Error_Notice extends PHPUnit_Framework_Error
  49386. {
  49387. public static $enabled = true;
  49388. }
  49389. <?php
  49390. /*
  49391. * This file is part of PHPUnit.
  49392. *
  49393. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49394. *
  49395. * For the full copyright and license information, please view the LICENSE
  49396. * file that was distributed with this source code.
  49397. */
  49398. /**
  49399. * Wrapper for PHP warnings.
  49400. * You can disable notice-to-exception conversion by setting
  49401. *
  49402. * <code>
  49403. * PHPUnit_Framework_Error_Warning::$enabled = false;
  49404. * </code>
  49405. *
  49406. * @package PHPUnit
  49407. * @subpackage Framework_Error
  49408. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49409. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49410. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49411. * @link http://www.phpunit.de/
  49412. * @since Class available since Release 3.3.0
  49413. */
  49414. class PHPUnit_Framework_Error_Warning extends PHPUnit_Framework_Error
  49415. {
  49416. public static $enabled = true;
  49417. }
  49418. <?php
  49419. /*
  49420. * This file is part of PHPUnit.
  49421. *
  49422. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49423. *
  49424. * For the full copyright and license information, please view the LICENSE
  49425. * file that was distributed with this source code.
  49426. */
  49427. /**
  49428. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  49429. * case of an incomplete test.
  49430. *
  49431. * @package PHPUnit
  49432. * @subpackage Framework
  49433. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49434. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49435. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49436. * @link http://www.phpunit.de/
  49437. * @since Class available since Release 2.0.0
  49438. */
  49439. class PHPUnit_Framework_IncompleteTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_IncompleteTest
  49440. {
  49441. }
  49442. <?php
  49443. /*
  49444. * This file is part of PHPUnit.
  49445. *
  49446. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49447. *
  49448. * For the full copyright and license information, please view the LICENSE
  49449. * file that was distributed with this source code.
  49450. */
  49451. /**
  49452. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  49453. * case of a test that is skipped because of an invalid @covers annotation.
  49454. *
  49455. * @package PHPUnit
  49456. * @subpackage Framework
  49457. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49458. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49459. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49460. * @link http://www.phpunit.de/
  49461. * @since Class available since Release 4.0.0
  49462. */
  49463. class PHPUnit_Framework_InvalidCoversTargetError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest
  49464. {
  49465. }
  49466. <?php
  49467. /*
  49468. * This file is part of PHPUnit.
  49469. *
  49470. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49471. *
  49472. * For the full copyright and license information, please view the LICENSE
  49473. * file that was distributed with this source code.
  49474. */
  49475. /**
  49476. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  49477. * case of a skipped test suite.
  49478. *
  49479. * @package PHPUnit
  49480. * @subpackage Framework
  49481. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49482. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49483. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49484. * @link http://www.phpunit.de/
  49485. * @since Class available since Release 3.1.0
  49486. */
  49487. class PHPUnit_Framework_SkippedTestSuiteError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest
  49488. {
  49489. }
  49490. <?php
  49491. /*
  49492. * This file is part of PHPUnit.
  49493. *
  49494. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49495. *
  49496. * For the full copyright and license information, please view the LICENSE
  49497. * file that was distributed with this source code.
  49498. */
  49499. /**
  49500. * A TestResult collects the results of executing a test case.
  49501. *
  49502. * @package PHPUnit
  49503. * @subpackage Framework
  49504. * @author Sebastian Bergmann <sebastian@phpunit.de>
  49505. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  49506. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  49507. * @link http://www.phpunit.de/
  49508. * @since Class available since Release 2.0.0
  49509. */
  49510. class PHPUnit_Framework_TestResult implements Countable
  49511. {
  49512. /**
  49513. * @var array
  49514. */
  49515. protected $passed = array();
  49516. /**
  49517. * @var array
  49518. */
  49519. protected $errors = array();
  49520. /**
  49521. * @var array
  49522. */
  49523. protected $failures = array();
  49524. /**
  49525. * @var array
  49526. */
  49527. protected $notImplemented = array();
  49528. /**
  49529. * @var array
  49530. */
  49531. protected $risky = array();
  49532. /**
  49533. * @var array
  49534. */
  49535. protected $skipped = array();
  49536. /**
  49537. * @var array
  49538. */
  49539. protected $listeners = array();
  49540. /**
  49541. * @var integer
  49542. */
  49543. protected $runTests = 0;
  49544. /**
  49545. * @var float
  49546. */
  49547. protected $time = 0;
  49548. /**
  49549. * @var PHPUnit_Framework_TestSuite
  49550. */
  49551. protected $topTestSuite = null;
  49552. /**
  49553. * Code Coverage information.
  49554. *
  49555. * @var PHP_CodeCoverage
  49556. */
  49557. protected $codeCoverage;
  49558. /**
  49559. * @var boolean
  49560. */
  49561. protected $convertErrorsToExceptions = true;
  49562. /**
  49563. * @var boolean
  49564. */
  49565. protected $stop = false;
  49566. /**
  49567. * @var boolean
  49568. */
  49569. protected $stopOnError = false;
  49570. /**
  49571. * @var boolean
  49572. */
  49573. protected $stopOnFailure = false;
  49574. /**
  49575. * @var boolean
  49576. */
  49577. protected $beStrictAboutTestsThatDoNotTestAnything = false;
  49578. /**
  49579. * @var boolean
  49580. */
  49581. protected $beStrictAboutOutputDuringTests = false;
  49582. /**
  49583. * @var boolean
  49584. */
  49585. protected $beStrictAboutTestSize = false;
  49586. /**
  49587. * @var boolean
  49588. */
  49589. protected $beStrictAboutTodoAnnotatedTests = false;
  49590. /**
  49591. * @var boolean
  49592. */
  49593. protected $stopOnRisky = false;
  49594. /**
  49595. * @var boolean
  49596. */
  49597. protected $stopOnIncomplete = false;
  49598. /**
  49599. * @var boolean
  49600. */
  49601. protected $stopOnSkipped = false;
  49602. /**
  49603. * @var boolean
  49604. */
  49605. protected $lastTestFailed = false;
  49606. /**
  49607. * @var integer
  49608. */
  49609. protected $timeoutForSmallTests = 1;
  49610. /**
  49611. * @var integer
  49612. */
  49613. protected $timeoutForMediumTests = 10;
  49614. /**
  49615. * @var integer
  49616. */
  49617. protected $timeoutForLargeTests = 60;
  49618. /**
  49619. * Registers a TestListener.
  49620. *
  49621. * @param PHPUnit_Framework_TestListener
  49622. */
  49623. public function addListener(PHPUnit_Framework_TestListener $listener)
  49624. {
  49625. $this->listeners[] = $listener;
  49626. }
  49627. /**
  49628. * Unregisters a TestListener.
  49629. *
  49630. * @param PHPUnit_Framework_TestListener $listener
  49631. */
  49632. public function removeListener(PHPUnit_Framework_TestListener $listener)
  49633. {
  49634. foreach ($this->listeners as $key => $_listener) {
  49635. if ($listener === $_listener) {
  49636. unset($this->listeners[$key]);
  49637. }
  49638. }
  49639. }
  49640. /**
  49641. * Flushes all flushable TestListeners.
  49642. *
  49643. * @since Method available since Release 3.0.0
  49644. */
  49645. public function flushListeners()
  49646. {
  49647. foreach ($this->listeners as $listener) {
  49648. if ($listener instanceof PHPUnit_Util_Printer) {
  49649. $listener->flush();
  49650. }
  49651. }
  49652. }
  49653. /**
  49654. * Adds an error to the list of errors.
  49655. *
  49656. * @param PHPUnit_Framework_Test $test
  49657. * @param Exception $e
  49658. * @param float $time
  49659. */
  49660. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  49661. {
  49662. if ($e instanceof PHPUnit_Framework_RiskyTest) {
  49663. $this->risky[] = new PHPUnit_Framework_TestFailure($test, $e);
  49664. $notifyMethod = 'addRiskyTest';
  49665. if ($this->stopOnRisky) {
  49666. $this->stop();
  49667. }
  49668. } elseif ($e instanceof PHPUnit_Framework_IncompleteTest) {
  49669. $this->notImplemented[] = new PHPUnit_Framework_TestFailure($test, $e);
  49670. $notifyMethod = 'addIncompleteTest';
  49671. if ($this->stopOnIncomplete) {
  49672. $this->stop();
  49673. }
  49674. } elseif ($e instanceof PHPUnit_Framework_SkippedTest) {
  49675. $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e);
  49676. $notifyMethod = 'addSkippedTest';
  49677. if ($this->stopOnSkipped) {
  49678. $this->stop();
  49679. }
  49680. } else {
  49681. $this->errors[] = new PHPUnit_Framework_TestFailure($test, $e);
  49682. $notifyMethod = 'addError';
  49683. if ($this->stopOnError || $this->stopOnFailure) {
  49684. $this->stop();
  49685. }
  49686. }
  49687. foreach ($this->listeners as $listener) {
  49688. $listener->$notifyMethod($test, $e, $time);
  49689. }
  49690. $this->lastTestFailed = true;
  49691. $this->time += $time;
  49692. }
  49693. /**
  49694. * Adds a failure to the list of failures.
  49695. * The passed in exception caused the failure.
  49696. *
  49697. * @param PHPUnit_Framework_Test $test
  49698. * @param PHPUnit_Framework_AssertionFailedError $e
  49699. * @param float $time
  49700. */
  49701. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  49702. {
  49703. if ($e instanceof PHPUnit_Framework_RiskyTest ||
  49704. $e instanceof PHPUnit_Framework_OutputError) {
  49705. $this->risky[] = new PHPUnit_Framework_TestFailure($test, $e);
  49706. $notifyMethod = 'addRiskyTest';
  49707. if ($this->stopOnRisky) {
  49708. $this->stop();
  49709. }
  49710. } elseif ($e instanceof PHPUnit_Framework_IncompleteTest) {
  49711. $this->notImplemented[] = new PHPUnit_Framework_TestFailure($test, $e);
  49712. $notifyMethod = 'addIncompleteTest';
  49713. if ($this->stopOnIncomplete) {
  49714. $this->stop();
  49715. }
  49716. } elseif ($e instanceof PHPUnit_Framework_SkippedTest) {
  49717. $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e);
  49718. $notifyMethod = 'addSkippedTest';
  49719. if ($this->stopOnSkipped) {
  49720. $this->stop();
  49721. }
  49722. } else {
  49723. $this->failures[] = new PHPUnit_Framework_TestFailure($test, $e);
  49724. $notifyMethod = 'addFailure';
  49725. if ($this->stopOnFailure) {
  49726. $this->stop();
  49727. }
  49728. }
  49729. foreach ($this->listeners as $listener) {
  49730. $listener->$notifyMethod($test, $e, $time);
  49731. }
  49732. $this->lastTestFailed = true;
  49733. $this->time += $time;
  49734. }
  49735. /**
  49736. * Informs the result that a testsuite will be started.
  49737. *
  49738. * @param PHPUnit_Framework_TestSuite $suite
  49739. * @since Method available since Release 2.2.0
  49740. */
  49741. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  49742. {
  49743. if ($this->topTestSuite === null) {
  49744. $this->topTestSuite = $suite;
  49745. }
  49746. foreach ($this->listeners as $listener) {
  49747. $listener->startTestSuite($suite);
  49748. }
  49749. }
  49750. /**
  49751. * Informs the result that a testsuite was completed.
  49752. *
  49753. * @param PHPUnit_Framework_TestSuite $suite
  49754. * @since Method available since Release 2.2.0
  49755. */
  49756. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  49757. {
  49758. foreach ($this->listeners as $listener) {
  49759. $listener->endTestSuite($suite);
  49760. }
  49761. }
  49762. /**
  49763. * Informs the result that a test will be started.
  49764. *
  49765. * @param PHPUnit_Framework_Test $test
  49766. */
  49767. public function startTest(PHPUnit_Framework_Test $test)
  49768. {
  49769. $this->lastTestFailed = false;
  49770. $this->runTests += count($test);
  49771. foreach ($this->listeners as $listener) {
  49772. $listener->startTest($test);
  49773. }
  49774. }
  49775. /**
  49776. * Informs the result that a test was completed.
  49777. *
  49778. * @param PHPUnit_Framework_Test $test
  49779. * @param float $time
  49780. */
  49781. public function endTest(PHPUnit_Framework_Test $test, $time)
  49782. {
  49783. foreach ($this->listeners as $listener) {
  49784. $listener->endTest($test, $time);
  49785. }
  49786. if (!$this->lastTestFailed && $test instanceof PHPUnit_Framework_TestCase) {
  49787. $class = get_class($test);
  49788. $key = $class . '::' . $test->getName();
  49789. $this->passed[$key] = array(
  49790. 'result' => $test->getResult(),
  49791. 'size' => PHPUnit_Util_Test::getSize(
  49792. $class,
  49793. $test->getName(false)
  49794. )
  49795. );
  49796. $this->time += $time;
  49797. }
  49798. }
  49799. /**
  49800. * Returns true if no risky test occurred.
  49801. *
  49802. * @return boolean
  49803. * @since Method available since Release 4.0.0
  49804. */
  49805. public function allHarmless()
  49806. {
  49807. return $this->riskyCount() == 0;
  49808. }
  49809. /**
  49810. * Gets the number of risky tests.
  49811. *
  49812. * @return integer
  49813. * @since Method available since Release 4.0.0
  49814. */
  49815. public function riskyCount()
  49816. {
  49817. return count($this->risky);
  49818. }
  49819. /**
  49820. * Returns true if no incomplete test occurred.
  49821. *
  49822. * @return boolean
  49823. */
  49824. public function allCompletelyImplemented()
  49825. {
  49826. return $this->notImplementedCount() == 0;
  49827. }
  49828. /**
  49829. * Gets the number of incomplete tests.
  49830. *
  49831. * @return integer
  49832. */
  49833. public function notImplementedCount()
  49834. {
  49835. return count($this->notImplemented);
  49836. }
  49837. /**
  49838. * Returns an Enumeration for the risky tests.
  49839. *
  49840. * @return array
  49841. * @since Method available since Release 4.0.0
  49842. */
  49843. public function risky()
  49844. {
  49845. return $this->risky;
  49846. }
  49847. /**
  49848. * Returns an Enumeration for the incomplete tests.
  49849. *
  49850. * @return array
  49851. */
  49852. public function notImplemented()
  49853. {
  49854. return $this->notImplemented;
  49855. }
  49856. /**
  49857. * Returns true if no test has been skipped.
  49858. *
  49859. * @return boolean
  49860. * @since Method available since Release 3.0.0
  49861. */
  49862. public function noneSkipped()
  49863. {
  49864. return $this->skippedCount() == 0;
  49865. }
  49866. /**
  49867. * Gets the number of skipped tests.
  49868. *
  49869. * @return integer
  49870. * @since Method available since Release 3.0.0
  49871. */
  49872. public function skippedCount()
  49873. {
  49874. return count($this->skipped);
  49875. }
  49876. /**
  49877. * Returns an Enumeration for the skipped tests.
  49878. *
  49879. * @return array
  49880. * @since Method available since Release 3.0.0
  49881. */
  49882. public function skipped()
  49883. {
  49884. return $this->skipped;
  49885. }
  49886. /**
  49887. * Gets the number of detected errors.
  49888. *
  49889. * @return integer
  49890. */
  49891. public function errorCount()
  49892. {
  49893. return count($this->errors);
  49894. }
  49895. /**
  49896. * Returns an Enumeration for the errors.
  49897. *
  49898. * @return array
  49899. */
  49900. public function errors()
  49901. {
  49902. return $this->errors;
  49903. }
  49904. /**
  49905. * Gets the number of detected failures.
  49906. *
  49907. * @return integer
  49908. */
  49909. public function failureCount()
  49910. {
  49911. return count($this->failures);
  49912. }
  49913. /**
  49914. * Returns an Enumeration for the failures.
  49915. *
  49916. * @return array
  49917. */
  49918. public function failures()
  49919. {
  49920. return $this->failures;
  49921. }
  49922. /**
  49923. * Returns the names of the tests that have passed.
  49924. *
  49925. * @return array
  49926. * @since Method available since Release 3.4.0
  49927. */
  49928. public function passed()
  49929. {
  49930. return $this->passed;
  49931. }
  49932. /**
  49933. * Returns the (top) test suite.
  49934. *
  49935. * @return PHPUnit_Framework_TestSuite
  49936. * @since Method available since Release 3.0.0
  49937. */
  49938. public function topTestSuite()
  49939. {
  49940. return $this->topTestSuite;
  49941. }
  49942. /**
  49943. * Returns whether code coverage information should be collected.
  49944. *
  49945. * @return boolean If code coverage should be collected
  49946. * @since Method available since Release 3.2.0
  49947. */
  49948. public function getCollectCodeCoverageInformation()
  49949. {
  49950. return $this->codeCoverage !== null;
  49951. }
  49952. /**
  49953. * Runs a TestCase.
  49954. *
  49955. * @param PHPUnit_Framework_Test $test
  49956. */
  49957. public function run(PHPUnit_Framework_Test $test)
  49958. {
  49959. PHPUnit_Framework_Assert::resetCount();
  49960. $error = false;
  49961. $failure = false;
  49962. $incomplete = false;
  49963. $risky = false;
  49964. $skipped = false;
  49965. $this->startTest($test);
  49966. $errorHandlerSet = false;
  49967. if ($this->convertErrorsToExceptions) {
  49968. $oldErrorHandler = set_error_handler(
  49969. array('PHPUnit_Util_ErrorHandler', 'handleError'),
  49970. E_ALL | E_STRICT
  49971. );
  49972. if ($oldErrorHandler === null) {
  49973. $errorHandlerSet = true;
  49974. } else {
  49975. restore_error_handler();
  49976. }
  49977. }
  49978. $collectCodeCoverage = $this->codeCoverage !== null &&
  49979. !$test instanceof PHPUnit_Extensions_SeleniumTestCase &&
  49980. !$test instanceof PHPUnit_Framework_Warning;
  49981. if ($collectCodeCoverage) {
  49982. // We need to blacklist test source files when no whitelist is used.
  49983. if (!$this->codeCoverage->filter()->hasWhitelist()) {
  49984. $classes = $this->getHierarchy(get_class($test), true);
  49985. foreach ($classes as $class) {
  49986. $this->codeCoverage->filter()->addFileToBlacklist(
  49987. $class->getFileName()
  49988. );
  49989. }
  49990. }
  49991. $this->codeCoverage->start($test);
  49992. }
  49993. PHP_Timer::start();
  49994. try {
  49995. if (!$test instanceof PHPUnit_Framework_Warning &&
  49996. $test->getSize() != PHPUnit_Util_Test::UNKNOWN &&
  49997. $this->beStrictAboutTestSize &&
  49998. extension_loaded('pcntl') && class_exists('PHP_Invoker')) {
  49999. switch ($test->getSize()) {
  50000. case PHPUnit_Util_Test::SMALL: {
  50001. $_timeout = $this->timeoutForSmallTests;
  50002. }
  50003. break;
  50004. case PHPUnit_Util_Test::MEDIUM: {
  50005. $_timeout = $this->timeoutForMediumTests;
  50006. }
  50007. break;
  50008. case PHPUnit_Util_Test::LARGE: {
  50009. $_timeout = $this->timeoutForLargeTests;
  50010. }
  50011. break;
  50012. }
  50013. $invoker = new PHP_Invoker;
  50014. $invoker->invoke(array($test, 'runBare'), array(), $_timeout);
  50015. } else {
  50016. $test->runBare();
  50017. }
  50018. } catch (PHPUnit_Framework_AssertionFailedError $e) {
  50019. $failure = true;
  50020. if ($e instanceof PHPUnit_Framework_RiskyTestError) {
  50021. $risky = true;
  50022. } elseif ($e instanceof PHPUnit_Framework_IncompleteTestError) {
  50023. $incomplete = true;
  50024. } elseif ($e instanceof PHPUnit_Framework_SkippedTestError) {
  50025. $skipped = true;
  50026. }
  50027. } catch (PHPUnit_Framework_Exception $e) {
  50028. $error = true;
  50029. } catch (Exception $e) {
  50030. $e = new PHPUnit_Framework_ExceptionWrapper($e);
  50031. $error = true;
  50032. }
  50033. $time = PHP_Timer::stop();
  50034. $test->addToAssertionCount(PHPUnit_Framework_Assert::getCount());
  50035. if ($this->beStrictAboutTestsThatDoNotTestAnything &&
  50036. $test->getNumAssertions() == 0) {
  50037. $risky = true;
  50038. }
  50039. if ($collectCodeCoverage) {
  50040. $append = !$risky && !$incomplete && !$skipped;
  50041. $linesToBeCovered = array();
  50042. $linesToBeUsed = array();
  50043. if ($append && $test instanceof PHPUnit_Framework_TestCase) {
  50044. $linesToBeCovered = PHPUnit_Util_Test::getLinesToBeCovered(
  50045. get_class($test),
  50046. $test->getName(false)
  50047. );
  50048. $linesToBeUsed = PHPUnit_Util_Test::getLinesToBeUsed(
  50049. get_class($test),
  50050. $test->getName(false)
  50051. );
  50052. }
  50053. try {
  50054. $this->codeCoverage->stop(
  50055. $append,
  50056. $linesToBeCovered,
  50057. $linesToBeUsed
  50058. );
  50059. } catch (PHP_CodeCoverage_Exception_UnintentionallyCoveredCode $cce) {
  50060. $this->addFailure(
  50061. $test,
  50062. new PHPUnit_Framework_UnintentionallyCoveredCodeError(
  50063. 'This test executed code that is not listed as code to be covered or used:' .
  50064. PHP_EOL . $cce->getMessage()
  50065. ),
  50066. $time
  50067. );
  50068. } catch (PHPUnit_Framework_InvalidCoversTargetException $cce) {
  50069. $this->addFailure(
  50070. $test,
  50071. new PHPUnit_Framework_InvalidCoversTargetError(
  50072. $cce->getMessage()
  50073. ),
  50074. $time
  50075. );
  50076. } catch (PHP_CodeCoverage_Exception $cce) {
  50077. $error = true;
  50078. if (!isset($e)) {
  50079. $e = $cce;
  50080. }
  50081. }
  50082. }
  50083. if ($errorHandlerSet === true) {
  50084. restore_error_handler();
  50085. }
  50086. if ($error === true) {
  50087. $this->addError($test, $e, $time);
  50088. } elseif ($failure === true) {
  50089. $this->addFailure($test, $e, $time);
  50090. } elseif ($this->beStrictAboutTestsThatDoNotTestAnything &&
  50091. $test->getNumAssertions() == 0) {
  50092. $this->addFailure(
  50093. $test,
  50094. new PHPUnit_Framework_RiskyTestError(
  50095. 'This test did not perform any assertions'
  50096. ),
  50097. $time
  50098. );
  50099. } elseif ($this->beStrictAboutOutputDuringTests && $test->hasOutput()) {
  50100. $this->addFailure(
  50101. $test,
  50102. new PHPUnit_Framework_OutputError(
  50103. sprintf(
  50104. 'This test printed output: %s',
  50105. $test->getActualOutput()
  50106. )
  50107. ),
  50108. $time
  50109. );
  50110. } elseif ($this->beStrictAboutTodoAnnotatedTests && $test instanceof PHPUnit_Framework_TestCase) {
  50111. $annotations = $test->getAnnotations();
  50112. if (isset($annotations['method']['todo'])) {
  50113. $this->addFailure(
  50114. $test,
  50115. new PHPUnit_Framework_RiskyTestError(
  50116. 'Test method is annotated with @todo'
  50117. ),
  50118. $time
  50119. );
  50120. }
  50121. }
  50122. $this->endTest($test, $time);
  50123. }
  50124. /**
  50125. * Gets the number of run tests.
  50126. *
  50127. * @return integer
  50128. */
  50129. public function count()
  50130. {
  50131. return $this->runTests;
  50132. }
  50133. /**
  50134. * Checks whether the test run should stop.
  50135. *
  50136. * @return boolean
  50137. */
  50138. public function shouldStop()
  50139. {
  50140. return $this->stop;
  50141. }
  50142. /**
  50143. * Marks that the test run should stop.
  50144. *
  50145. */
  50146. public function stop()
  50147. {
  50148. $this->stop = true;
  50149. }
  50150. /**
  50151. * Returns the PHP_CodeCoverage object.
  50152. *
  50153. * @return PHP_CodeCoverage
  50154. * @since Method available since Release 3.5.0
  50155. */
  50156. public function getCodeCoverage()
  50157. {
  50158. return $this->codeCoverage;
  50159. }
  50160. /**
  50161. * Sets the PHP_CodeCoverage object.
  50162. *
  50163. * @param PHP_CodeCoverage $codeCoverage
  50164. * @since Method available since Release 3.6.0
  50165. */
  50166. public function setCodeCoverage(PHP_CodeCoverage $codeCoverage)
  50167. {
  50168. $this->codeCoverage = $codeCoverage;
  50169. }
  50170. /**
  50171. * Enables or disables the error-to-exception conversion.
  50172. *
  50173. * @param boolean $flag
  50174. * @throws PHPUnit_Framework_Exception
  50175. * @since Method available since Release 3.2.14
  50176. */
  50177. public function convertErrorsToExceptions($flag)
  50178. {
  50179. if (!is_bool($flag)) {
  50180. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  50181. }
  50182. $this->convertErrorsToExceptions = $flag;
  50183. }
  50184. /**
  50185. * Returns the error-to-exception conversion setting.
  50186. *
  50187. * @return boolean
  50188. * @since Method available since Release 3.4.0
  50189. */
  50190. public function getConvertErrorsToExceptions()
  50191. {
  50192. return $this->convertErrorsToExceptions;
  50193. }
  50194. /**
  50195. * Enables or disables the stopping when an error occurs.
  50196. *
  50197. * @param boolean $flag
  50198. * @throws PHPUnit_Framework_Exception
  50199. * @since Method available since Release 3.5.0
  50200. */
  50201. public function stopOnError($flag)
  50202. {
  50203. if (!is_bool($flag)) {
  50204. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  50205. }
  50206. $this->stopOnError = $flag;
  50207. }
  50208. /**
  50209. * Enables or disables the stopping when a failure occurs.
  50210. *
  50211. * @param boolean $flag
  50212. * @throws PHPUnit_Framework_Exception
  50213. * @since Method available since Release 3.1.0
  50214. */
  50215. public function stopOnFailure($flag)
  50216. {
  50217. if (!is_bool($flag)) {
  50218. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  50219. }
  50220. $this->stopOnFailure = $flag;
  50221. }
  50222. /**
  50223. * @param boolean $flag
  50224. * @throws PHPUnit_Framework_Exception
  50225. * @since Method available since Release 4.0.0
  50226. */
  50227. public function beStrictAboutTestsThatDoNotTestAnything($flag)
  50228. {
  50229. if (!is_bool($flag)) {
  50230. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  50231. }
  50232. $this->beStrictAboutTestsThatDoNotTestAnything = $flag;
  50233. }
  50234. /**
  50235. * @return boolean
  50236. * @since Method available since Release 4.0.0
  50237. */
  50238. public function isStrictAboutTestsThatDoNotTestAnything()
  50239. {
  50240. return $this->beStrictAboutTestsThatDoNotTestAnything;
  50241. }
  50242. /**
  50243. * @param boolean $flag
  50244. * @throws PHPUnit_Framework_Exception
  50245. * @since Method available since Release 4.0.0
  50246. */
  50247. public function beStrictAboutOutputDuringTests($flag)
  50248. {
  50249. if (!is_bool($flag)) {
  50250. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  50251. }
  50252. $this->beStrictAboutOutputDuringTests = $flag;
  50253. }
  50254. /**
  50255. * @return boolean
  50256. * @since Method available since Release 4.0.0
  50257. */
  50258. public function isStrictAboutOutputDuringTests()
  50259. {
  50260. return $this->beStrictAboutOutputDuringTests;
  50261. }
  50262. /**
  50263. * @param boolean $flag
  50264. * @throws PHPUnit_Framework_Exception
  50265. * @since Method available since Release 4.0.0
  50266. */
  50267. public function beStrictAboutTestSize($flag)
  50268. {
  50269. if (!is_bool($flag)) {
  50270. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  50271. }
  50272. $this->beStrictAboutTestSize = $flag;
  50273. }
  50274. /**
  50275. * @return boolean
  50276. * @since Method available since Release 4.0.0
  50277. */
  50278. public function isStrictAboutTestSize()
  50279. {
  50280. return $this->beStrictAboutTestSize;
  50281. }
  50282. /**
  50283. * @param boolean $flag
  50284. * @throws PHPUnit_Framework_Exception
  50285. * @since Method available since Release 4.2.0
  50286. */
  50287. public function beStrictAboutTodoAnnotatedTests($flag)
  50288. {
  50289. if (!is_bool($flag)) {
  50290. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  50291. }
  50292. $this->beStrictAboutTodoAnnotatedTests = $flag;
  50293. }
  50294. /**
  50295. * @return boolean
  50296. * @since Method available since Release 4.2.0
  50297. */
  50298. public function isStrictAboutTodoAnnotatedTests()
  50299. {
  50300. return $this->beStrictAboutTodoAnnotatedTests;
  50301. }
  50302. /**
  50303. * Enables or disables the stopping for risky tests.
  50304. *
  50305. * @param boolean $flag
  50306. * @throws PHPUnit_Framework_Exception
  50307. * @since Method available since Release 4.0.0
  50308. */
  50309. public function stopOnRisky($flag)
  50310. {
  50311. if (!is_bool($flag)) {
  50312. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  50313. }
  50314. $this->stopOnRisky = $flag;
  50315. }
  50316. /**
  50317. * Enables or disables the stopping for incomplete tests.
  50318. *
  50319. * @param boolean $flag
  50320. * @throws PHPUnit_Framework_Exception
  50321. * @since Method available since Release 3.5.0
  50322. */
  50323. public function stopOnIncomplete($flag)
  50324. {
  50325. if (!is_bool($flag)) {
  50326. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  50327. }
  50328. $this->stopOnIncomplete = $flag;
  50329. }
  50330. /**
  50331. * Enables or disables the stopping for skipped tests.
  50332. *
  50333. * @param boolean $flag
  50334. * @throws PHPUnit_Framework_Exception
  50335. * @since Method available since Release 3.1.0
  50336. */
  50337. public function stopOnSkipped($flag)
  50338. {
  50339. if (!is_bool($flag)) {
  50340. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  50341. }
  50342. $this->stopOnSkipped = $flag;
  50343. }
  50344. /**
  50345. * Returns the time spent running the tests.
  50346. *
  50347. * @return float
  50348. */
  50349. public function time()
  50350. {
  50351. return $this->time;
  50352. }
  50353. /**
  50354. * Returns whether the entire test was successful or not.
  50355. *
  50356. * @return boolean
  50357. */
  50358. public function wasSuccessful()
  50359. {
  50360. return empty($this->errors) && empty($this->failures);
  50361. }
  50362. /**
  50363. * Sets the timeout for small tests.
  50364. *
  50365. * @param integer $timeout
  50366. * @throws PHPUnit_Framework_Exception
  50367. * @since Method available since Release 3.6.0
  50368. */
  50369. public function setTimeoutForSmallTests($timeout)
  50370. {
  50371. if (!is_integer($timeout)) {
  50372. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  50373. }
  50374. $this->timeoutForSmallTests = $timeout;
  50375. }
  50376. /**
  50377. * Sets the timeout for medium tests.
  50378. *
  50379. * @param integer $timeout
  50380. * @throws PHPUnit_Framework_Exception
  50381. * @since Method available since Release 3.6.0
  50382. */
  50383. public function setTimeoutForMediumTests($timeout)
  50384. {
  50385. if (!is_integer($timeout)) {
  50386. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  50387. }
  50388. $this->timeoutForMediumTests = $timeout;
  50389. }
  50390. /**
  50391. * Sets the timeout for large tests.
  50392. *
  50393. * @param integer $timeout
  50394. * @throws PHPUnit_Framework_Exception
  50395. * @since Method available since Release 3.6.0
  50396. */
  50397. public function setTimeoutForLargeTests($timeout)
  50398. {
  50399. if (!is_integer($timeout)) {
  50400. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  50401. }
  50402. $this->timeoutForLargeTests = $timeout;
  50403. }
  50404. /**
  50405. * Returns the class hierarchy for a given class.
  50406. *
  50407. * @param string $className
  50408. * @param boolean $asReflectionObjects
  50409. * @return array
  50410. */
  50411. protected function getHierarchy($className, $asReflectionObjects = false)
  50412. {
  50413. if ($asReflectionObjects) {
  50414. $classes = array(new ReflectionClass($className));
  50415. } else {
  50416. $classes = array($className);
  50417. }
  50418. $done = false;
  50419. while (!$done) {
  50420. if ($asReflectionObjects) {
  50421. $class = new ReflectionClass(
  50422. $classes[count($classes)-1]->getName()
  50423. );
  50424. } else {
  50425. $class = new ReflectionClass($classes[count($classes)-1]);
  50426. }
  50427. $parent = $class->getParentClass();
  50428. if ($parent !== false) {
  50429. if ($asReflectionObjects) {
  50430. $classes[] = $parent;
  50431. } else {
  50432. $classes[] = $parent->getName();
  50433. }
  50434. } else {
  50435. $done = true;
  50436. }
  50437. }
  50438. return $classes;
  50439. }
  50440. }
  50441. <?php
  50442. /*
  50443. * This file is part of PHPUnit.
  50444. *
  50445. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50446. *
  50447. * For the full copyright and license information, please view the LICENSE
  50448. * file that was distributed with this source code.
  50449. */
  50450. /**
  50451. * A TestFailure collects a failed test together with the caught exception.
  50452. *
  50453. * @package PHPUnit
  50454. * @subpackage Framework
  50455. * @author Sebastian Bergmann <sebastian@phpunit.de>
  50456. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  50457. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  50458. * @link http://www.phpunit.de/
  50459. * @since Class available since Release 2.0.0
  50460. */
  50461. class PHPUnit_Framework_TestFailure
  50462. {
  50463. /**
  50464. * @var string
  50465. */
  50466. private $testName;
  50467. /**
  50468. * @var PHPUnit_Framework_Test|null
  50469. */
  50470. protected $failedTest;
  50471. /**
  50472. * @var Exception
  50473. */
  50474. protected $thrownException;
  50475. /**
  50476. * Constructs a TestFailure with the given test and exception.
  50477. *
  50478. * @param PHPUnit_Framework_Test $failedTest
  50479. * @param Exception $thrownException
  50480. */
  50481. public function __construct(PHPUnit_Framework_Test $failedTest, Exception $thrownException)
  50482. {
  50483. if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) {
  50484. $this->testName = $failedTest->toString();
  50485. } else {
  50486. $this->testName = get_class($failedTest);
  50487. }
  50488. if (!$failedTest instanceof PHPUnit_Framework_TestCase || !$failedTest->isInIsolation()) {
  50489. $this->failedTest = $failedTest;
  50490. }
  50491. $this->thrownException = $thrownException;
  50492. }
  50493. /**
  50494. * Returns a short description of the failure.
  50495. *
  50496. * @return string
  50497. */
  50498. public function toString()
  50499. {
  50500. return sprintf(
  50501. '%s: %s',
  50502. $this->testName,
  50503. $this->thrownException->getMessage()
  50504. );
  50505. }
  50506. /**
  50507. * Returns a description for the thrown exception.
  50508. *
  50509. * @return string
  50510. * @since Method available since Release 3.4.0
  50511. */
  50512. public function getExceptionAsString()
  50513. {
  50514. return self::exceptionToString($this->thrownException);
  50515. }
  50516. /**
  50517. * Returns a description for an exception.
  50518. *
  50519. * @param Exception $e
  50520. * @return string
  50521. * @since Method available since Release 3.2.0
  50522. */
  50523. public static function exceptionToString(Exception $e)
  50524. {
  50525. if ($e instanceof PHPUnit_Framework_SelfDescribing) {
  50526. $buffer = $e->toString();
  50527. if ($e instanceof PHPUnit_Framework_ExpectationFailedException && $e->getComparisonFailure()) {
  50528. $buffer = $buffer . $e->getComparisonFailure()->getDiff();
  50529. }
  50530. if (!empty($buffer)) {
  50531. $buffer = trim($buffer) . "\n";
  50532. }
  50533. } elseif ($e instanceof PHPUnit_Framework_Error) {
  50534. $buffer = $e->getMessage() . "\n";
  50535. } elseif ($e instanceof PHPUnit_Framework_ExceptionWrapper) {
  50536. $buffer = $e->getClassname() . ': ' . $e->getMessage() . "\n";
  50537. } else {
  50538. $buffer = get_class($e) . ': ' . $e->getMessage() . "\n";
  50539. }
  50540. return $buffer;
  50541. }
  50542. /**
  50543. * Returns the name of the failing test (including data set, if any).
  50544. *
  50545. * @return string
  50546. * @since Method available since Release 4.3.0
  50547. */
  50548. public function getTestName()
  50549. {
  50550. return $this->testName;
  50551. }
  50552. /**
  50553. * Returns the failing test.
  50554. *
  50555. * Note: The test object is not set when the test is executed in process
  50556. * isolation.
  50557. *
  50558. * @see PHPUnit_Framework_Exception
  50559. *
  50560. * @return PHPUnit_Framework_Test|null
  50561. */
  50562. public function failedTest()
  50563. {
  50564. return $this->failedTest;
  50565. }
  50566. /**
  50567. * Gets the thrown exception.
  50568. *
  50569. * @return Exception
  50570. */
  50571. public function thrownException()
  50572. {
  50573. return $this->thrownException;
  50574. }
  50575. /**
  50576. * Returns the exception's message.
  50577. *
  50578. * @return string
  50579. */
  50580. public function exceptionMessage()
  50581. {
  50582. return $this->thrownException()->getMessage();
  50583. }
  50584. /**
  50585. * Returns true if the thrown exception
  50586. * is of type AssertionFailedError.
  50587. *
  50588. * @return boolean
  50589. */
  50590. public function isFailure()
  50591. {
  50592. return ($this->thrownException() instanceof PHPUnit_Framework_AssertionFailedError);
  50593. }
  50594. }
  50595. <?php
  50596. /*
  50597. * This file is part of PHPUnit.
  50598. *
  50599. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50600. *
  50601. * For the full copyright and license information, please view the LICENSE
  50602. * file that was distributed with this source code.
  50603. */
  50604. /**
  50605. * A marker interface for marking any exception/error as result of an unit
  50606. * test as incomplete implementation or currently not implemented.
  50607. *
  50608. * @package PHPUnit
  50609. * @subpackage Framework
  50610. * @author Sebastian Bergmann <sebastian@phpunit.de>
  50611. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  50612. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  50613. * @link http://www.phpunit.de/
  50614. * @since Interface available since Release 2.0.0
  50615. */
  50616. interface PHPUnit_Framework_IncompleteTest
  50617. {
  50618. }
  50619. <?php
  50620. /*
  50621. * This file is part of PHPUnit.
  50622. *
  50623. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50624. *
  50625. * For the full copyright and license information, please view the LICENSE
  50626. * file that was distributed with this source code.
  50627. */
  50628. /**
  50629. * A skipped test case
  50630. *
  50631. * @package PHPUnit
  50632. * @subpackage Framework
  50633. * @author Davey Shafik <me@daveyshafik.com>
  50634. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  50635. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  50636. * @link http://www.phpunit.de/
  50637. * @since Class available since Release 4.3.0
  50638. */
  50639. class PHPUnit_Framework_SkippedTestCase extends PHPUnit_Framework_TestCase
  50640. {
  50641. /**
  50642. * @var string
  50643. */
  50644. protected $message = '';
  50645. /**
  50646. * @var boolean
  50647. */
  50648. protected $backupGlobals = false;
  50649. /**
  50650. * @var boolean
  50651. */
  50652. protected $backupStaticAttributes = false;
  50653. /**
  50654. * @var boolean
  50655. */
  50656. protected $runTestInSeparateProcess = false;
  50657. /**
  50658. * @var boolean
  50659. */
  50660. protected $useErrorHandler = false;
  50661. /**
  50662. * @var boolean
  50663. */
  50664. protected $useOutputBuffering = false;
  50665. /**
  50666. * @param string $message
  50667. */
  50668. public function __construct($className, $methodName, $message = '')
  50669. {
  50670. $this->message = $message;
  50671. parent::__construct($className . '::' . $methodName);
  50672. }
  50673. /**
  50674. * @throws PHPUnit_Framework_Exception
  50675. */
  50676. protected function runTest()
  50677. {
  50678. $this->markTestSkipped($this->message);
  50679. }
  50680. /**
  50681. * @return string
  50682. */
  50683. public function getMessage()
  50684. {
  50685. return $this->message;
  50686. }
  50687. /**
  50688. * Returns a string representation of the test case.
  50689. *
  50690. * @return string
  50691. */
  50692. public function toString()
  50693. {
  50694. return $this->getName();
  50695. }
  50696. }
  50697. <?php
  50698. /*
  50699. * This file is part of PHPUnit.
  50700. *
  50701. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50702. *
  50703. * For the full copyright and license information, please view the LICENSE
  50704. * file that was distributed with this source code.
  50705. */
  50706. /**
  50707. * Constraint that asserts that the class it is evaluated for has a given
  50708. * attribute.
  50709. *
  50710. * The attribute name is passed in the constructor.
  50711. *
  50712. * @package PHPUnit
  50713. * @subpackage Framework_Constraint
  50714. * @author Sebastian Bergmann <sebastian@phpunit.de>
  50715. * @author Bernhard Schussek <bschussek@2bepublished.at>
  50716. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  50717. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  50718. * @link http://www.phpunit.de/
  50719. * @since Class available since Release 3.1.0
  50720. */
  50721. class PHPUnit_Framework_Constraint_ClassHasAttribute extends PHPUnit_Framework_Constraint
  50722. {
  50723. /**
  50724. * @var string
  50725. */
  50726. protected $attributeName;
  50727. /**
  50728. * @param string $attributeName
  50729. */
  50730. public function __construct($attributeName)
  50731. {
  50732. parent::__construct();
  50733. $this->attributeName = $attributeName;
  50734. }
  50735. /**
  50736. * Evaluates the constraint for parameter $other. Returns true if the
  50737. * constraint is met, false otherwise.
  50738. *
  50739. * @param mixed $other Value or object to evaluate.
  50740. * @return bool
  50741. */
  50742. protected function matches($other)
  50743. {
  50744. $class = new ReflectionClass($other);
  50745. return $class->hasProperty($this->attributeName);
  50746. }
  50747. /**
  50748. * Returns a string representation of the constraint.
  50749. *
  50750. * @return string
  50751. */
  50752. public function toString()
  50753. {
  50754. return sprintf(
  50755. 'has attribute "%s"',
  50756. $this->attributeName
  50757. );
  50758. }
  50759. /**
  50760. * Returns the description of the failure
  50761. *
  50762. * The beginning of failure messages is "Failed asserting that" in most
  50763. * cases. This method should return the second part of that sentence.
  50764. *
  50765. * @param mixed $other Evaluated value or object.
  50766. * @return string
  50767. */
  50768. protected function failureDescription($other)
  50769. {
  50770. return sprintf(
  50771. '%sclass "%s" %s',
  50772. is_object($other) ? 'object of ' : '',
  50773. is_object($other) ? get_class($other) : $other,
  50774. $this->toString()
  50775. );
  50776. }
  50777. }
  50778. <?php
  50779. /*
  50780. * This file is part of PHPUnit.
  50781. *
  50782. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50783. *
  50784. * For the full copyright and license information, please view the LICENSE
  50785. * file that was distributed with this source code.
  50786. */
  50787. /**
  50788. * Constraint that asserts that the Traversable it is applied to contains
  50789. * a given value.
  50790. *
  50791. * @package PHPUnit
  50792. * @subpackage Framework_Constraint
  50793. * @author Sebastian Bergmann <sebastian@phpunit.de>
  50794. * @author Bernhard Schussek <bschussek@2bepublished.at>
  50795. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  50796. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  50797. * @link http://www.phpunit.de/
  50798. * @since Class available since Release 3.0.0
  50799. */
  50800. class PHPUnit_Framework_Constraint_TraversableContains extends PHPUnit_Framework_Constraint
  50801. {
  50802. /**
  50803. * @var boolean
  50804. */
  50805. protected $checkForObjectIdentity;
  50806. /**
  50807. * @var boolean
  50808. */
  50809. protected $checkForNonObjectIdentity;
  50810. /**
  50811. * @var mixed
  50812. */
  50813. protected $value;
  50814. /**
  50815. * @param mixed $value
  50816. * @param boolean $checkForObjectIdentity
  50817. * @param boolean $checkForNonObjectIdentity
  50818. * @throws PHPUnit_Framework_Exception
  50819. */
  50820. public function __construct($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  50821. {
  50822. parent::__construct();
  50823. if (!is_bool($checkForObjectIdentity)) {
  50824. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
  50825. }
  50826. if (!is_bool($checkForNonObjectIdentity)) {
  50827. throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'boolean');
  50828. }
  50829. $this->checkForObjectIdentity = $checkForObjectIdentity;
  50830. $this->checkForNonObjectIdentity = $checkForNonObjectIdentity;
  50831. $this->value = $value;
  50832. }
  50833. /**
  50834. * Evaluates the constraint for parameter $other. Returns true if the
  50835. * constraint is met, false otherwise.
  50836. *
  50837. * @param mixed $other Value or object to evaluate.
  50838. * @return bool
  50839. */
  50840. protected function matches($other)
  50841. {
  50842. if ($other instanceof SplObjectStorage) {
  50843. return $other->contains($this->value);
  50844. }
  50845. if (is_object($this->value)) {
  50846. foreach ($other as $element) {
  50847. if (($this->checkForObjectIdentity &&
  50848. $element === $this->value) ||
  50849. (!$this->checkForObjectIdentity &&
  50850. $element == $this->value)) {
  50851. return true;
  50852. }
  50853. }
  50854. } else {
  50855. foreach ($other as $element) {
  50856. if (($this->checkForNonObjectIdentity &&
  50857. $element === $this->value) ||
  50858. (!$this->checkForNonObjectIdentity &&
  50859. $element == $this->value)) {
  50860. return true;
  50861. }
  50862. }
  50863. }
  50864. return false;
  50865. }
  50866. /**
  50867. * Returns a string representation of the constraint.
  50868. *
  50869. * @return string
  50870. */
  50871. public function toString()
  50872. {
  50873. if (is_string($this->value) && strpos($this->value, "\n") !== false) {
  50874. return 'contains "' . $this->value . '"';
  50875. } else {
  50876. return 'contains ' . $this->exporter->export($this->value);
  50877. }
  50878. }
  50879. /**
  50880. * Returns the description of the failure
  50881. *
  50882. * The beginning of failure messages is "Failed asserting that" in most
  50883. * cases. This method should return the second part of that sentence.
  50884. *
  50885. * @param mixed $other Evaluated value or object.
  50886. * @return string
  50887. */
  50888. protected function failureDescription($other)
  50889. {
  50890. return sprintf(
  50891. '%s %s',
  50892. is_array($other) ? 'an array' : 'a traversable',
  50893. $this->toString()
  50894. );
  50895. }
  50896. }
  50897. <?php
  50898. /*
  50899. * This file is part of PHPUnit.
  50900. *
  50901. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50902. *
  50903. * For the full copyright and license information, please view the LICENSE
  50904. * file that was distributed with this source code.
  50905. */
  50906. /**
  50907. *
  50908. *
  50909. * @package PHPUnit
  50910. * @subpackage Framework_Constraint
  50911. * @author Sebastian Bergmann <sebastian@phpunit.de>
  50912. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  50913. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  50914. * @link http://www.phpunit.de/
  50915. * @since Class available since Release 3.6.6
  50916. */
  50917. class PHPUnit_Framework_Constraint_ExceptionCode extends PHPUnit_Framework_Constraint
  50918. {
  50919. /**
  50920. * @var integer
  50921. */
  50922. protected $expectedCode;
  50923. /**
  50924. * @param integer $expected
  50925. */
  50926. public function __construct($expected)
  50927. {
  50928. parent::__construct();
  50929. $this->expectedCode = $expected;
  50930. }
  50931. /**
  50932. * Evaluates the constraint for parameter $other. Returns true if the
  50933. * constraint is met, false otherwise.
  50934. *
  50935. * @param Exception $other
  50936. * @return boolean
  50937. */
  50938. protected function matches($other)
  50939. {
  50940. return (string) $other->getCode() == (string) $this->expectedCode;
  50941. }
  50942. /**
  50943. * Returns the description of the failure
  50944. *
  50945. * The beginning of failure messages is "Failed asserting that" in most
  50946. * cases. This method should return the second part of that sentence.
  50947. *
  50948. * @param mixed $other Evaluated value or object.
  50949. * @return string
  50950. */
  50951. protected function failureDescription($other)
  50952. {
  50953. return sprintf(
  50954. '%s is equal to expected exception code %s',
  50955. $this->exporter->export($other->getCode()),
  50956. $this->exporter->export($this->expectedCode)
  50957. );
  50958. }
  50959. /**
  50960. * @return string
  50961. */
  50962. public function toString()
  50963. {
  50964. return 'exception code is ';
  50965. }
  50966. }
  50967. <?php
  50968. /*
  50969. * This file is part of PHPUnit.
  50970. *
  50971. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50972. *
  50973. * For the full copyright and license information, please view the LICENSE
  50974. * file that was distributed with this source code.
  50975. */
  50976. /**
  50977. *
  50978. *
  50979. * @package PHPUnit
  50980. * @subpackage Framework_Constraint
  50981. * @author Sebastian Bergmann <sebastian@phpunit.de>
  50982. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  50983. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  50984. * @link http://www.phpunit.de/
  50985. * @since Class available since Release 3.6.6
  50986. */
  50987. class PHPUnit_Framework_Constraint_Exception extends PHPUnit_Framework_Constraint
  50988. {
  50989. /**
  50990. * @var string
  50991. */
  50992. protected $className;
  50993. /**
  50994. * @param string $className
  50995. */
  50996. public function __construct($className)
  50997. {
  50998. parent::__construct();
  50999. $this->className = $className;
  51000. }
  51001. /**
  51002. * Evaluates the constraint for parameter $other. Returns true if the
  51003. * constraint is met, false otherwise.
  51004. *
  51005. * @param mixed $other Value or object to evaluate.
  51006. * @return bool
  51007. */
  51008. protected function matches($other)
  51009. {
  51010. return $other instanceof $this->className;
  51011. }
  51012. /**
  51013. * Returns the description of the failure
  51014. *
  51015. * The beginning of failure messages is "Failed asserting that" in most
  51016. * cases. This method should return the second part of that sentence.
  51017. *
  51018. * @param mixed $other Evaluated value or object.
  51019. * @return string
  51020. */
  51021. protected function failureDescription($other)
  51022. {
  51023. if ($other !== null) {
  51024. $message = '';
  51025. if ($other instanceof Exception) {
  51026. $message = '. Message was: "' . $other->getMessage() . '" at'
  51027. . "\n" . $other->getTraceAsString();
  51028. }
  51029. return sprintf(
  51030. 'exception of type "%s" matches expected exception "%s"%s',
  51031. get_class($other),
  51032. $this->className,
  51033. $message
  51034. );
  51035. }
  51036. return sprintf(
  51037. 'exception of type "%s" is thrown',
  51038. $this->className
  51039. );
  51040. }
  51041. /**
  51042. * Returns a string representation of the constraint.
  51043. *
  51044. * @return string
  51045. */
  51046. public function toString()
  51047. {
  51048. return sprintf(
  51049. 'exception of type "%s"',
  51050. $this->className
  51051. );
  51052. }
  51053. }
  51054. <?php
  51055. /*
  51056. * This file is part of PHPUnit.
  51057. *
  51058. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51059. *
  51060. * For the full copyright and license information, please view the LICENSE
  51061. * file that was distributed with this source code.
  51062. */
  51063. /**
  51064. *
  51065. *
  51066. * @package PHPUnit
  51067. * @subpackage Framework_Constraint
  51068. * @author Sebastian Bergmann <sebastian@phpunit.de>
  51069. * @author Bernhard Schussek <bschussek@2bepublished.at>
  51070. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51071. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  51072. * @link http://www.phpunit.de/
  51073. * @since Class available since Release 3.6.0
  51074. */
  51075. class PHPUnit_Framework_Constraint_SameSize extends PHPUnit_Framework_Constraint_Count
  51076. {
  51077. /**
  51078. * @var integer
  51079. */
  51080. protected $expectedCount;
  51081. /**
  51082. * @param integer $expected
  51083. */
  51084. public function __construct($expected)
  51085. {
  51086. parent::__construct($this->getCountOf($expected));
  51087. }
  51088. }
  51089. <?php
  51090. /*
  51091. * This file is part of PHPUnit.
  51092. *
  51093. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51094. *
  51095. * For the full copyright and license information, please view the LICENSE
  51096. * file that was distributed with this source code.
  51097. */
  51098. /**
  51099. * Asserts whether or not two JSON objects are equal.
  51100. *
  51101. * @package PHPUnit
  51102. * @subpackage Framework_Constraint
  51103. * @author Bastian Feder <php@bastian-feder.de>
  51104. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51105. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause
  51106. * @link http://www.phpunit.de/
  51107. * @since Class available since Release 3.7.0
  51108. */
  51109. class PHPUnit_Framework_Constraint_JsonMatches extends PHPUnit_Framework_Constraint
  51110. {
  51111. /**
  51112. * @var string
  51113. */
  51114. protected $value;
  51115. /**
  51116. * Creates a new constraint.
  51117. *
  51118. * @param string $value
  51119. */
  51120. public function __construct($value)
  51121. {
  51122. parent::__construct();
  51123. $this->value = $value;
  51124. }
  51125. /**
  51126. * Evaluates the constraint for parameter $other. Returns true if the
  51127. * constraint is met, false otherwise.
  51128. *
  51129. * This method can be overridden to implement the evaluation algorithm.
  51130. *
  51131. * @param mixed $other Value or object to evaluate.
  51132. * @return bool
  51133. */
  51134. protected function matches($other)
  51135. {
  51136. $decodedOther = json_decode($other);
  51137. if (json_last_error()) {
  51138. return false;
  51139. }
  51140. $decodedValue = json_decode($this->value);
  51141. if (json_last_error()) {
  51142. return false;
  51143. }
  51144. return $decodedOther == $decodedValue;
  51145. }
  51146. /**
  51147. * Returns a string representation of the object.
  51148. *
  51149. * @return string
  51150. */
  51151. public function toString()
  51152. {
  51153. return sprintf(
  51154. 'matches JSON string "%s"',
  51155. $this->value
  51156. );
  51157. }
  51158. }
  51159. <?php
  51160. /*
  51161. * This file is part of PHPUnit.
  51162. *
  51163. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51164. *
  51165. * For the full copyright and license information, please view the LICENSE
  51166. * file that was distributed with this source code.
  51167. */
  51168. /**
  51169. * Constraint that asserts that the object it is evaluated for is an instance
  51170. * of a given class.
  51171. *
  51172. * The expected class name is passed in the constructor.
  51173. *
  51174. * @package PHPUnit
  51175. * @subpackage Framework_Constraint
  51176. * @author Sebastian Bergmann <sebastian@phpunit.de>
  51177. * @author Bernhard Schussek <bschussek@2bepublished.at>
  51178. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51179. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  51180. * @link http://www.phpunit.de/
  51181. * @since Class available since Release 3.0.0
  51182. */
  51183. class PHPUnit_Framework_Constraint_IsInstanceOf extends PHPUnit_Framework_Constraint
  51184. {
  51185. /**
  51186. * @var string
  51187. */
  51188. protected $className;
  51189. /**
  51190. * @param string $className
  51191. */
  51192. public function __construct($className)
  51193. {
  51194. parent::__construct();
  51195. $this->className = $className;
  51196. }
  51197. /**
  51198. * Evaluates the constraint for parameter $other. Returns true if the
  51199. * constraint is met, false otherwise.
  51200. *
  51201. * @param mixed $other Value or object to evaluate.
  51202. * @return bool
  51203. */
  51204. protected function matches($other)
  51205. {
  51206. return ($other instanceof $this->className);
  51207. }
  51208. /**
  51209. * Returns the description of the failure
  51210. *
  51211. * The beginning of failure messages is "Failed asserting that" in most
  51212. * cases. This method should return the second part of that sentence.
  51213. *
  51214. * @param mixed $other Evaluated value or object.
  51215. * @return string
  51216. */
  51217. protected function failureDescription($other)
  51218. {
  51219. return sprintf(
  51220. '%s is an instance of %s "%s"',
  51221. $this->exporter->shortenedExport($other),
  51222. $this->getType(),
  51223. $this->className
  51224. );
  51225. }
  51226. /**
  51227. * Returns a string representation of the constraint.
  51228. *
  51229. * @return string
  51230. */
  51231. public function toString()
  51232. {
  51233. return sprintf(
  51234. 'is instance of %s "%s"',
  51235. $this->getType(),
  51236. $this->className
  51237. );
  51238. }
  51239. private function getType()
  51240. {
  51241. try {
  51242. $reflection = new ReflectionClass($this->className);
  51243. if ($reflection->isInterface()) {
  51244. return 'interface';
  51245. }
  51246. } catch (ReflectionException $e) {
  51247. }
  51248. return 'class';
  51249. }
  51250. }
  51251. <?php
  51252. /*
  51253. * This file is part of PHPUnit.
  51254. *
  51255. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51256. *
  51257. * For the full copyright and license information, please view the LICENSE
  51258. * file that was distributed with this source code.
  51259. */
  51260. /**
  51261. * Constraint that asserts that the object it is evaluated for has a given
  51262. * attribute.
  51263. *
  51264. * The attribute name is passed in the constructor.
  51265. *
  51266. * @package PHPUnit
  51267. * @subpackage Framework_Constraint
  51268. * @author Sebastian Bergmann <sebastian@phpunit.de>
  51269. * @author Bernhard Schussek <bschussek@2bepublished.at>
  51270. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51271. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  51272. * @link http://www.phpunit.de/
  51273. * @since Class available since Release 3.0.0
  51274. */
  51275. class PHPUnit_Framework_Constraint_ObjectHasAttribute extends PHPUnit_Framework_Constraint_ClassHasAttribute
  51276. {
  51277. /**
  51278. * Evaluates the constraint for parameter $other. Returns true if the
  51279. * constraint is met, false otherwise.
  51280. *
  51281. * @param mixed $other Value or object to evaluate.
  51282. * @return bool
  51283. */
  51284. protected function matches($other)
  51285. {
  51286. $object = new ReflectionObject($other);
  51287. return $object->hasProperty($this->attributeName);
  51288. }
  51289. }
  51290. <?php
  51291. /*
  51292. * This file is part of PHPUnit.
  51293. *
  51294. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51295. *
  51296. * For the full copyright and license information, please view the LICENSE
  51297. * file that was distributed with this source code.
  51298. */
  51299. /**
  51300. * Constraint that asserts that the value it is evaluated for is of a
  51301. * specified type.
  51302. *
  51303. * The expected value is passed in the constructor.
  51304. *
  51305. * @package PHPUnit
  51306. * @subpackage Framework_Constraint
  51307. * @author Sebastian Bergmann <sebastian@phpunit.de>
  51308. * @author Bernhard Schussek <bschussek@2bepublished.at>
  51309. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51310. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  51311. * @link http://www.phpunit.de/
  51312. * @since Class available since Release 3.0.0
  51313. */
  51314. class PHPUnit_Framework_Constraint_IsType extends PHPUnit_Framework_Constraint
  51315. {
  51316. const TYPE_ARRAY = 'array';
  51317. const TYPE_BOOL = 'bool';
  51318. const TYPE_FLOAT = 'float';
  51319. const TYPE_INT = 'int';
  51320. const TYPE_NULL = 'null';
  51321. const TYPE_NUMERIC = 'numeric';
  51322. const TYPE_OBJECT = 'object';
  51323. const TYPE_RESOURCE = 'resource';
  51324. const TYPE_STRING = 'string';
  51325. const TYPE_SCALAR = 'scalar';
  51326. const TYPE_CALLABLE = 'callable';
  51327. /**
  51328. * @var array
  51329. */
  51330. protected $types = array(
  51331. 'array' => true,
  51332. 'boolean' => true,
  51333. 'bool' => true,
  51334. 'double' => true,
  51335. 'float' => true,
  51336. 'integer' => true,
  51337. 'int' => true,
  51338. 'null' => true,
  51339. 'numeric' => true,
  51340. 'object' => true,
  51341. 'resource' => true,
  51342. 'string' => true,
  51343. 'scalar' => true,
  51344. 'callable' => true
  51345. );
  51346. /**
  51347. * @var string
  51348. */
  51349. protected $type;
  51350. /**
  51351. * @param string $type
  51352. * @throws PHPUnit_Framework_Exception
  51353. */
  51354. public function __construct($type)
  51355. {
  51356. parent::__construct();
  51357. if (!isset($this->types[$type])) {
  51358. throw new PHPUnit_Framework_Exception(
  51359. sprintf(
  51360. 'Type specified for PHPUnit_Framework_Constraint_IsType <%s> ' .
  51361. 'is not a valid type.',
  51362. $type
  51363. )
  51364. );
  51365. }
  51366. $this->type = $type;
  51367. }
  51368. /**
  51369. * Evaluates the constraint for parameter $other. Returns true if the
  51370. * constraint is met, false otherwise.
  51371. *
  51372. * @param mixed $other Value or object to evaluate.
  51373. * @return bool
  51374. */
  51375. protected function matches($other)
  51376. {
  51377. switch ($this->type) {
  51378. case 'numeric': {
  51379. return is_numeric($other);
  51380. }
  51381. case 'integer':
  51382. case 'int': {
  51383. return is_integer($other);
  51384. }
  51385. case 'double':
  51386. case 'float': {
  51387. return is_float($other);
  51388. }
  51389. case 'string': {
  51390. return is_string($other);
  51391. }
  51392. case 'boolean':
  51393. case 'bool': {
  51394. return is_bool($other);
  51395. }
  51396. case 'null': {
  51397. return is_null($other);
  51398. }
  51399. case 'array': {
  51400. return is_array($other);
  51401. }
  51402. case 'object': {
  51403. return is_object($other);
  51404. }
  51405. case 'resource': {
  51406. return is_resource($other) || is_string(@get_resource_type($other));
  51407. }
  51408. case 'scalar': {
  51409. return is_scalar($other);
  51410. }
  51411. case 'callable': {
  51412. return is_callable($other);
  51413. }
  51414. }
  51415. }
  51416. /**
  51417. * Returns a string representation of the constraint.
  51418. *
  51419. * @return string
  51420. */
  51421. public function toString()
  51422. {
  51423. return sprintf(
  51424. 'is of type "%s"',
  51425. $this->type
  51426. );
  51427. }
  51428. }
  51429. <?php
  51430. /*
  51431. * This file is part of PHPUnit.
  51432. *
  51433. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51434. *
  51435. * For the full copyright and license information, please view the LICENSE
  51436. * file that was distributed with this source code.
  51437. */
  51438. /**
  51439. * Constraint that asserts that the value it is evaluated for is less than
  51440. * a given value.
  51441. *
  51442. * @package PHPUnit
  51443. * @subpackage Framework_Constraint
  51444. * @author Sebastian Bergmann <sebastian@phpunit.de>
  51445. * @author Bernhard Schussek <bschussek@2bepublished.at>
  51446. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51447. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  51448. * @link http://www.phpunit.de/
  51449. * @since Class available since Release 3.0.0
  51450. */
  51451. class PHPUnit_Framework_Constraint_LessThan extends PHPUnit_Framework_Constraint
  51452. {
  51453. /**
  51454. * @var numeric
  51455. */
  51456. protected $value;
  51457. /**
  51458. * @param numeric $value
  51459. */
  51460. public function __construct($value)
  51461. {
  51462. parent::__construct();
  51463. $this->value = $value;
  51464. }
  51465. /**
  51466. * Evaluates the constraint for parameter $other. Returns true if the
  51467. * constraint is met, false otherwise.
  51468. *
  51469. * @param mixed $other Value or object to evaluate.
  51470. * @return bool
  51471. */
  51472. protected function matches($other)
  51473. {
  51474. return $this->value > $other;
  51475. }
  51476. /**
  51477. * Returns a string representation of the constraint.
  51478. *
  51479. * @return string
  51480. */
  51481. public function toString()
  51482. {
  51483. return 'is less than ' . $this->exporter->export($this->value);
  51484. }
  51485. }
  51486. <?php
  51487. /*
  51488. * This file is part of PHPUnit.
  51489. *
  51490. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51491. *
  51492. * For the full copyright and license information, please view the LICENSE
  51493. * file that was distributed with this source code.
  51494. */
  51495. /**
  51496. * Constraint that asserts that the array it is evaluated for has a specified subset.
  51497. *
  51498. * Uses array_replace_recursive() to check if a key value subset is part of the
  51499. * subject array.
  51500. *
  51501. * @package PHPUnit
  51502. * @subpackage Framework_Constraint
  51503. * @author Márcio Almada <marcio3w@gmail.com>
  51504. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51505. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  51506. * @link http://www.phpunit.de/
  51507. * @since Class available since Release 4.4.0
  51508. */
  51509. class PHPUnit_Framework_Constraint_ArraySubset extends PHPUnit_Framework_Constraint
  51510. {
  51511. /**
  51512. * @var array|ArrayAccess
  51513. */
  51514. protected $subset;
  51515. /**
  51516. * @var boolean
  51517. */
  51518. protected $strict;
  51519. /**
  51520. * @param array|ArrayAccess $subset
  51521. * @param boolean $strict Check for object identity
  51522. */
  51523. public function __construct($subset, $strict = false)
  51524. {
  51525. parent::__construct();
  51526. $this->strict = $strict;
  51527. $this->subset = $subset;
  51528. }
  51529. /**
  51530. * Evaluates the constraint for parameter $other. Returns true if the
  51531. * constraint is met, false otherwise.
  51532. *
  51533. * @param array|ArrayAccess $other Array or ArrayAcess object to evaluate.
  51534. * @return bool
  51535. */
  51536. protected function matches($other)
  51537. {
  51538. $patched = array_replace_recursive($other, $this->subset);
  51539. if ($this->strict) {
  51540. return $other === $patched;
  51541. } else {
  51542. return $other == $patched;
  51543. }
  51544. }
  51545. /**
  51546. * Returns a string representation of the constraint.
  51547. *
  51548. * @return string
  51549. */
  51550. public function toString()
  51551. {
  51552. return 'has the subset ' . $this->exporter->export($this->subset);
  51553. }
  51554. /**
  51555. * Returns the description of the failure
  51556. *
  51557. * The beginning of failure messages is "Failed asserting that" in most
  51558. * cases. This method should return the second part of that sentence.
  51559. *
  51560. * @param mixed $other Evaluated value or object.
  51561. * @return string
  51562. */
  51563. protected function failureDescription($other)
  51564. {
  51565. return 'an array ' . $this->toString();
  51566. }
  51567. }
  51568. <?php
  51569. /*
  51570. * This file is part of PHPUnit.
  51571. *
  51572. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51573. *
  51574. * For the full copyright and license information, please view the LICENSE
  51575. * file that was distributed with this source code.
  51576. */
  51577. /**
  51578. * Constraint that accepts true.
  51579. *
  51580. * @package PHPUnit
  51581. * @subpackage Framework_Constraint
  51582. * @author Sebastian Bergmann <sebastian@phpunit.de>
  51583. * @author Bernhard Schussek <bschussek@2bepublished.at>
  51584. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51585. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  51586. * @link http://www.phpunit.de/
  51587. * @since Class available since Release 3.3.0
  51588. */
  51589. class PHPUnit_Framework_Constraint_IsTrue extends PHPUnit_Framework_Constraint
  51590. {
  51591. /**
  51592. * Evaluates the constraint for parameter $other. Returns true if the
  51593. * constraint is met, false otherwise.
  51594. *
  51595. * @param mixed $other Value or object to evaluate.
  51596. * @return bool
  51597. */
  51598. protected function matches($other)
  51599. {
  51600. return $other === true;
  51601. }
  51602. /**
  51603. * Returns a string representation of the constraint.
  51604. *
  51605. * @return string
  51606. */
  51607. public function toString()
  51608. {
  51609. return 'is true';
  51610. }
  51611. }
  51612. <?php
  51613. /*
  51614. * This file is part of PHPUnit.
  51615. *
  51616. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51617. *
  51618. * For the full copyright and license information, please view the LICENSE
  51619. * file that was distributed with this source code.
  51620. */
  51621. /**
  51622. * Constraint that asserts that a string is valid JSON.
  51623. *
  51624. * @package PHPUnit
  51625. * @subpackage Framework_Constraint
  51626. * @author Sebastian Bergmann <sebastian@phpunit.de>
  51627. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51628. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  51629. * @link http://www.phpunit.de/
  51630. * @since Class available since Release 3.7.20
  51631. */
  51632. class PHPUnit_Framework_Constraint_IsJson extends PHPUnit_Framework_Constraint
  51633. {
  51634. /**
  51635. * Evaluates the constraint for parameter $other. Returns true if the
  51636. * constraint is met, false otherwise.
  51637. *
  51638. * @param mixed $other Value or object to evaluate.
  51639. * @return bool
  51640. */
  51641. protected function matches($other)
  51642. {
  51643. json_decode($other);
  51644. if (json_last_error()) {
  51645. return false;
  51646. }
  51647. return true;
  51648. }
  51649. /**
  51650. * Returns the description of the failure
  51651. *
  51652. * The beginning of failure messages is "Failed asserting that" in most
  51653. * cases. This method should return the second part of that sentence.
  51654. *
  51655. * @param mixed $other Evaluated value or object.
  51656. * @return string
  51657. */
  51658. protected function failureDescription($other)
  51659. {
  51660. json_decode($other);
  51661. $error = PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::determineJsonError(
  51662. json_last_error()
  51663. );
  51664. return sprintf(
  51665. '%s is valid JSON (%s)',
  51666. $this->exporter->shortenedExport($other),
  51667. $error
  51668. );
  51669. }
  51670. /**
  51671. * Returns a string representation of the constraint.
  51672. *
  51673. * @return string
  51674. */
  51675. public function toString()
  51676. {
  51677. return 'is valid JSON';
  51678. }
  51679. }
  51680. <?php
  51681. /*
  51682. * This file is part of PHPUnit.
  51683. *
  51684. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51685. *
  51686. * For the full copyright and license information, please view the LICENSE
  51687. * file that was distributed with this source code.
  51688. */
  51689. /**
  51690. * Constraint that checks if one value is equal to another.
  51691. *
  51692. * Equality is checked with PHP's == operator, the operator is explained in
  51693. * detail at {@url http://www.php.net/manual/en/types.comparisons.php}.
  51694. * Two values are equal if they have the same value disregarding type.
  51695. *
  51696. * The expected value is passed in the constructor.
  51697. *
  51698. * @package PHPUnit
  51699. * @subpackage Framework_Constraint
  51700. * @author Kore Nordmann <kn@ez.no>
  51701. * @author Sebastian Bergmann <sebastian@phpunit.de>
  51702. * @author Bernhard Schussek <bschussek@2bepublished.at>
  51703. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51704. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  51705. * @link http://www.phpunit.de/
  51706. * @since Class available since Release 3.0.0
  51707. */
  51708. class PHPUnit_Framework_Constraint_IsEqual extends PHPUnit_Framework_Constraint
  51709. {
  51710. /**
  51711. * @var mixed
  51712. */
  51713. protected $value;
  51714. /**
  51715. * @var float
  51716. */
  51717. protected $delta = 0.0;
  51718. /**
  51719. * @var integer
  51720. */
  51721. protected $maxDepth = 10;
  51722. /**
  51723. * @var boolean
  51724. */
  51725. protected $canonicalize = false;
  51726. /**
  51727. * @var boolean
  51728. */
  51729. protected $ignoreCase = false;
  51730. /**
  51731. * @var SebastianBergmann\Comparator\ComparisonFailure
  51732. */
  51733. protected $lastFailure;
  51734. /**
  51735. * @param mixed $value
  51736. * @param float $delta
  51737. * @param integer $maxDepth
  51738. * @param boolean $canonicalize
  51739. * @param boolean $ignoreCase
  51740. * @throws PHPUnit_Framework_Exception
  51741. */
  51742. public function __construct($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  51743. {
  51744. parent::__construct();
  51745. if (!is_numeric($delta)) {
  51746. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'numeric');
  51747. }
  51748. if (!is_int($maxDepth)) {
  51749. throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'integer');
  51750. }
  51751. if (!is_bool($canonicalize)) {
  51752. throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean');
  51753. }
  51754. if (!is_bool($ignoreCase)) {
  51755. throw PHPUnit_Util_InvalidArgumentHelper::factory(5, 'boolean');
  51756. }
  51757. $this->value = $value;
  51758. $this->delta = $delta;
  51759. $this->maxDepth = $maxDepth;
  51760. $this->canonicalize = $canonicalize;
  51761. $this->ignoreCase = $ignoreCase;
  51762. }
  51763. /**
  51764. * Evaluates the constraint for parameter $other
  51765. *
  51766. * If $returnResult is set to false (the default), an exception is thrown
  51767. * in case of a failure. null is returned otherwise.
  51768. *
  51769. * If $returnResult is true, the result of the evaluation is returned as
  51770. * a boolean value instead: true in case of success, false in case of a
  51771. * failure.
  51772. *
  51773. * @param mixed $other Value or object to evaluate.
  51774. * @param string $description Additional information about the test
  51775. * @param bool $returnResult Whether to return a result or throw an exception
  51776. * @return mixed
  51777. * @throws PHPUnit_Framework_ExpectationFailedException
  51778. */
  51779. public function evaluate($other, $description = '', $returnResult = false)
  51780. {
  51781. // If $this->value and $other are identical, they are also equal.
  51782. // This is the most common path and will allow us to skip
  51783. // initialization of all the comparators.
  51784. if ($this->value === $other) {
  51785. return true;
  51786. }
  51787. $comparatorFactory = SebastianBergmann\Comparator\Factory::getInstance();
  51788. try {
  51789. $comparator = $comparatorFactory->getComparatorFor(
  51790. $this->value,
  51791. $other
  51792. );
  51793. $comparator->assertEquals(
  51794. $this->value,
  51795. $other,
  51796. $this->delta,
  51797. $this->canonicalize,
  51798. $this->ignoreCase
  51799. );
  51800. } catch (SebastianBergmann\Comparator\ComparisonFailure $f) {
  51801. if ($returnResult) {
  51802. return false;
  51803. }
  51804. throw new PHPUnit_Framework_ExpectationFailedException(
  51805. trim($description . "\n" . $f->getMessage()),
  51806. $f
  51807. );
  51808. }
  51809. return true;
  51810. }
  51811. /**
  51812. * Returns a string representation of the constraint.
  51813. *
  51814. * @return string
  51815. */
  51816. public function toString()
  51817. {
  51818. $delta = '';
  51819. if (is_string($this->value)) {
  51820. if (strpos($this->value, "\n") !== false) {
  51821. return 'is equal to <text>';
  51822. } else {
  51823. return sprintf(
  51824. 'is equal to <string:%s>',
  51825. $this->value
  51826. );
  51827. }
  51828. } else {
  51829. if ($this->delta != 0) {
  51830. $delta = sprintf(
  51831. ' with delta <%F>',
  51832. $this->delta
  51833. );
  51834. }
  51835. return sprintf(
  51836. 'is equal to %s%s',
  51837. $this->exporter->export($this->value),
  51838. $delta
  51839. );
  51840. }
  51841. }
  51842. }
  51843. <?php
  51844. /*
  51845. * This file is part of PHPUnit.
  51846. *
  51847. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51848. *
  51849. * For the full copyright and license information, please view the LICENSE
  51850. * file that was distributed with this source code.
  51851. */
  51852. /**
  51853. * Logical XOR.
  51854. *
  51855. * @package PHPUnit
  51856. * @subpackage Framework_Constraint
  51857. * @author Sebastian Bergmann <sebastian@phpunit.de>
  51858. * @author Bernhard Schussek <bschussek@2bepublished.at>
  51859. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51860. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  51861. * @link http://www.phpunit.de/
  51862. * @since Class available since Release 3.0.0
  51863. */
  51864. class PHPUnit_Framework_Constraint_Xor extends PHPUnit_Framework_Constraint
  51865. {
  51866. /**
  51867. * @var PHPUnit_Framework_Constraint[]
  51868. */
  51869. protected $constraints = array();
  51870. /**
  51871. * @param PHPUnit_Framework_Constraint[] $constraints
  51872. */
  51873. public function setConstraints(array $constraints)
  51874. {
  51875. $this->constraints = array();
  51876. foreach ($constraints as $constraint) {
  51877. if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
  51878. $constraint = new PHPUnit_Framework_Constraint_IsEqual(
  51879. $constraint
  51880. );
  51881. }
  51882. $this->constraints[] = $constraint;
  51883. }
  51884. }
  51885. /**
  51886. * Evaluates the constraint for parameter $other
  51887. *
  51888. * If $returnResult is set to false (the default), an exception is thrown
  51889. * in case of a failure. null is returned otherwise.
  51890. *
  51891. * If $returnResult is true, the result of the evaluation is returned as
  51892. * a boolean value instead: true in case of success, false in case of a
  51893. * failure.
  51894. *
  51895. * @param mixed $other Value or object to evaluate.
  51896. * @param string $description Additional information about the test
  51897. * @param bool $returnResult Whether to return a result or throw an exception
  51898. * @return mixed
  51899. * @throws PHPUnit_Framework_ExpectationFailedException
  51900. */
  51901. public function evaluate($other, $description = '', $returnResult = false)
  51902. {
  51903. $success = true;
  51904. $lastResult = null;
  51905. $constraint = null;
  51906. foreach ($this->constraints as $constraint) {
  51907. $result = $constraint->evaluate($other, $description, true);
  51908. if ($result === $lastResult) {
  51909. $success = false;
  51910. break;
  51911. }
  51912. $lastResult = $result;
  51913. }
  51914. if ($returnResult) {
  51915. return $success;
  51916. }
  51917. if (!$success) {
  51918. $this->fail($other, $description);
  51919. }
  51920. }
  51921. /**
  51922. * Returns a string representation of the constraint.
  51923. *
  51924. * @return string
  51925. */
  51926. public function toString()
  51927. {
  51928. $text = '';
  51929. foreach ($this->constraints as $key => $constraint) {
  51930. if ($key > 0) {
  51931. $text .= ' xor ';
  51932. }
  51933. $text .= $constraint->toString();
  51934. }
  51935. return $text;
  51936. }
  51937. /**
  51938. * Counts the number of constraint elements.
  51939. *
  51940. * @return integer
  51941. * @since Method available since Release 3.4.0
  51942. */
  51943. public function count()
  51944. {
  51945. $count = 0;
  51946. foreach ($this->constraints as $constraint) {
  51947. $count += count($constraint);
  51948. }
  51949. return $count;
  51950. }
  51951. }
  51952. <?php
  51953. /*
  51954. * This file is part of PHPUnit.
  51955. *
  51956. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51957. *
  51958. * For the full copyright and license information, please view the LICENSE
  51959. * file that was distributed with this source code.
  51960. */
  51961. /**
  51962. * Provides human readable messages for each JSON error.
  51963. *
  51964. * @package PHPUnit
  51965. * @subpackage Framework_Constraint
  51966. * @author Bastian Feder <php@bastian-feder.de>
  51967. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  51968. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause
  51969. * @link http://www.phpunit.de/
  51970. * @since Class available since Release 3.7.0
  51971. */
  51972. class PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider
  51973. {
  51974. /**
  51975. * Translates JSON error to a human readable string.
  51976. *
  51977. * @param string $error
  51978. * @param string $prefix
  51979. * @return string
  51980. */
  51981. public static function determineJsonError($error, $prefix = '')
  51982. {
  51983. switch ($error) {
  51984. case JSON_ERROR_NONE:
  51985. return;
  51986. case JSON_ERROR_DEPTH:
  51987. return $prefix . 'Maximum stack depth exceeded';
  51988. case JSON_ERROR_STATE_MISMATCH:
  51989. return $prefix . 'Underflow or the modes mismatch';
  51990. case JSON_ERROR_CTRL_CHAR:
  51991. return $prefix . 'Unexpected control character found';
  51992. case JSON_ERROR_SYNTAX:
  51993. return $prefix . 'Syntax error, malformed JSON';
  51994. case JSON_ERROR_UTF8:
  51995. return $prefix . 'Malformed UTF-8 characters, possibly incorrectly encoded';
  51996. default:
  51997. return $prefix . 'Unknown error';
  51998. }
  51999. }
  52000. /**
  52001. * Translates a given type to a human readable message prefix.
  52002. *
  52003. * @param string $type
  52004. * @return string
  52005. */
  52006. public static function translateTypeToPrefix($type)
  52007. {
  52008. switch (strtolower($type)) {
  52009. case 'expected':
  52010. $prefix = 'Expected value JSON decode error - ';
  52011. break;
  52012. case 'actual':
  52013. $prefix = 'Actual value JSON decode error - ';
  52014. break;
  52015. default:
  52016. $prefix = '';
  52017. break;
  52018. }
  52019. return $prefix;
  52020. }
  52021. }
  52022. <?php
  52023. /*
  52024. * This file is part of PHPUnit.
  52025. *
  52026. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52027. *
  52028. * For the full copyright and license information, please view the LICENSE
  52029. * file that was distributed with this source code.
  52030. */
  52031. use SebastianBergmann\Diff\Differ;
  52032. /**
  52033. * ...
  52034. *
  52035. * @package PHPUnit
  52036. * @subpackage Framework_Constraint
  52037. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52038. * @author Bernhard Schussek <bschussek@2bepublished.at>
  52039. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52040. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52041. * @link http://www.phpunit.de/
  52042. * @since Class available since Release 3.5.0
  52043. */
  52044. class PHPUnit_Framework_Constraint_StringMatches extends PHPUnit_Framework_Constraint_PCREMatch
  52045. {
  52046. /**
  52047. * @var string
  52048. */
  52049. protected $string;
  52050. /**
  52051. * @param string $string
  52052. */
  52053. public function __construct($string)
  52054. {
  52055. parent::__construct($string);
  52056. $this->pattern = $this->createPatternFromFormat(
  52057. preg_replace('/\r\n/', "\n", $string)
  52058. );
  52059. $this->string = $string;
  52060. }
  52061. protected function failureDescription($other)
  52062. {
  52063. return "format description matches text";
  52064. }
  52065. protected function additionalFailureDescription($other)
  52066. {
  52067. $from = preg_split('(\r\n|\r|\n)', $this->string);
  52068. $to = preg_split('(\r\n|\r|\n)', $other);
  52069. foreach ($from as $index => $line) {
  52070. if (isset($to[$index]) && $line !== $to[$index]) {
  52071. $line = $this->createPatternFromFormat($line);
  52072. if (preg_match($line, $to[$index]) > 0) {
  52073. $from[$index] = $to[$index];
  52074. }
  52075. }
  52076. }
  52077. $this->string = implode("\n", $from);
  52078. $other = implode("\n", $to);
  52079. $differ = new Differ("--- Expected\n+++ Actual\n");
  52080. return $differ->diff($this->string, $other);
  52081. }
  52082. protected function createPatternFromFormat($string)
  52083. {
  52084. $string = str_replace(
  52085. array(
  52086. '%e',
  52087. '%s',
  52088. '%S',
  52089. '%a',
  52090. '%A',
  52091. '%w',
  52092. '%i',
  52093. '%d',
  52094. '%x',
  52095. '%f',
  52096. '%c'
  52097. ),
  52098. array(
  52099. '\\' . DIRECTORY_SEPARATOR,
  52100. '[^\r\n]+',
  52101. '[^\r\n]*',
  52102. '.+',
  52103. '.*',
  52104. '\s*',
  52105. '[+-]?\d+',
  52106. '\d+',
  52107. '[0-9a-fA-F]+',
  52108. '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?',
  52109. '.'
  52110. ),
  52111. preg_quote($string, '/')
  52112. );
  52113. return '/^' . $string . '$/s';
  52114. }
  52115. }
  52116. <?php
  52117. /*
  52118. * This file is part of PHPUnit.
  52119. *
  52120. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52121. *
  52122. * For the full copyright and license information, please view the LICENSE
  52123. * file that was distributed with this source code.
  52124. */
  52125. /**
  52126. * Logical NOT.
  52127. *
  52128. * @package PHPUnit
  52129. * @subpackage Framework_Constraint
  52130. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52131. * @author Bernhard Schussek <bschussek@2bepublished.at>
  52132. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52133. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52134. * @link http://www.phpunit.de/
  52135. * @since Class available since Release 3.0.0
  52136. */
  52137. class PHPUnit_Framework_Constraint_Not extends PHPUnit_Framework_Constraint
  52138. {
  52139. /**
  52140. * @var PHPUnit_Framework_Constraint
  52141. */
  52142. protected $constraint;
  52143. /**
  52144. * @param PHPUnit_Framework_Constraint $constraint
  52145. */
  52146. public function __construct($constraint)
  52147. {
  52148. parent::__construct();
  52149. if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
  52150. $constraint = new PHPUnit_Framework_Constraint_IsEqual($constraint);
  52151. }
  52152. $this->constraint = $constraint;
  52153. }
  52154. /**
  52155. * @param string $string
  52156. * @return string
  52157. */
  52158. public static function negate($string)
  52159. {
  52160. return str_replace(
  52161. array(
  52162. 'contains ',
  52163. 'exists',
  52164. 'has ',
  52165. 'is ',
  52166. 'are ',
  52167. 'matches ',
  52168. 'starts with ',
  52169. 'ends with ',
  52170. 'reference ',
  52171. 'not not '
  52172. ),
  52173. array(
  52174. 'does not contain ',
  52175. 'does not exist',
  52176. 'does not have ',
  52177. 'is not ',
  52178. 'are not ',
  52179. 'does not match ',
  52180. 'starts not with ',
  52181. 'ends not with ',
  52182. 'don\'t reference ',
  52183. 'not '
  52184. ),
  52185. $string
  52186. );
  52187. }
  52188. /**
  52189. * Evaluates the constraint for parameter $other
  52190. *
  52191. * If $returnResult is set to false (the default), an exception is thrown
  52192. * in case of a failure. null is returned otherwise.
  52193. *
  52194. * If $returnResult is true, the result of the evaluation is returned as
  52195. * a boolean value instead: true in case of success, false in case of a
  52196. * failure.
  52197. *
  52198. * @param mixed $other Value or object to evaluate.
  52199. * @param string $description Additional information about the test
  52200. * @param bool $returnResult Whether to return a result or throw an exception
  52201. * @return mixed
  52202. * @throws PHPUnit_Framework_ExpectationFailedException
  52203. */
  52204. public function evaluate($other, $description = '', $returnResult = false)
  52205. {
  52206. $success = !$this->constraint->evaluate($other, $description, true);
  52207. if ($returnResult) {
  52208. return $success;
  52209. }
  52210. if (!$success) {
  52211. $this->fail($other, $description);
  52212. }
  52213. }
  52214. /**
  52215. * Returns the description of the failure
  52216. *
  52217. * The beginning of failure messages is "Failed asserting that" in most
  52218. * cases. This method should return the second part of that sentence.
  52219. *
  52220. * @param mixed $other Evaluated value or object.
  52221. * @return string
  52222. */
  52223. protected function failureDescription($other)
  52224. {
  52225. switch (get_class($this->constraint)) {
  52226. case 'PHPUnit_Framework_Constraint_And':
  52227. case 'PHPUnit_Framework_Constraint_Not':
  52228. case 'PHPUnit_Framework_Constraint_Or': {
  52229. return 'not( ' . $this->constraint->failureDescription($other) . ' )';
  52230. }
  52231. break;
  52232. default: {
  52233. return self::negate(
  52234. $this->constraint->failureDescription($other)
  52235. );
  52236. }
  52237. }
  52238. }
  52239. /**
  52240. * Returns a string representation of the constraint.
  52241. *
  52242. * @return string
  52243. */
  52244. public function toString()
  52245. {
  52246. switch (get_class($this->constraint)) {
  52247. case 'PHPUnit_Framework_Constraint_And':
  52248. case 'PHPUnit_Framework_Constraint_Not':
  52249. case 'PHPUnit_Framework_Constraint_Or': {
  52250. return 'not( ' . $this->constraint->toString() . ' )';
  52251. }
  52252. break;
  52253. default: {
  52254. return self::negate(
  52255. $this->constraint->toString()
  52256. );
  52257. }
  52258. }
  52259. }
  52260. /**
  52261. * Counts the number of constraint elements.
  52262. *
  52263. * @return integer
  52264. * @since Method available since Release 3.4.0
  52265. */
  52266. public function count()
  52267. {
  52268. return count($this->constraint);
  52269. }
  52270. }
  52271. <?php
  52272. /*
  52273. * This file is part of PHPUnit.
  52274. *
  52275. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52276. *
  52277. * For the full copyright and license information, please view the LICENSE
  52278. * file that was distributed with this source code.
  52279. */
  52280. /**
  52281. *
  52282. *
  52283. * @package PHPUnit
  52284. * @subpackage Framework_Constraint
  52285. * @author Márcio Almada <marcio3w@gmail.com>
  52286. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52287. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52288. * @link http://www.phpunit.de/
  52289. * @since Class available since Release 4.3.0
  52290. */
  52291. class PHPUnit_Framework_Constraint_ExceptionMessageRegExp extends PHPUnit_Framework_Constraint
  52292. {
  52293. /**
  52294. * @var integer
  52295. */
  52296. protected $expectedMessageRegExp;
  52297. /**
  52298. * @param string $expected
  52299. */
  52300. public function __construct($expected)
  52301. {
  52302. parent::__construct();
  52303. $this->expectedMessageRegExp = $expected;
  52304. }
  52305. /**
  52306. * Evaluates the constraint for parameter $other. Returns true if the
  52307. * constraint is met, false otherwise.
  52308. *
  52309. * @param Exception $other
  52310. * @return boolean
  52311. */
  52312. protected function matches($other)
  52313. {
  52314. $match = PHPUnit_Util_Regex::pregMatchSafe($this->expectedMessageRegExp, $other->getMessage());
  52315. if (false === $match) {
  52316. throw new PHPUnit_Framework_Exception(
  52317. "Invalid expected exception message regex given: '{$this->expectedMessageRegExp}'"
  52318. );
  52319. }
  52320. return 1 === $match;
  52321. }
  52322. /**
  52323. * Returns the description of the failure
  52324. *
  52325. * The beginning of failure messages is "Failed asserting that" in most
  52326. * cases. This method should return the second part of that sentence.
  52327. *
  52328. * @param mixed $other Evaluated value or object.
  52329. * @return string
  52330. */
  52331. protected function failureDescription($other)
  52332. {
  52333. return sprintf(
  52334. "exception message '%s' matches '%s'",
  52335. $other->getMessage(),
  52336. $this->expectedMessageRegExp
  52337. );
  52338. }
  52339. /**
  52340. * @return string
  52341. */
  52342. public function toString()
  52343. {
  52344. return "exception message matches ";
  52345. }
  52346. }
  52347. <?php
  52348. /*
  52349. * This file is part of PHPUnit.
  52350. *
  52351. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52352. *
  52353. * For the full copyright and license information, please view the LICENSE
  52354. * file that was distributed with this source code.
  52355. */
  52356. /**
  52357. * Constraint that asserts that the value it is evaluated for is greater
  52358. * than a given value.
  52359. *
  52360. * @package PHPUnit
  52361. * @subpackage Framework_Constraint
  52362. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52363. * @author Bernhard Schussek <bschussek@2bepublished.at>
  52364. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52365. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52366. * @link http://www.phpunit.de/
  52367. * @since Class available since Release 3.0.0
  52368. */
  52369. class PHPUnit_Framework_Constraint_GreaterThan extends PHPUnit_Framework_Constraint
  52370. {
  52371. /**
  52372. * @var numeric
  52373. */
  52374. protected $value;
  52375. /**
  52376. * @param numeric $value
  52377. */
  52378. public function __construct($value)
  52379. {
  52380. parent::__construct();
  52381. $this->value = $value;
  52382. }
  52383. /**
  52384. * Evaluates the constraint for parameter $other. Returns true if the
  52385. * constraint is met, false otherwise.
  52386. *
  52387. * @param mixed $other Value or object to evaluate.
  52388. * @return bool
  52389. */
  52390. protected function matches($other)
  52391. {
  52392. return $this->value < $other;
  52393. }
  52394. /**
  52395. * Returns a string representation of the constraint.
  52396. *
  52397. * @return string
  52398. */
  52399. public function toString()
  52400. {
  52401. return 'is greater than ' . $this->exporter->export($this->value);
  52402. }
  52403. }
  52404. <?php
  52405. /*
  52406. * This file is part of PHPUnit.
  52407. *
  52408. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52409. *
  52410. * For the full copyright and license information, please view the LICENSE
  52411. * file that was distributed with this source code.
  52412. */
  52413. /**
  52414. *
  52415. *
  52416. * @package PHPUnit
  52417. * @subpackage Framework_Constraint
  52418. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52419. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52420. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52421. * @link http://www.phpunit.de/
  52422. * @since Class available since Release 3.6.6
  52423. */
  52424. class PHPUnit_Framework_Constraint_ExceptionMessage extends PHPUnit_Framework_Constraint
  52425. {
  52426. /**
  52427. * @var integer
  52428. */
  52429. protected $expectedMessage;
  52430. /**
  52431. * @param string $expected
  52432. */
  52433. public function __construct($expected)
  52434. {
  52435. parent::__construct();
  52436. $this->expectedMessage = $expected;
  52437. }
  52438. /**
  52439. * Evaluates the constraint for parameter $other. Returns true if the
  52440. * constraint is met, false otherwise.
  52441. *
  52442. * @param Exception $other
  52443. * @return boolean
  52444. */
  52445. protected function matches($other)
  52446. {
  52447. return strpos($other->getMessage(), $this->expectedMessage) !== false;
  52448. }
  52449. /**
  52450. * Returns the description of the failure
  52451. *
  52452. * The beginning of failure messages is "Failed asserting that" in most
  52453. * cases. This method should return the second part of that sentence.
  52454. *
  52455. * @param mixed $other Evaluated value or object.
  52456. * @return string
  52457. */
  52458. protected function failureDescription($other)
  52459. {
  52460. return sprintf(
  52461. "exception message '%s' contains '%s'",
  52462. $other->getMessage(),
  52463. $this->expectedMessage
  52464. );
  52465. }
  52466. /**
  52467. * @return string
  52468. */
  52469. public function toString()
  52470. {
  52471. return 'exception message contains ';
  52472. }
  52473. }
  52474. <?php
  52475. /*
  52476. * This file is part of PHPUnit.
  52477. *
  52478. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52479. *
  52480. * For the full copyright and license information, please view the LICENSE
  52481. * file that was distributed with this source code.
  52482. */
  52483. /**
  52484. * Constraint that evaluates against a specified closure.
  52485. *
  52486. * @package PHPUnit
  52487. * @subpackage Framework_Constraint
  52488. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52489. * @author Timon Rapp <timon@zaeda.net>
  52490. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52491. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52492. * @link http://www.phpunit.de/
  52493. */
  52494. class PHPUnit_Framework_Constraint_Callback extends PHPUnit_Framework_Constraint
  52495. {
  52496. private $callback;
  52497. /**
  52498. * @param callable $callback
  52499. * @throws PHPUnit_Framework_Exception
  52500. */
  52501. public function __construct($callback)
  52502. {
  52503. if (!is_callable($callback)) {
  52504. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  52505. 1,
  52506. 'callable'
  52507. );
  52508. }
  52509. parent::__construct();
  52510. $this->callback = $callback;
  52511. }
  52512. /**
  52513. * Evaluates the constraint for parameter $value. Returns true if the
  52514. * constraint is met, false otherwise.
  52515. *
  52516. * @param mixed $other Value or object to evaluate.
  52517. * @return bool
  52518. */
  52519. protected function matches($other)
  52520. {
  52521. return call_user_func($this->callback, $other);
  52522. }
  52523. /**
  52524. * Returns a string representation of the constraint.
  52525. *
  52526. * @return string
  52527. */
  52528. public function toString()
  52529. {
  52530. return 'is accepted by specified callback';
  52531. }
  52532. }
  52533. <?php
  52534. /*
  52535. * This file is part of PHPUnit.
  52536. *
  52537. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52538. *
  52539. * For the full copyright and license information, please view the LICENSE
  52540. * file that was distributed with this source code.
  52541. */
  52542. /**
  52543. * Constraint that asserts that the array it is evaluated for has a given key.
  52544. *
  52545. * Uses array_key_exists() to check if the key is found in the input array, if
  52546. * not found the evaluation fails.
  52547. *
  52548. * The array key is passed in the constructor.
  52549. *
  52550. * @package PHPUnit
  52551. * @subpackage Framework_Constraint
  52552. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52553. * @author Bernhard Schussek <bschussek@2bepublished.at>
  52554. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52555. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52556. * @link http://www.phpunit.de/
  52557. * @since Class available since Release 3.0.0
  52558. */
  52559. class PHPUnit_Framework_Constraint_ArrayHasKey extends PHPUnit_Framework_Constraint
  52560. {
  52561. /**
  52562. * @var integer|string
  52563. */
  52564. protected $key;
  52565. /**
  52566. * @param integer|string $key
  52567. */
  52568. public function __construct($key)
  52569. {
  52570. parent::__construct();
  52571. $this->key = $key;
  52572. }
  52573. /**
  52574. * Evaluates the constraint for parameter $other. Returns true if the
  52575. * constraint is met, false otherwise.
  52576. *
  52577. * @param mixed $other Value or object to evaluate.
  52578. * @return bool
  52579. */
  52580. protected function matches($other)
  52581. {
  52582. if (is_array($other)) {
  52583. return array_key_exists($this->key, $other);
  52584. }
  52585. if ($other instanceof ArrayAccess) {
  52586. return $other->offsetExists($this->key);
  52587. }
  52588. return false;
  52589. }
  52590. /**
  52591. * Returns a string representation of the constraint.
  52592. *
  52593. * @return string
  52594. */
  52595. public function toString()
  52596. {
  52597. return 'has the key ' . $this->exporter->export($this->key);
  52598. }
  52599. /**
  52600. * Returns the description of the failure
  52601. *
  52602. * The beginning of failure messages is "Failed asserting that" in most
  52603. * cases. This method should return the second part of that sentence.
  52604. *
  52605. * @param mixed $other Evaluated value or object.
  52606. * @return string
  52607. */
  52608. protected function failureDescription($other)
  52609. {
  52610. return 'an array ' . $this->toString();
  52611. }
  52612. }
  52613. <?php
  52614. /*
  52615. * This file is part of PHPUnit.
  52616. *
  52617. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52618. *
  52619. * For the full copyright and license information, please view the LICENSE
  52620. * file that was distributed with this source code.
  52621. */
  52622. /**
  52623. * Constraint that asserts that the string it is evaluated for contains
  52624. * a given string.
  52625. *
  52626. * Uses strpos() to find the position of the string in the input, if not found
  52627. * the evaluation fails.
  52628. *
  52629. * The sub-string is passed in the constructor.
  52630. *
  52631. * @package PHPUnit
  52632. * @subpackage Framework_Constraint
  52633. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52634. * @author Bernhard Schussek <bschussek@2bepublished.at>
  52635. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52636. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52637. * @link http://www.phpunit.de/
  52638. * @since Class available since Release 3.0.0
  52639. */
  52640. class PHPUnit_Framework_Constraint_StringContains extends PHPUnit_Framework_Constraint
  52641. {
  52642. /**
  52643. * @var string
  52644. */
  52645. protected $string;
  52646. /**
  52647. * @var boolean
  52648. */
  52649. protected $ignoreCase;
  52650. /**
  52651. * @param string $string
  52652. * @param boolean $ignoreCase
  52653. */
  52654. public function __construct($string, $ignoreCase = false)
  52655. {
  52656. parent::__construct();
  52657. $this->string = $string;
  52658. $this->ignoreCase = $ignoreCase;
  52659. }
  52660. /**
  52661. * Evaluates the constraint for parameter $other. Returns true if the
  52662. * constraint is met, false otherwise.
  52663. *
  52664. * @param mixed $other Value or object to evaluate.
  52665. * @return bool
  52666. */
  52667. protected function matches($other)
  52668. {
  52669. if ($this->ignoreCase) {
  52670. return stripos($other, $this->string) !== false;
  52671. } else {
  52672. return strpos($other, $this->string) !== false;
  52673. }
  52674. }
  52675. /**
  52676. * Returns a string representation of the constraint.
  52677. *
  52678. * @return string
  52679. */
  52680. public function toString()
  52681. {
  52682. if ($this->ignoreCase) {
  52683. $string = strtolower($this->string);
  52684. } else {
  52685. $string = $this->string;
  52686. }
  52687. return sprintf(
  52688. 'contains "%s"',
  52689. $string
  52690. );
  52691. }
  52692. }
  52693. <?php
  52694. /*
  52695. * This file is part of PHPUnit.
  52696. *
  52697. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52698. *
  52699. * For the full copyright and license information, please view the LICENSE
  52700. * file that was distributed with this source code.
  52701. */
  52702. /**
  52703. * Constraint that asserts that the Traversable it is applied to contains
  52704. * only values of a given type.
  52705. *
  52706. * @package PHPUnit
  52707. * @subpackage Framework_Constraint
  52708. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52709. * @author Bernhard Schussek <bschussek@2bepublished.at>
  52710. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52711. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52712. * @link http://www.phpunit.de/
  52713. * @since Class available since Release 3.1.4
  52714. */
  52715. class PHPUnit_Framework_Constraint_TraversableContainsOnly extends PHPUnit_Framework_Constraint
  52716. {
  52717. /**
  52718. * @var PHPUnit_Framework_Constraint
  52719. */
  52720. protected $constraint;
  52721. /**
  52722. * @var string
  52723. */
  52724. protected $type;
  52725. /**
  52726. * @param string $type
  52727. * @param boolean $isNativeType
  52728. */
  52729. public function __construct($type, $isNativeType = true)
  52730. {
  52731. parent::__construct();
  52732. if ($isNativeType) {
  52733. $this->constraint = new PHPUnit_Framework_Constraint_IsType($type);
  52734. } else {
  52735. $this->constraint = new PHPUnit_Framework_Constraint_IsInstanceOf(
  52736. $type
  52737. );
  52738. }
  52739. $this->type = $type;
  52740. }
  52741. /**
  52742. * Evaluates the constraint for parameter $other
  52743. *
  52744. * If $returnResult is set to false (the default), an exception is thrown
  52745. * in case of a failure. null is returned otherwise.
  52746. *
  52747. * If $returnResult is true, the result of the evaluation is returned as
  52748. * a boolean value instead: true in case of success, false in case of a
  52749. * failure.
  52750. *
  52751. * @param mixed $other Value or object to evaluate.
  52752. * @param string $description Additional information about the test
  52753. * @param bool $returnResult Whether to return a result or throw an exception
  52754. * @return mixed
  52755. * @throws PHPUnit_Framework_ExpectationFailedException
  52756. */
  52757. public function evaluate($other, $description = '', $returnResult = false)
  52758. {
  52759. $success = true;
  52760. foreach ($other as $item) {
  52761. if (!$this->constraint->evaluate($item, '', true)) {
  52762. $success = false;
  52763. break;
  52764. }
  52765. }
  52766. if ($returnResult) {
  52767. return $success;
  52768. }
  52769. if (!$success) {
  52770. $this->fail($other, $description);
  52771. }
  52772. }
  52773. /**
  52774. * Returns a string representation of the constraint.
  52775. *
  52776. * @return string
  52777. */
  52778. public function toString()
  52779. {
  52780. return 'contains only values of type "' . $this->type . '"';
  52781. }
  52782. }
  52783. <?php
  52784. /*
  52785. * This file is part of PHPUnit.
  52786. *
  52787. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52788. *
  52789. * For the full copyright and license information, please view the LICENSE
  52790. * file that was distributed with this source code.
  52791. */
  52792. /**
  52793. * Constraint that checks whether a variable is empty().
  52794. *
  52795. * @package PHPUnit
  52796. * @subpackage Framework_Constraint
  52797. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52798. * @author Bernhard Schussek <bschussek@2bepublished.at>
  52799. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52800. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52801. * @link http://www.phpunit.de/
  52802. * @since Class available since Release 3.5.0
  52803. */
  52804. class PHPUnit_Framework_Constraint_IsEmpty extends PHPUnit_Framework_Constraint
  52805. {
  52806. /**
  52807. * Evaluates the constraint for parameter $other. Returns true if the
  52808. * constraint is met, false otherwise.
  52809. *
  52810. * @param mixed $other Value or object to evaluate.
  52811. * @return bool
  52812. */
  52813. protected function matches($other)
  52814. {
  52815. if ($other instanceof Countable) {
  52816. return count($other) === 0;
  52817. }
  52818. return empty($other);
  52819. }
  52820. /**
  52821. * Returns a string representation of the constraint.
  52822. *
  52823. * @return string
  52824. */
  52825. public function toString()
  52826. {
  52827. return 'is empty';
  52828. }
  52829. /**
  52830. * Returns the description of the failure
  52831. *
  52832. * The beginning of failure messages is "Failed asserting that" in most
  52833. * cases. This method should return the second part of that sentence.
  52834. *
  52835. * @param mixed $other Evaluated value or object.
  52836. * @return string
  52837. */
  52838. protected function failureDescription($other)
  52839. {
  52840. $type = gettype($other);
  52841. return sprintf(
  52842. '%s %s %s',
  52843. $type[0] == 'a' || $type[0] == 'o' ? 'an' : 'a',
  52844. $type,
  52845. $this->toString()
  52846. );
  52847. }
  52848. }
  52849. <?php
  52850. /*
  52851. * This file is part of PHPUnit.
  52852. *
  52853. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52854. *
  52855. * For the full copyright and license information, please view the LICENSE
  52856. * file that was distributed with this source code.
  52857. */
  52858. /**
  52859. * Constraint that asserts that the string it is evaluated for matches
  52860. * a regular expression.
  52861. *
  52862. * Checks a given value using the Perl Compatible Regular Expression extension
  52863. * in PHP. The pattern is matched by executing preg_match().
  52864. *
  52865. * The pattern string passed in the constructor.
  52866. *
  52867. * @package PHPUnit
  52868. * @subpackage Framework_Constraint
  52869. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52870. * @author Bernhard Schussek <bschussek@2bepublished.at>
  52871. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52872. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52873. * @link http://www.phpunit.de/
  52874. * @since Class available since Release 3.0.0
  52875. */
  52876. class PHPUnit_Framework_Constraint_PCREMatch extends PHPUnit_Framework_Constraint
  52877. {
  52878. /**
  52879. * @var string
  52880. */
  52881. protected $pattern;
  52882. /**
  52883. * @param string $pattern
  52884. */
  52885. public function __construct($pattern)
  52886. {
  52887. parent::__construct();
  52888. $this->pattern = $pattern;
  52889. }
  52890. /**
  52891. * Evaluates the constraint for parameter $other. Returns true if the
  52892. * constraint is met, false otherwise.
  52893. *
  52894. * @param mixed $other Value or object to evaluate.
  52895. * @return bool
  52896. */
  52897. protected function matches($other)
  52898. {
  52899. return preg_match($this->pattern, $other) > 0;
  52900. }
  52901. /**
  52902. * Returns a string representation of the constraint.
  52903. *
  52904. * @return string
  52905. */
  52906. public function toString()
  52907. {
  52908. return sprintf(
  52909. 'matches PCRE pattern "%s"',
  52910. $this->pattern
  52911. );
  52912. }
  52913. }
  52914. <?php
  52915. /*
  52916. * This file is part of PHPUnit.
  52917. *
  52918. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52919. *
  52920. * For the full copyright and license information, please view the LICENSE
  52921. * file that was distributed with this source code.
  52922. */
  52923. /**
  52924. * Constraint that accepts null.
  52925. *
  52926. * @package PHPUnit
  52927. * @subpackage Framework_Constraint
  52928. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52929. * @author Bernhard Schussek <bschussek@2bepublished.at>
  52930. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52931. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52932. * @link http://www.phpunit.de/
  52933. * @since Class available since Release 3.3.0
  52934. */
  52935. class PHPUnit_Framework_Constraint_IsNull extends PHPUnit_Framework_Constraint
  52936. {
  52937. /**
  52938. * Evaluates the constraint for parameter $other. Returns true if the
  52939. * constraint is met, false otherwise.
  52940. *
  52941. * @param mixed $other Value or object to evaluate.
  52942. * @return bool
  52943. */
  52944. protected function matches($other)
  52945. {
  52946. return $other === null;
  52947. }
  52948. /**
  52949. * Returns a string representation of the constraint.
  52950. *
  52951. * @return string
  52952. */
  52953. public function toString()
  52954. {
  52955. return 'is null';
  52956. }
  52957. }
  52958. <?php
  52959. /*
  52960. * This file is part of PHPUnit.
  52961. *
  52962. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52963. *
  52964. * For the full copyright and license information, please view the LICENSE
  52965. * file that was distributed with this source code.
  52966. */
  52967. /**
  52968. * @package PHPUnit
  52969. * @subpackage Framework_Constraint
  52970. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52971. * @author Bernhard Schussek <bschussek@2bepublished.at>
  52972. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  52973. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  52974. * @link http://www.phpunit.de/
  52975. * @since Class available since Release 3.1.0
  52976. */
  52977. class PHPUnit_Framework_Constraint_Attribute extends PHPUnit_Framework_Constraint_Composite
  52978. {
  52979. /**
  52980. * @var string
  52981. */
  52982. protected $attributeName;
  52983. /**
  52984. * @param PHPUnit_Framework_Constraint $constraint
  52985. * @param string $attributeName
  52986. */
  52987. public function __construct(PHPUnit_Framework_Constraint $constraint, $attributeName)
  52988. {
  52989. parent::__construct($constraint);
  52990. $this->attributeName = $attributeName;
  52991. }
  52992. /**
  52993. * Evaluates the constraint for parameter $other
  52994. *
  52995. * If $returnResult is set to false (the default), an exception is thrown
  52996. * in case of a failure. null is returned otherwise.
  52997. *
  52998. * If $returnResult is true, the result of the evaluation is returned as
  52999. * a boolean value instead: true in case of success, false in case of a
  53000. * failure.
  53001. *
  53002. * @param mixed $other Value or object to evaluate.
  53003. * @param string $description Additional information about the test
  53004. * @param bool $returnResult Whether to return a result or throw an exception
  53005. * @return mixed
  53006. * @throws PHPUnit_Framework_ExpectationFailedException
  53007. */
  53008. public function evaluate($other, $description = '', $returnResult = false)
  53009. {
  53010. return parent::evaluate(
  53011. PHPUnit_Framework_Assert::readAttribute(
  53012. $other,
  53013. $this->attributeName
  53014. ),
  53015. $description,
  53016. $returnResult
  53017. );
  53018. }
  53019. /**
  53020. * Returns a string representation of the constraint.
  53021. *
  53022. * @return string
  53023. */
  53024. public function toString()
  53025. {
  53026. return 'attribute "' . $this->attributeName . '" ' .
  53027. $this->innerConstraint->toString();
  53028. }
  53029. /**
  53030. * Returns the description of the failure
  53031. *
  53032. * The beginning of failure messages is "Failed asserting that" in most
  53033. * cases. This method should return the second part of that sentence.
  53034. *
  53035. * @param mixed $other Evaluated value or object.
  53036. * @return string
  53037. */
  53038. protected function failureDescription($other)
  53039. {
  53040. return $this->toString();
  53041. }
  53042. }
  53043. <?php
  53044. /*
  53045. * This file is part of PHPUnit.
  53046. *
  53047. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53048. *
  53049. * For the full copyright and license information, please view the LICENSE
  53050. * file that was distributed with this source code.
  53051. */
  53052. /**
  53053. * Constraint that accepts false.
  53054. *
  53055. * @package PHPUnit
  53056. * @subpackage Framework_Constraint
  53057. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53058. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53059. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53060. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53061. * @link http://www.phpunit.de/
  53062. * @since Class available since Release 3.3.0
  53063. */
  53064. class PHPUnit_Framework_Constraint_IsFalse extends PHPUnit_Framework_Constraint
  53065. {
  53066. /**
  53067. * Evaluates the constraint for parameter $other. Returns true if the
  53068. * constraint is met, false otherwise.
  53069. *
  53070. * @param mixed $other Value or object to evaluate.
  53071. * @return bool
  53072. */
  53073. protected function matches($other)
  53074. {
  53075. return $other === false;
  53076. }
  53077. /**
  53078. * Returns a string representation of the constraint.
  53079. *
  53080. * @return string
  53081. */
  53082. public function toString()
  53083. {
  53084. return 'is false';
  53085. }
  53086. }
  53087. <?php
  53088. /*
  53089. * This file is part of PHPUnit.
  53090. *
  53091. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53092. *
  53093. * For the full copyright and license information, please view the LICENSE
  53094. * file that was distributed with this source code.
  53095. */
  53096. /**
  53097. * Constraint that asserts that the class it is evaluated for has a given
  53098. * static attribute.
  53099. *
  53100. * The attribute name is passed in the constructor.
  53101. *
  53102. * @package PHPUnit
  53103. * @subpackage Framework_Constraint
  53104. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53105. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53106. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53107. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53108. * @link http://www.phpunit.de/
  53109. * @since Class available since Release 3.1.0
  53110. */
  53111. class PHPUnit_Framework_Constraint_ClassHasStaticAttribute extends PHPUnit_Framework_Constraint_ClassHasAttribute
  53112. {
  53113. /**
  53114. * Evaluates the constraint for parameter $other. Returns true if the
  53115. * constraint is met, false otherwise.
  53116. *
  53117. * @param mixed $other Value or object to evaluate.
  53118. * @return bool
  53119. */
  53120. protected function matches($other)
  53121. {
  53122. $class = new ReflectionClass($other);
  53123. if ($class->hasProperty($this->attributeName)) {
  53124. $attribute = $class->getProperty($this->attributeName);
  53125. return $attribute->isStatic();
  53126. } else {
  53127. return false;
  53128. }
  53129. }
  53130. /**
  53131. * Returns a string representation of the constraint.
  53132. *
  53133. * @return string
  53134. * @since Method available since Release 3.3.0
  53135. */
  53136. public function toString()
  53137. {
  53138. return sprintf(
  53139. 'has static attribute "%s"',
  53140. $this->attributeName
  53141. );
  53142. }
  53143. }
  53144. <?php
  53145. /*
  53146. * This file is part of PHPUnit.
  53147. *
  53148. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53149. *
  53150. * For the full copyright and license information, please view the LICENSE
  53151. * file that was distributed with this source code.
  53152. */
  53153. /**
  53154. * Logical OR.
  53155. *
  53156. * @package PHPUnit
  53157. * @subpackage Framework_Constraint
  53158. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53159. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53160. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53161. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53162. * @link http://www.phpunit.de/
  53163. * @since Class available since Release 3.0.0
  53164. */
  53165. class PHPUnit_Framework_Constraint_Or extends PHPUnit_Framework_Constraint
  53166. {
  53167. /**
  53168. * @var PHPUnit_Framework_Constraint[]
  53169. */
  53170. protected $constraints = array();
  53171. /**
  53172. * @param PHPUnit_Framework_Constraint[] $constraints
  53173. */
  53174. public function setConstraints(array $constraints)
  53175. {
  53176. $this->constraints = array();
  53177. foreach ($constraints as $constraint) {
  53178. if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
  53179. $constraint = new PHPUnit_Framework_Constraint_IsEqual(
  53180. $constraint
  53181. );
  53182. }
  53183. $this->constraints[] = $constraint;
  53184. }
  53185. }
  53186. /**
  53187. * Evaluates the constraint for parameter $other
  53188. *
  53189. * If $returnResult is set to false (the default), an exception is thrown
  53190. * in case of a failure. null is returned otherwise.
  53191. *
  53192. * If $returnResult is true, the result of the evaluation is returned as
  53193. * a boolean value instead: true in case of success, false in case of a
  53194. * failure.
  53195. *
  53196. * @param mixed $other Value or object to evaluate.
  53197. * @param string $description Additional information about the test
  53198. * @param bool $returnResult Whether to return a result or throw an exception
  53199. * @return mixed
  53200. * @throws PHPUnit_Framework_ExpectationFailedException
  53201. */
  53202. public function evaluate($other, $description = '', $returnResult = false)
  53203. {
  53204. $success = false;
  53205. $constraint = null;
  53206. foreach ($this->constraints as $constraint) {
  53207. if ($constraint->evaluate($other, $description, true)) {
  53208. $success = true;
  53209. break;
  53210. }
  53211. }
  53212. if ($returnResult) {
  53213. return $success;
  53214. }
  53215. if (!$success) {
  53216. $this->fail($other, $description);
  53217. }
  53218. }
  53219. /**
  53220. * Returns a string representation of the constraint.
  53221. *
  53222. * @return string
  53223. */
  53224. public function toString()
  53225. {
  53226. $text = '';
  53227. foreach ($this->constraints as $key => $constraint) {
  53228. if ($key > 0) {
  53229. $text .= ' or ';
  53230. }
  53231. $text .= $constraint->toString();
  53232. }
  53233. return $text;
  53234. }
  53235. /**
  53236. * Counts the number of constraint elements.
  53237. *
  53238. * @return integer
  53239. * @since Method available since Release 3.4.0
  53240. */
  53241. public function count()
  53242. {
  53243. $count = 0;
  53244. foreach ($this->constraints as $constraint) {
  53245. $count += count($constraint);
  53246. }
  53247. return $count;
  53248. }
  53249. }
  53250. <?php
  53251. /*
  53252. * This file is part of PHPUnit.
  53253. *
  53254. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53255. *
  53256. * For the full copyright and license information, please view the LICENSE
  53257. * file that was distributed with this source code.
  53258. */
  53259. /**
  53260. * Constraint that asserts that one value is identical to another.
  53261. *
  53262. * Identical check is performed with PHP's === operator, the operator is
  53263. * explained in detail at
  53264. * {@url http://www.php.net/manual/en/types.comparisons.php}.
  53265. * Two values are identical if they have the same value and are of the same
  53266. * type.
  53267. *
  53268. * The expected value is passed in the constructor.
  53269. *
  53270. * @package PHPUnit
  53271. * @subpackage Framework_Constraint
  53272. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53273. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53274. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53275. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53276. * @link http://www.phpunit.de/
  53277. * @since Class available since Release 3.0.0
  53278. */
  53279. class PHPUnit_Framework_Constraint_IsIdentical extends PHPUnit_Framework_Constraint
  53280. {
  53281. /**
  53282. * @var float
  53283. */
  53284. const EPSILON = 0.0000000001;
  53285. /**
  53286. * @var mixed
  53287. */
  53288. protected $value;
  53289. /**
  53290. * @param mixed $value
  53291. */
  53292. public function __construct($value)
  53293. {
  53294. parent::__construct();
  53295. $this->value = $value;
  53296. }
  53297. /**
  53298. * Evaluates the constraint for parameter $other
  53299. *
  53300. * If $returnResult is set to false (the default), an exception is thrown
  53301. * in case of a failure. null is returned otherwise.
  53302. *
  53303. * If $returnResult is true, the result of the evaluation is returned as
  53304. * a boolean value instead: true in case of success, false in case of a
  53305. * failure.
  53306. *
  53307. * @param mixed $other Value or object to evaluate.
  53308. * @param string $description Additional information about the test
  53309. * @param bool $returnResult Whether to return a result or throw an exception
  53310. * @return mixed
  53311. * @throws PHPUnit_Framework_ExpectationFailedException
  53312. */
  53313. public function evaluate($other, $description = '', $returnResult = false)
  53314. {
  53315. if (is_double($this->value) && is_double($other) &&
  53316. !is_infinite($this->value) && !is_infinite($other) &&
  53317. !is_nan($this->value) && !is_nan($other)) {
  53318. $success = abs($this->value - $other) < self::EPSILON;
  53319. } else {
  53320. $success = $this->value === $other;
  53321. }
  53322. if ($returnResult) {
  53323. return $success;
  53324. }
  53325. if (!$success) {
  53326. $f = null;
  53327. // if both values are strings, make sure a diff is generated
  53328. if (is_string($this->value) && is_string($other)) {
  53329. $f = new SebastianBergmann\Comparator\ComparisonFailure(
  53330. $this->value,
  53331. $other,
  53332. $this->value,
  53333. $other
  53334. );
  53335. }
  53336. $this->fail($other, $description, $f);
  53337. }
  53338. }
  53339. /**
  53340. * Returns the description of the failure
  53341. *
  53342. * The beginning of failure messages is "Failed asserting that" in most
  53343. * cases. This method should return the second part of that sentence.
  53344. *
  53345. * @param mixed $other Evaluated value or object.
  53346. * @return string
  53347. */
  53348. protected function failureDescription($other)
  53349. {
  53350. if (is_object($this->value) && is_object($other)) {
  53351. return 'two variables reference the same object';
  53352. }
  53353. if (is_string($this->value) && is_string($other)) {
  53354. return 'two strings are identical';
  53355. }
  53356. return parent::failureDescription($other);
  53357. }
  53358. /**
  53359. * Returns a string representation of the constraint.
  53360. *
  53361. * @return string
  53362. */
  53363. public function toString()
  53364. {
  53365. if (is_object($this->value)) {
  53366. return 'is identical to an object of class "' .
  53367. get_class($this->value) . '"';
  53368. } else {
  53369. return 'is identical to ' .
  53370. $this->exporter->export($this->value);
  53371. }
  53372. }
  53373. }
  53374. <?php
  53375. /*
  53376. * This file is part of PHPUnit.
  53377. *
  53378. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53379. *
  53380. * For the full copyright and license information, please view the LICENSE
  53381. * file that was distributed with this source code.
  53382. */
  53383. /**
  53384. * Constraint that checks if the file(name) that it is evaluated for exists.
  53385. *
  53386. * The file path to check is passed as $other in evaluate().
  53387. *
  53388. * @package PHPUnit
  53389. * @subpackage Framework_Constraint
  53390. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53391. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53392. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53393. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53394. * @link http://www.phpunit.de/
  53395. * @since Class available since Release 3.0.0
  53396. */
  53397. class PHPUnit_Framework_Constraint_FileExists extends PHPUnit_Framework_Constraint
  53398. {
  53399. /**
  53400. * Evaluates the constraint for parameter $other. Returns true if the
  53401. * constraint is met, false otherwise.
  53402. *
  53403. * @param mixed $other Value or object to evaluate.
  53404. * @return bool
  53405. */
  53406. protected function matches($other)
  53407. {
  53408. return file_exists($other);
  53409. }
  53410. /**
  53411. * Returns the description of the failure
  53412. *
  53413. * The beginning of failure messages is "Failed asserting that" in most
  53414. * cases. This method should return the second part of that sentence.
  53415. *
  53416. * @param mixed $other Evaluated value or object.
  53417. * @return string
  53418. */
  53419. protected function failureDescription($other)
  53420. {
  53421. return sprintf(
  53422. 'file "%s" exists',
  53423. $other
  53424. );
  53425. }
  53426. /**
  53427. * Returns a string representation of the constraint.
  53428. *
  53429. * @return string
  53430. */
  53431. public function toString()
  53432. {
  53433. return 'file exists';
  53434. }
  53435. }
  53436. <?php
  53437. /*
  53438. * This file is part of PHPUnit.
  53439. *
  53440. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53441. *
  53442. * For the full copyright and license information, please view the LICENSE
  53443. * file that was distributed with this source code.
  53444. */
  53445. /**
  53446. * @package PHPUnit
  53447. * @subpackage Framework_Constraint
  53448. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53449. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53450. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53451. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53452. * @link http://www.phpunit.de/
  53453. * @since Class available since Release 3.1.0
  53454. */
  53455. abstract class PHPUnit_Framework_Constraint_Composite extends PHPUnit_Framework_Constraint
  53456. {
  53457. /**
  53458. * @var PHPUnit_Framework_Constraint
  53459. */
  53460. protected $innerConstraint;
  53461. /**
  53462. * @param PHPUnit_Framework_Constraint $innerConstraint
  53463. */
  53464. public function __construct(PHPUnit_Framework_Constraint $innerConstraint)
  53465. {
  53466. parent::__construct();
  53467. $this->innerConstraint = $innerConstraint;
  53468. }
  53469. /**
  53470. * Evaluates the constraint for parameter $other
  53471. *
  53472. * If $returnResult is set to false (the default), an exception is thrown
  53473. * in case of a failure. null is returned otherwise.
  53474. *
  53475. * If $returnResult is true, the result of the evaluation is returned as
  53476. * a boolean value instead: true in case of success, false in case of a
  53477. * failure.
  53478. *
  53479. * @param mixed $other Value or object to evaluate.
  53480. * @param string $description Additional information about the test
  53481. * @param bool $returnResult Whether to return a result or throw an exception
  53482. * @return mixed
  53483. * @throws PHPUnit_Framework_ExpectationFailedException
  53484. */
  53485. public function evaluate($other, $description = '', $returnResult = false)
  53486. {
  53487. try {
  53488. return $this->innerConstraint->evaluate(
  53489. $other,
  53490. $description,
  53491. $returnResult
  53492. );
  53493. } catch (PHPUnit_Framework_ExpectationFailedException $e) {
  53494. $this->fail($other, $description);
  53495. }
  53496. }
  53497. /**
  53498. * Counts the number of constraint elements.
  53499. *
  53500. * @return integer
  53501. */
  53502. public function count()
  53503. {
  53504. return count($this->innerConstraint);
  53505. }
  53506. }
  53507. <?php
  53508. /*
  53509. * This file is part of PHPUnit.
  53510. *
  53511. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53512. *
  53513. * For the full copyright and license information, please view the LICENSE
  53514. * file that was distributed with this source code.
  53515. */
  53516. /**
  53517. * Constraint that asserts that the string it is evaluated for begins with a
  53518. * given prefix.
  53519. *
  53520. * @package PHPUnit
  53521. * @subpackage Framework_Constraint
  53522. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53523. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53524. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53525. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53526. * @link http://www.phpunit.de/
  53527. * @since Class available since Release 3.4.0
  53528. */
  53529. class PHPUnit_Framework_Constraint_StringStartsWith extends PHPUnit_Framework_Constraint
  53530. {
  53531. /**
  53532. * @var string
  53533. */
  53534. protected $prefix;
  53535. /**
  53536. * @param string $prefix
  53537. */
  53538. public function __construct($prefix)
  53539. {
  53540. parent::__construct();
  53541. $this->prefix = $prefix;
  53542. }
  53543. /**
  53544. * Evaluates the constraint for parameter $other. Returns true if the
  53545. * constraint is met, false otherwise.
  53546. *
  53547. * @param mixed $other Value or object to evaluate.
  53548. * @return bool
  53549. */
  53550. protected function matches($other)
  53551. {
  53552. return strpos($other, $this->prefix) === 0;
  53553. }
  53554. /**
  53555. * Returns a string representation of the constraint.
  53556. *
  53557. * @return string
  53558. */
  53559. public function toString()
  53560. {
  53561. return 'starts with "' . $this->prefix . '"';
  53562. }
  53563. }
  53564. <?php
  53565. /*
  53566. * This file is part of PHPUnit.
  53567. *
  53568. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53569. *
  53570. * For the full copyright and license information, please view the LICENSE
  53571. * file that was distributed with this source code.
  53572. */
  53573. /**
  53574. * Constraint that asserts that the string it is evaluated for ends with a given
  53575. * suffix.
  53576. *
  53577. * @package PHPUnit
  53578. * @subpackage Framework_Constraint
  53579. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53580. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53581. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53582. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53583. * @link http://www.phpunit.de/
  53584. * @since Class available since Release 3.4.0
  53585. */
  53586. class PHPUnit_Framework_Constraint_StringEndsWith extends PHPUnit_Framework_Constraint
  53587. {
  53588. /**
  53589. * @var string
  53590. */
  53591. protected $suffix;
  53592. /**
  53593. * @param string $suffix
  53594. */
  53595. public function __construct($suffix)
  53596. {
  53597. parent::__construct();
  53598. $this->suffix = $suffix;
  53599. }
  53600. /**
  53601. * Evaluates the constraint for parameter $other. Returns true if the
  53602. * constraint is met, false otherwise.
  53603. *
  53604. * @param mixed $other Value or object to evaluate.
  53605. * @return bool
  53606. */
  53607. protected function matches($other)
  53608. {
  53609. return substr($other, 0 - strlen($this->suffix)) == $this->suffix;
  53610. }
  53611. /**
  53612. * Returns a string representation of the constraint.
  53613. *
  53614. * @return string
  53615. */
  53616. public function toString()
  53617. {
  53618. return 'ends with "' . $this->suffix . '"';
  53619. }
  53620. }
  53621. <?php
  53622. /*
  53623. * This file is part of PHPUnit.
  53624. *
  53625. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53626. *
  53627. * For the full copyright and license information, please view the LICENSE
  53628. * file that was distributed with this source code.
  53629. */
  53630. /**
  53631. * Constraint that accepts any input value.
  53632. *
  53633. * @package PHPUnit
  53634. * @subpackage Framework_Constraint
  53635. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53636. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53637. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53638. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53639. * @link http://www.phpunit.de/
  53640. * @since Class available since Release 3.0.0
  53641. */
  53642. class PHPUnit_Framework_Constraint_IsAnything extends PHPUnit_Framework_Constraint
  53643. {
  53644. /**
  53645. * Evaluates the constraint for parameter $other
  53646. *
  53647. * If $returnResult is set to false (the default), an exception is thrown
  53648. * in case of a failure. null is returned otherwise.
  53649. *
  53650. * If $returnResult is true, the result of the evaluation is returned as
  53651. * a boolean value instead: true in case of success, false in case of a
  53652. * failure.
  53653. *
  53654. * @param mixed $other Value or object to evaluate.
  53655. * @param string $description Additional information about the test
  53656. * @param bool $returnResult Whether to return a result or throw an exception
  53657. * @return mixed
  53658. * @throws PHPUnit_Framework_ExpectationFailedException
  53659. */
  53660. public function evaluate($other, $description = '', $returnResult = false)
  53661. {
  53662. return $returnResult ? true : null;
  53663. }
  53664. /**
  53665. * Returns a string representation of the constraint.
  53666. *
  53667. * @return string
  53668. */
  53669. public function toString()
  53670. {
  53671. return 'is anything';
  53672. }
  53673. /**
  53674. * Counts the number of constraint elements.
  53675. *
  53676. * @return integer
  53677. * @since Method available since Release 3.5.0
  53678. */
  53679. public function count()
  53680. {
  53681. return 0;
  53682. }
  53683. }
  53684. <?php
  53685. /*
  53686. * This file is part of PHPUnit.
  53687. *
  53688. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53689. *
  53690. * For the full copyright and license information, please view the LICENSE
  53691. * file that was distributed with this source code.
  53692. */
  53693. /**
  53694. *
  53695. *
  53696. * @package PHPUnit
  53697. * @subpackage Framework_Constraint
  53698. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53699. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53700. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53701. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53702. * @link http://www.phpunit.de/
  53703. * @since Class available since Release 3.6.0
  53704. */
  53705. class PHPUnit_Framework_Constraint_Count extends PHPUnit_Framework_Constraint
  53706. {
  53707. /**
  53708. * @var integer
  53709. */
  53710. protected $expectedCount = 0;
  53711. /**
  53712. * @param integer $expected
  53713. */
  53714. public function __construct($expected)
  53715. {
  53716. parent::__construct();
  53717. $this->expectedCount = $expected;
  53718. }
  53719. /**
  53720. * Evaluates the constraint for parameter $other. Returns true if the
  53721. * constraint is met, false otherwise.
  53722. *
  53723. * @param mixed $other
  53724. * @return boolean
  53725. */
  53726. protected function matches($other)
  53727. {
  53728. return $this->expectedCount === $this->getCountOf($other);
  53729. }
  53730. /**
  53731. * @param mixed $other
  53732. * @return boolean
  53733. */
  53734. protected function getCountOf($other)
  53735. {
  53736. if ($other instanceof Countable || is_array($other)) {
  53737. return count($other);
  53738. } elseif ($other instanceof Traversable) {
  53739. if ($other instanceof IteratorAggregate) {
  53740. $iterator = $other->getIterator();
  53741. } else {
  53742. $iterator = $other;
  53743. }
  53744. $key = $iterator->key();
  53745. $count = iterator_count($iterator);
  53746. // manually rewind $iterator to previous key, since iterator_count
  53747. // moves pointer
  53748. if ($key !== null) {
  53749. $iterator->rewind();
  53750. while ($iterator->valid() && $key !== $iterator->key()) {
  53751. $iterator->next();
  53752. }
  53753. }
  53754. return $count;
  53755. }
  53756. }
  53757. /**
  53758. * Returns the description of the failure
  53759. *
  53760. * The beginning of failure messages is "Failed asserting that" in most
  53761. * cases. This method should return the second part of that sentence.
  53762. *
  53763. * @param mixed $other Evaluated value or object.
  53764. * @return string
  53765. */
  53766. protected function failureDescription($other)
  53767. {
  53768. return sprintf(
  53769. 'actual size %d matches expected size %d',
  53770. $this->getCountOf($other),
  53771. $this->expectedCount
  53772. );
  53773. }
  53774. /**
  53775. * @return string
  53776. */
  53777. public function toString()
  53778. {
  53779. return sprintf(
  53780. 'count matches %d',
  53781. $this->expectedCount
  53782. );
  53783. }
  53784. }
  53785. <?php
  53786. /*
  53787. * This file is part of PHPUnit.
  53788. *
  53789. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53790. *
  53791. * For the full copyright and license information, please view the LICENSE
  53792. * file that was distributed with this source code.
  53793. */
  53794. /**
  53795. * Logical AND.
  53796. *
  53797. * @package PHPUnit
  53798. * @subpackage Framework_Constraint
  53799. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53800. * @author Bernhard Schussek <bschussek@2bepublished.at>
  53801. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53802. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53803. * @link http://www.phpunit.de/
  53804. * @since Class available since Release 3.0.0
  53805. */
  53806. class PHPUnit_Framework_Constraint_And extends PHPUnit_Framework_Constraint
  53807. {
  53808. /**
  53809. * @var PHPUnit_Framework_Constraint[]
  53810. */
  53811. protected $constraints = array();
  53812. /**
  53813. * @var PHPUnit_Framework_Constraint
  53814. */
  53815. protected $lastConstraint = null;
  53816. /**
  53817. * @param PHPUnit_Framework_Constraint[] $constraints
  53818. * @throws PHPUnit_Framework_Exception
  53819. */
  53820. public function setConstraints(array $constraints)
  53821. {
  53822. $this->constraints = array();
  53823. foreach ($constraints as $constraint) {
  53824. if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
  53825. throw new PHPUnit_Framework_Exception(
  53826. 'All parameters to ' . __CLASS__ .
  53827. ' must be a constraint object.'
  53828. );
  53829. }
  53830. $this->constraints[] = $constraint;
  53831. }
  53832. }
  53833. /**
  53834. * Evaluates the constraint for parameter $other
  53835. *
  53836. * If $returnResult is set to false (the default), an exception is thrown
  53837. * in case of a failure. null is returned otherwise.
  53838. *
  53839. * If $returnResult is true, the result of the evaluation is returned as
  53840. * a boolean value instead: true in case of success, false in case of a
  53841. * failure.
  53842. *
  53843. * @param mixed $other Value or object to evaluate.
  53844. * @param string $description Additional information about the test
  53845. * @param bool $returnResult Whether to return a result or throw an exception
  53846. * @return mixed
  53847. * @throws PHPUnit_Framework_ExpectationFailedException
  53848. */
  53849. public function evaluate($other, $description = '', $returnResult = false)
  53850. {
  53851. $success = true;
  53852. $constraint = null;
  53853. foreach ($this->constraints as $constraint) {
  53854. if (!$constraint->evaluate($other, $description, true)) {
  53855. $success = false;
  53856. break;
  53857. }
  53858. }
  53859. if ($returnResult) {
  53860. return $success;
  53861. }
  53862. if (!$success) {
  53863. $this->fail($other, $description);
  53864. }
  53865. }
  53866. /**
  53867. * Returns a string representation of the constraint.
  53868. *
  53869. * @return string
  53870. */
  53871. public function toString()
  53872. {
  53873. $text = '';
  53874. foreach ($this->constraints as $key => $constraint) {
  53875. if ($key > 0) {
  53876. $text .= ' and ';
  53877. }
  53878. $text .= $constraint->toString();
  53879. }
  53880. return $text;
  53881. }
  53882. /**
  53883. * Counts the number of constraint elements.
  53884. *
  53885. * @return integer
  53886. * @since Method available since Release 3.4.0
  53887. */
  53888. public function count()
  53889. {
  53890. $count = 0;
  53891. foreach ($this->constraints as $constraint) {
  53892. $count += count($constraint);
  53893. }
  53894. return $count;
  53895. }
  53896. }
  53897. <?php
  53898. /*
  53899. * This file is part of PHPUnit.
  53900. *
  53901. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53902. *
  53903. * For the full copyright and license information, please view the LICENSE
  53904. * file that was distributed with this source code.
  53905. */
  53906. /**
  53907. * An empty Listener that can be extended to implement TestListener
  53908. * with just a few lines of code.
  53909. * @see PHPUnit_Framework_TestListener for documentation on the API methods.
  53910. *
  53911. * @package PHPUnit
  53912. * @subpackage Framework
  53913. * @author Giorgio Sironi<info@giorgiosironi.com>
  53914. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53915. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53916. * @link http://www.phpunit.de/
  53917. * @since Class available since Release 4.0.0
  53918. */
  53919. abstract class PHPUnit_Framework_BaseTestListener implements PHPUnit_Framework_TestListener
  53920. {
  53921. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  53922. {
  53923. }
  53924. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  53925. {
  53926. }
  53927. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  53928. {
  53929. }
  53930. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  53931. {
  53932. }
  53933. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  53934. {
  53935. }
  53936. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  53937. {
  53938. }
  53939. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  53940. {
  53941. }
  53942. public function startTest(PHPUnit_Framework_Test $test)
  53943. {
  53944. }
  53945. public function endTest(PHPUnit_Framework_Test $test, $time)
  53946. {
  53947. }
  53948. }
  53949. <?php
  53950. /*
  53951. * This file is part of PHPUnit.
  53952. *
  53953. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53954. *
  53955. * For the full copyright and license information, please view the LICENSE
  53956. * file that was distributed with this source code.
  53957. */
  53958. /**
  53959. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  53960. * case of a skipped test.
  53961. *
  53962. * @package PHPUnit
  53963. * @subpackage Framework
  53964. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53965. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53966. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53967. * @link http://www.phpunit.de/
  53968. * @since Class available since Release 3.0.0
  53969. */
  53970. class PHPUnit_Framework_SkippedTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest
  53971. {
  53972. }
  53973. <?php
  53974. /*
  53975. * This file is part of PHPUnit.
  53976. *
  53977. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53978. *
  53979. * For the full copyright and license information, please view the LICENSE
  53980. * file that was distributed with this source code.
  53981. */
  53982. /**
  53983. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  53984. * case of a test test that unintentionally covers code.
  53985. *
  53986. * @package PHPUnit
  53987. * @subpackage Framework
  53988. * @author Sebastian Bergmann <sebastian@phpunit.de>
  53989. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  53990. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  53991. * @link http://www.phpunit.de/
  53992. * @since Class available since Release 4.0.0
  53993. */
  53994. class PHPUnit_Framework_UnintentionallyCoveredCodeError extends PHPUnit_Framework_RiskyTestError
  53995. {
  53996. }
  53997. <?php
  53998. /*
  53999. * This file is part of PHPUnit.
  54000. *
  54001. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54002. *
  54003. * For the full copyright and license information, please view the LICENSE
  54004. * file that was distributed with this source code.
  54005. */
  54006. /**
  54007. * A warning.
  54008. *
  54009. * @package PHPUnit
  54010. * @subpackage Framework
  54011. * @author Sebastian Bergmann <sebastian@phpunit.de>
  54012. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  54013. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  54014. * @link http://www.phpunit.de/
  54015. * @since Class available since Release 2.0.0
  54016. */
  54017. class PHPUnit_Framework_Warning extends PHPUnit_Framework_TestCase
  54018. {
  54019. /**
  54020. * @var string
  54021. */
  54022. protected $message = '';
  54023. /**
  54024. * @var boolean
  54025. */
  54026. protected $backupGlobals = false;
  54027. /**
  54028. * @var boolean
  54029. */
  54030. protected $backupStaticAttributes = false;
  54031. /**
  54032. * @var boolean
  54033. */
  54034. protected $runTestInSeparateProcess = false;
  54035. /**
  54036. * @var boolean
  54037. */
  54038. protected $useErrorHandler = false;
  54039. /**
  54040. * @param string $message
  54041. */
  54042. public function __construct($message = '')
  54043. {
  54044. $this->message = $message;
  54045. parent::__construct('Warning');
  54046. }
  54047. /**
  54048. * @throws PHPUnit_Framework_Exception
  54049. */
  54050. protected function runTest()
  54051. {
  54052. $this->fail($this->message);
  54053. }
  54054. /**
  54055. * @return string
  54056. * @since Method available since Release 3.0.0
  54057. */
  54058. public function getMessage()
  54059. {
  54060. return $this->message;
  54061. }
  54062. /**
  54063. * Returns a string representation of the test case.
  54064. *
  54065. * @return string
  54066. * @since Method available since Release 3.4.0
  54067. */
  54068. public function toString()
  54069. {
  54070. return 'Warning';
  54071. }
  54072. }
  54073. <?php
  54074. /*
  54075. * This file is part of PHPUnit.
  54076. *
  54077. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54078. *
  54079. * For the full copyright and license information, please view the LICENSE
  54080. * file that was distributed with this source code.
  54081. */
  54082. /**
  54083. * We have a TestSuite object A.
  54084. * In TestSuite object A we have Tests tagged with @group.
  54085. * We want a TestSuite object B that contains TestSuite objects C, D, ...
  54086. * for the Tests tagged with @group C, @group D, ...
  54087. * Running the Tests from TestSuite object B results in Tests tagged with both
  54088. * @group C and @group D in TestSuite object A to be run twice .
  54089. *
  54090. * <code>
  54091. * $suite = new PHPUnit_Extensions_GroupTestSuite($A, array('C', 'D'));
  54092. * </code>
  54093. *
  54094. * @package PHPUnit
  54095. * @subpackage Extensions
  54096. * @author Sebastian Bergmann <sebastian@phpunit.de>
  54097. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  54098. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  54099. * @link http://www.phpunit.de/
  54100. * @since Class available since Release 3.3.0
  54101. */
  54102. class PHPUnit_Extensions_GroupTestSuite extends PHPUnit_Framework_TestSuite
  54103. {
  54104. public function __construct(PHPUnit_Framework_TestSuite $suite, array $groups)
  54105. {
  54106. $groupSuites = array();
  54107. $name = $suite->getName();
  54108. foreach ($groups as $group) {
  54109. $groupSuites[$group] = new PHPUnit_Framework_TestSuite($name . ' - ' . $group);
  54110. $this->addTest($groupSuites[$group]);
  54111. }
  54112. $tests = new RecursiveIteratorIterator(
  54113. new PHPUnit_Util_TestSuiteIterator($suite),
  54114. RecursiveIteratorIterator::LEAVES_ONLY
  54115. );
  54116. foreach ($tests as $test) {
  54117. if ($test instanceof PHPUnit_Framework_TestCase) {
  54118. $testGroups = PHPUnit_Util_Test::getGroups(
  54119. get_class($test),
  54120. $test->getName(false)
  54121. );
  54122. foreach ($groups as $group) {
  54123. foreach ($testGroups as $testGroup) {
  54124. if ($group == $testGroup) {
  54125. $groupSuites[$group]->addTest($test);
  54126. }
  54127. }
  54128. }
  54129. }
  54130. }
  54131. }
  54132. }
  54133. <?php
  54134. /*
  54135. * This file is part of PHPUnit.
  54136. *
  54137. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54138. *
  54139. * For the full copyright and license information, please view the LICENSE
  54140. * file that was distributed with this source code.
  54141. */
  54142. /**
  54143. * Suite for .phpt test cases.
  54144. *
  54145. * @package PHPUnit
  54146. * @subpackage Extensions_PhptTestCase
  54147. * @author Sebastian Bergmann <sebastian@phpunit.de>
  54148. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  54149. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  54150. * @link http://www.phpunit.de/
  54151. * @since Class available since Release 3.1.4
  54152. */
  54153. class PHPUnit_Extensions_PhptTestSuite extends PHPUnit_Framework_TestSuite
  54154. {
  54155. /**
  54156. * Constructs a new TestSuite for .phpt test cases.
  54157. *
  54158. * @param string $directory
  54159. * @param array $options Array with ini settings for the php instance run,
  54160. * key being the name if the setting, value the ini value.
  54161. * @throws PHPUnit_Framework_Exception
  54162. */
  54163. public function __construct($directory, array $options = array())
  54164. {
  54165. if (is_string($directory) && is_dir($directory)) {
  54166. $this->setName($directory);
  54167. $facade = new File_Iterator_Facade;
  54168. $files = $facade->getFilesAsArray($directory, '.phpt');
  54169. foreach ($files as $file) {
  54170. $this->addTestFile($file, $options);
  54171. }
  54172. } else {
  54173. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'directory name');
  54174. }
  54175. }
  54176. }
  54177. <?php
  54178. /*
  54179. * This file is part of PHPUnit.
  54180. *
  54181. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54182. *
  54183. * For the full copyright and license information, please view the LICENSE
  54184. * file that was distributed with this source code.
  54185. */
  54186. /**
  54187. * A Decorator that runs a test repeatedly.
  54188. *
  54189. * @package PHPUnit
  54190. * @author Sebastian Bergmann <sebastian@phpunit.de>
  54191. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  54192. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  54193. * @link http://www.phpunit.de/
  54194. * @since Class available since Release 2.0.0
  54195. */
  54196. class PHPUnit_Extensions_RepeatedTest extends PHPUnit_Extensions_TestDecorator
  54197. {
  54198. /**
  54199. * @var mixed
  54200. */
  54201. protected $filter = false;
  54202. /**
  54203. * @var array
  54204. */
  54205. protected $groups = array();
  54206. /**
  54207. * @var array
  54208. */
  54209. protected $excludeGroups = array();
  54210. /**
  54211. * @var boolean
  54212. */
  54213. protected $processIsolation = false;
  54214. /**
  54215. * @var integer
  54216. */
  54217. protected $timesRepeat = 1;
  54218. /**
  54219. * @param PHPUnit_Framework_Test $test
  54220. * @param integer $timesRepeat
  54221. * @param boolean $processIsolation
  54222. * @throws PHPUnit_Framework_Exception
  54223. */
  54224. public function __construct(PHPUnit_Framework_Test $test, $timesRepeat = 1, $processIsolation = false)
  54225. {
  54226. parent::__construct($test);
  54227. if (is_integer($timesRepeat) &&
  54228. $timesRepeat >= 0) {
  54229. $this->timesRepeat = $timesRepeat;
  54230. } else {
  54231. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  54232. 2,
  54233. 'positive integer'
  54234. );
  54235. }
  54236. $this->processIsolation = $processIsolation;
  54237. }
  54238. /**
  54239. * Counts the number of test cases that
  54240. * will be run by this test.
  54241. *
  54242. * @return integer
  54243. */
  54244. public function count()
  54245. {
  54246. return $this->timesRepeat * count($this->test);
  54247. }
  54248. /**
  54249. * Runs the decorated test and collects the
  54250. * result in a TestResult.
  54251. *
  54252. * @param PHPUnit_Framework_TestResult $result
  54253. * @return PHPUnit_Framework_TestResult
  54254. * @throws PHPUnit_Framework_Exception
  54255. */
  54256. public function run(PHPUnit_Framework_TestResult $result = null)
  54257. {
  54258. if ($result === null) {
  54259. $result = $this->createResult();
  54260. }
  54261. //@codingStandardsIgnoreStart
  54262. for ($i = 0; $i < $this->timesRepeat && !$result->shouldStop(); $i++) {
  54263. //@codingStandardsIgnoreEnd
  54264. if ($this->test instanceof PHPUnit_Framework_TestSuite) {
  54265. $this->test->setRunTestInSeparateProcess($this->processIsolation);
  54266. }
  54267. $this->test->run($result);
  54268. }
  54269. return $result;
  54270. }
  54271. }
  54272. <?php
  54273. /*
  54274. * This file is part of PHPUnit.
  54275. *
  54276. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54277. *
  54278. * For the full copyright and license information, please view the LICENSE
  54279. * file that was distributed with this source code.
  54280. */
  54281. /**
  54282. * Base class for test listeners that interact with an issue tracker.
  54283. *
  54284. * @package PHPUnit
  54285. * @subpackage Extensions_TicketListener
  54286. * @author Sean Coates <sean@caedmon.net>
  54287. * @author Sebastian Bergmann <sebastian@phpunit.de>
  54288. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  54289. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  54290. * @link http://www.phpunit.de/
  54291. * @since Class available since Release 3.4.0
  54292. */
  54293. abstract class PHPUnit_Extensions_TicketListener implements PHPUnit_Framework_TestListener
  54294. {
  54295. /**
  54296. * @var array
  54297. */
  54298. protected $ticketCounts = array();
  54299. /**
  54300. * @var boolean
  54301. */
  54302. protected $ran = false;
  54303. /**
  54304. * An error occurred.
  54305. *
  54306. * @param PHPUnit_Framework_Test $test
  54307. * @param Exception $e
  54308. * @param float $time
  54309. */
  54310. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  54311. {
  54312. }
  54313. /**
  54314. * A failure occurred.
  54315. *
  54316. * @param PHPUnit_Framework_Test $test
  54317. * @param PHPUnit_Framework_AssertionFailedError $e
  54318. * @param float $time
  54319. */
  54320. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  54321. {
  54322. }
  54323. /**
  54324. * Incomplete test.
  54325. *
  54326. * @param PHPUnit_Framework_Test $test
  54327. * @param Exception $e
  54328. * @param float $time
  54329. */
  54330. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  54331. {
  54332. }
  54333. /**
  54334. * Risky test.
  54335. *
  54336. * @param PHPUnit_Framework_Test $test
  54337. * @param Exception $e
  54338. * @param float $time
  54339. * @since Method available since Release 4.0.0
  54340. */
  54341. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  54342. {
  54343. }
  54344. /**
  54345. * Skipped test.
  54346. *
  54347. * @param PHPUnit_Framework_Test $test
  54348. * @param Exception $e
  54349. * @param float $time
  54350. * @since Method available since Release 3.0.0
  54351. */
  54352. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  54353. {
  54354. }
  54355. /**
  54356. * A test suite started.
  54357. *
  54358. * @param PHPUnit_Framework_TestSuite $suite
  54359. * @since Method available since Release 2.2.0
  54360. */
  54361. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  54362. {
  54363. }
  54364. /**
  54365. * A test suite ended.
  54366. *
  54367. * @param PHPUnit_Framework_TestSuite $suite
  54368. * @since Method available since Release 2.2.0
  54369. */
  54370. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  54371. {
  54372. }
  54373. /**
  54374. * A test started.
  54375. *
  54376. * @param PHPUnit_Framework_Test $test
  54377. */
  54378. public function startTest(PHPUnit_Framework_Test $test)
  54379. {
  54380. if (!$test instanceof PHPUnit_Framework_Warning) {
  54381. if ($this->ran) {
  54382. return;
  54383. }
  54384. $name = $test->getName(false);
  54385. $tickets = PHPUnit_Util_Test::getTickets(get_class($test), $name);
  54386. foreach ($tickets as $ticket) {
  54387. $this->ticketCounts[$ticket][$name] = 1;
  54388. }
  54389. $this->ran = true;
  54390. }
  54391. }
  54392. /**
  54393. * A test ended.
  54394. *
  54395. * @param PHPUnit_Framework_Test $test
  54396. * @param float $time
  54397. */
  54398. public function endTest(PHPUnit_Framework_Test $test, $time)
  54399. {
  54400. if (!$test instanceof PHPUnit_Framework_Warning) {
  54401. if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
  54402. $ifStatus = array('assigned', 'new', 'reopened');
  54403. $newStatus = 'closed';
  54404. $message = 'Automatically closed by PHPUnit (test passed).';
  54405. $resolution = 'fixed';
  54406. $cumulative = true;
  54407. } elseif ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
  54408. $ifStatus = array('closed');
  54409. $newStatus = 'reopened';
  54410. $message = 'Automatically reopened by PHPUnit (test failed).';
  54411. $resolution = '';
  54412. $cumulative = false;
  54413. } else {
  54414. return;
  54415. }
  54416. $name = $test->getName(false);
  54417. $tickets = PHPUnit_Util_Test::getTickets(get_class($test), $name);
  54418. foreach ($tickets as $ticket) {
  54419. // Remove this test from the totals (if it passed).
  54420. if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
  54421. unset($this->ticketCounts[$ticket][$name]);
  54422. }
  54423. // Only close tickets if ALL referenced cases pass
  54424. // but reopen tickets if a single test fails.
  54425. if ($cumulative) {
  54426. // Determine number of to-pass tests:
  54427. if (count($this->ticketCounts[$ticket]) > 0) {
  54428. // There exist remaining test cases with this reference.
  54429. $adjustTicket = false;
  54430. } else {
  54431. // No remaining tickets, go ahead and adjust.
  54432. $adjustTicket = true;
  54433. }
  54434. } else {
  54435. $adjustTicket = true;
  54436. }
  54437. $ticketInfo = $this->getTicketInfo($ticket);
  54438. if ($adjustTicket && in_array($ticketInfo['status'], $ifStatus)) {
  54439. $this->updateTicket($ticket, $newStatus, $message, $resolution);
  54440. }
  54441. }
  54442. }
  54443. }
  54444. abstract protected function getTicketInfo($ticketId = null);
  54445. abstract protected function updateTicket($ticketId, $newStatus, $message, $resolution);
  54446. }
  54447. <?php
  54448. /*
  54449. * This file is part of PHPUnit.
  54450. *
  54451. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54452. *
  54453. * For the full copyright and license information, please view the LICENSE
  54454. * file that was distributed with this source code.
  54455. */
  54456. /**
  54457. * A Decorator for Tests.
  54458. *
  54459. * Use TestDecorator as the base class for defining new
  54460. * test decorators. Test decorator subclasses can be introduced
  54461. * to add behaviour before or after a test is run.
  54462. *
  54463. * @package PHPUnit
  54464. * @subpackage Extensions
  54465. * @author Sebastian Bergmann <sebastian@phpunit.de>
  54466. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  54467. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  54468. * @link http://www.phpunit.de/
  54469. * @since Class available since Release 2.0.0
  54470. */
  54471. class PHPUnit_Extensions_TestDecorator extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing
  54472. {
  54473. /**
  54474. * The Test to be decorated.
  54475. *
  54476. * @var object
  54477. */
  54478. protected $test = null;
  54479. /**
  54480. * Constructor.
  54481. *
  54482. * @param PHPUnit_Framework_Test $test
  54483. */
  54484. public function __construct(PHPUnit_Framework_Test $test)
  54485. {
  54486. $this->test = $test;
  54487. }
  54488. /**
  54489. * Returns a string representation of the test.
  54490. *
  54491. * @return string
  54492. */
  54493. public function toString()
  54494. {
  54495. return $this->test->toString();
  54496. }
  54497. /**
  54498. * Runs the test and collects the
  54499. * result in a TestResult.
  54500. *
  54501. * @param PHPUnit_Framework_TestResult $result
  54502. */
  54503. public function basicRun(PHPUnit_Framework_TestResult $result)
  54504. {
  54505. $this->test->run($result);
  54506. }
  54507. /**
  54508. * Counts the number of test cases that
  54509. * will be run by this test.
  54510. *
  54511. * @return integer
  54512. */
  54513. public function count()
  54514. {
  54515. return count($this->test);
  54516. }
  54517. /**
  54518. * Creates a default TestResult object.
  54519. *
  54520. * @return PHPUnit_Framework_TestResult
  54521. */
  54522. protected function createResult()
  54523. {
  54524. return new PHPUnit_Framework_TestResult;
  54525. }
  54526. /**
  54527. * Returns the test to be run.
  54528. *
  54529. * @return PHPUnit_Framework_Test
  54530. */
  54531. public function getTest()
  54532. {
  54533. return $this->test;
  54534. }
  54535. /**
  54536. * Runs the decorated test and collects the
  54537. * result in a TestResult.
  54538. *
  54539. * @param PHPUnit_Framework_TestResult $result
  54540. * @return PHPUnit_Framework_TestResult
  54541. */
  54542. public function run(PHPUnit_Framework_TestResult $result = null)
  54543. {
  54544. if ($result === null) {
  54545. $result = $this->createResult();
  54546. }
  54547. $this->basicRun($result);
  54548. return $result;
  54549. }
  54550. }
  54551. <?php
  54552. /*
  54553. * This file is part of PHPUnit.
  54554. *
  54555. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54556. *
  54557. * For the full copyright and license information, please view the LICENSE
  54558. * file that was distributed with this source code.
  54559. */
  54560. /**
  54561. * Runner for PHPT test cases.
  54562. *
  54563. * @package PHPUnit
  54564. * @subpackage Extensions_PhptTestCase
  54565. * @author Sebastian Bergmann <sebastian@phpunit.de>
  54566. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  54567. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  54568. * @link http://www.phpunit.de/
  54569. * @since Class available since Release 3.1.4
  54570. */
  54571. class PHPUnit_Extensions_PhptTestCase implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing
  54572. {
  54573. /**
  54574. * @var string
  54575. */
  54576. private $filename;
  54577. /**
  54578. * @var array
  54579. */
  54580. private $settings = array(
  54581. 'allow_url_fopen=1',
  54582. 'auto_append_file=',
  54583. 'auto_prepend_file=',
  54584. 'disable_functions=',
  54585. 'display_errors=1',
  54586. 'docref_root=',
  54587. 'docref_ext=.html',
  54588. 'error_append_string=',
  54589. 'error_prepend_string=',
  54590. 'error_reporting=-1',
  54591. 'html_errors=0',
  54592. 'log_errors=0',
  54593. 'magic_quotes_runtime=0',
  54594. 'output_handler=',
  54595. 'open_basedir=',
  54596. 'output_buffering=Off',
  54597. 'report_memleaks=0',
  54598. 'report_zend_debug=0',
  54599. 'safe_mode=0',
  54600. 'track_errors=1',
  54601. 'xdebug.default_enable=0'
  54602. );
  54603. /**
  54604. * Constructs a test case with the given filename.
  54605. *
  54606. * @param string $filename
  54607. * @throws PHPUnit_Framework_Exception
  54608. */
  54609. public function __construct($filename)
  54610. {
  54611. if (!is_string($filename)) {
  54612. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  54613. }
  54614. if (!is_file($filename)) {
  54615. throw new PHPUnit_Framework_Exception(
  54616. sprintf(
  54617. 'File "%s" does not exist.',
  54618. $filename
  54619. )
  54620. );
  54621. }
  54622. $this->filename = $filename;
  54623. }
  54624. /**
  54625. * Counts the number of test cases executed by run(TestResult result).
  54626. *
  54627. * @return integer
  54628. */
  54629. public function count()
  54630. {
  54631. return 1;
  54632. }
  54633. /**
  54634. * Runs a test and collects its result in a TestResult instance.
  54635. *
  54636. * @param PHPUnit_Framework_TestResult $result
  54637. * @return PHPUnit_Framework_TestResult
  54638. */
  54639. public function run(PHPUnit_Framework_TestResult $result = null)
  54640. {
  54641. $sections = $this->parse();
  54642. $code = $this->render($sections['FILE']);
  54643. if ($result === null) {
  54644. $result = new PHPUnit_Framework_TestResult;
  54645. }
  54646. $php = PHPUnit_Util_PHP::factory();
  54647. $skip = false;
  54648. $time = 0;
  54649. $settings = $this->settings;
  54650. $result->startTest($this);
  54651. if (isset($sections['INI'])) {
  54652. $settings = array_merge($settings, $this->parseIniSection($sections['INI']));
  54653. }
  54654. if (isset($sections['SKIPIF'])) {
  54655. $jobResult = $php->runJob($sections['SKIPIF'], $settings);
  54656. if (!strncasecmp('skip', ltrim($jobResult['stdout']), 4)) {
  54657. if (preg_match('/^\s*skip\s*(.+)\s*/i', $jobResult['stdout'], $message)) {
  54658. $message = substr($message[1], 2);
  54659. } else {
  54660. $message = '';
  54661. }
  54662. $result->addFailure($this, new PHPUnit_Framework_SkippedTestError($message), 0);
  54663. $skip = true;
  54664. }
  54665. }
  54666. if (!$skip) {
  54667. PHP_Timer::start();
  54668. $jobResult = $php->runJob($code, $settings);
  54669. $time = PHP_Timer::stop();
  54670. if (isset($sections['EXPECT'])) {
  54671. $assertion = 'assertEquals';
  54672. $expected = $sections['EXPECT'];
  54673. } else {
  54674. $assertion = 'assertStringMatchesFormat';
  54675. $expected = $sections['EXPECTF'];
  54676. }
  54677. $output = preg_replace('/\r\n/', "\n", trim($jobResult['stdout']));
  54678. $expected = preg_replace('/\r\n/', "\n", trim($expected));
  54679. try {
  54680. PHPUnit_Framework_Assert::$assertion($expected, $output);
  54681. } catch (PHPUnit_Framework_AssertionFailedError $e) {
  54682. $result->addFailure($this, $e, $time);
  54683. } catch (Exception $e) {
  54684. $result->addError($this, $e, $time);
  54685. }
  54686. }
  54687. $result->endTest($this, $time);
  54688. return $result;
  54689. }
  54690. /**
  54691. * Returns the name of the test case.
  54692. *
  54693. * @return string
  54694. */
  54695. public function getName()
  54696. {
  54697. return $this->toString();
  54698. }
  54699. /**
  54700. * Returns a string representation of the test case.
  54701. *
  54702. * @return string
  54703. */
  54704. public function toString()
  54705. {
  54706. return $this->filename;
  54707. }
  54708. /**
  54709. * @return array
  54710. * @throws PHPUnit_Framework_Exception
  54711. */
  54712. private function parse()
  54713. {
  54714. $sections = array();
  54715. $section = '';
  54716. foreach (file($this->filename) as $line) {
  54717. if (preg_match('/^--([_A-Z]+)--/', $line, $result)) {
  54718. $section = $result[1];
  54719. $sections[$section] = '';
  54720. continue;
  54721. } elseif (empty($section)) {
  54722. throw new PHPUnit_Framework_Exception('Invalid PHPT file');
  54723. }
  54724. $sections[$section] .= $line;
  54725. }
  54726. if (!isset($sections['FILE']) ||
  54727. (!isset($sections['EXPECT']) && !isset($sections['EXPECTF']))) {
  54728. throw new PHPUnit_Framework_Exception('Invalid PHPT file');
  54729. }
  54730. return $sections;
  54731. }
  54732. /**
  54733. * @param string $code
  54734. * @return string
  54735. */
  54736. private function render($code)
  54737. {
  54738. return str_replace(
  54739. array(
  54740. '__DIR__',
  54741. '__FILE__'
  54742. ),
  54743. array(
  54744. "'" . dirname($this->filename) . "'",
  54745. "'" . $this->filename . "'"
  54746. ),
  54747. $code
  54748. );
  54749. }
  54750. /**
  54751. * Parse --INI-- section key value pairs and return as array.
  54752. *
  54753. * @param string
  54754. * @return array
  54755. */
  54756. protected function parseIniSection($content)
  54757. {
  54758. return preg_split('/\n|\r/', $content, -1, PREG_SPLIT_NO_EMPTY);
  54759. }
  54760. }
  54761. <?php
  54762. /*
  54763. * This file is part of PHPUnit.
  54764. *
  54765. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54766. *
  54767. * For the full copyright and license information, please view the LICENSE
  54768. * file that was distributed with this source code.
  54769. */
  54770. /**
  54771. * A TestRunner for the Command Line Interface (CLI)
  54772. * PHP SAPI Module.
  54773. *
  54774. * @package PHPUnit
  54775. * @subpackage TextUI
  54776. * @author Sebastian Bergmann <sebastian@phpunit.de>
  54777. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  54778. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  54779. * @link http://www.phpunit.de/
  54780. * @since Class available since Release 3.0.0
  54781. */
  54782. class PHPUnit_TextUI_Command
  54783. {
  54784. /**
  54785. * @var array
  54786. */
  54787. protected $arguments = array(
  54788. 'listGroups' => false,
  54789. 'loader' => null,
  54790. 'useDefaultConfiguration' => true
  54791. );
  54792. /**
  54793. * @var array
  54794. */
  54795. protected $options = array();
  54796. /**
  54797. * @var array
  54798. */
  54799. protected $longOptions = array(
  54800. 'colors==' => null,
  54801. 'bootstrap=' => null,
  54802. 'columns=' => null,
  54803. 'configuration=' => null,
  54804. 'coverage-clover=' => null,
  54805. 'coverage-crap4j=' => null,
  54806. 'coverage-html=' => null,
  54807. 'coverage-php=' => null,
  54808. 'coverage-text==' => null,
  54809. 'coverage-xml=' => null,
  54810. 'debug' => null,
  54811. 'exclude-group=' => null,
  54812. 'filter=' => null,
  54813. 'testsuite=' => null,
  54814. 'group=' => null,
  54815. 'help' => null,
  54816. 'include-path=' => null,
  54817. 'list-groups' => null,
  54818. 'loader=' => null,
  54819. 'log-json=' => null,
  54820. 'log-junit=' => null,
  54821. 'log-tap=' => null,
  54822. 'process-isolation' => null,
  54823. 'repeat=' => null,
  54824. 'stderr' => null,
  54825. 'stop-on-error' => null,
  54826. 'stop-on-failure' => null,
  54827. 'stop-on-incomplete' => null,
  54828. 'stop-on-risky' => null,
  54829. 'stop-on-skipped' => null,
  54830. 'report-useless-tests' => null,
  54831. 'strict-coverage' => null,
  54832. 'disallow-test-output' => null,
  54833. 'enforce-time-limit' => null,
  54834. 'disallow-todo-tests' => null,
  54835. 'strict-global-state' => null,
  54836. 'strict' => null,
  54837. 'tap' => null,
  54838. 'testdox' => null,
  54839. 'testdox-html=' => null,
  54840. 'testdox-text=' => null,
  54841. 'test-suffix=' => null,
  54842. 'no-configuration' => null,
  54843. 'no-globals-backup' => null,
  54844. 'printer=' => null,
  54845. 'static-backup' => null,
  54846. 'verbose' => null,
  54847. 'version' => null
  54848. );
  54849. /**
  54850. * @var boolean
  54851. */
  54852. private $versionStringPrinted = false;
  54853. /**
  54854. * @param boolean $exit
  54855. */
  54856. public static function main($exit = true)
  54857. {
  54858. $command = new static;
  54859. return $command->run($_SERVER['argv'], $exit);
  54860. }
  54861. /**
  54862. * @param array $argv
  54863. * @param boolean $exit
  54864. * @return integer
  54865. */
  54866. public function run(array $argv, $exit = true)
  54867. {
  54868. $this->handleArguments($argv);
  54869. $runner = $this->createRunner();
  54870. if (is_object($this->arguments['test']) &&
  54871. $this->arguments['test'] instanceof PHPUnit_Framework_Test) {
  54872. $suite = $this->arguments['test'];
  54873. } else {
  54874. $suite = $runner->getTest(
  54875. $this->arguments['test'],
  54876. $this->arguments['testFile'],
  54877. $this->arguments['testSuffixes']
  54878. );
  54879. }
  54880. if ($this->arguments['listGroups']) {
  54881. $this->printVersionString();
  54882. print "Available test group(s):\n";
  54883. $groups = $suite->getGroups();
  54884. sort($groups);
  54885. foreach ($groups as $group) {
  54886. print " - $group\n";
  54887. }
  54888. if ($exit) {
  54889. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  54890. } else {
  54891. return PHPUnit_TextUI_TestRunner::SUCCESS_EXIT;
  54892. }
  54893. }
  54894. unset($this->arguments['test']);
  54895. unset($this->arguments['testFile']);
  54896. try {
  54897. $result = $runner->doRun($suite, $this->arguments);
  54898. } catch (PHPUnit_Framework_Exception $e) {
  54899. print $e->getMessage() . "\n";
  54900. }
  54901. $ret = PHPUnit_TextUI_TestRunner::FAILURE_EXIT;
  54902. if (isset($result) && $result->wasSuccessful()) {
  54903. $ret = PHPUnit_TextUI_TestRunner::SUCCESS_EXIT;
  54904. } elseif (!isset($result) || $result->errorCount() > 0) {
  54905. $ret = PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT;
  54906. }
  54907. if ($exit) {
  54908. exit($ret);
  54909. } else {
  54910. return $ret;
  54911. }
  54912. }
  54913. /**
  54914. * Create a TestRunner, override in subclasses.
  54915. *
  54916. * @return PHPUnit_TextUI_TestRunner
  54917. * @since Method available since Release 3.6.0
  54918. */
  54919. protected function createRunner()
  54920. {
  54921. return new PHPUnit_TextUI_TestRunner($this->arguments['loader']);
  54922. }
  54923. /**
  54924. * Handles the command-line arguments.
  54925. *
  54926. * A child class of PHPUnit_TextUI_Command can hook into the argument
  54927. * parsing by adding the switch(es) to the $longOptions array and point to a
  54928. * callback method that handles the switch(es) in the child class like this
  54929. *
  54930. * <code>
  54931. * <?php
  54932. * class MyCommand extends PHPUnit_TextUI_Command
  54933. * {
  54934. * public function __construct()
  54935. * {
  54936. * // my-switch won't accept a value, it's an on/off
  54937. * $this->longOptions['my-switch'] = 'myHandler';
  54938. * // my-secondswitch will accept a value - note the equals sign
  54939. * $this->longOptions['my-secondswitch='] = 'myOtherHandler';
  54940. * }
  54941. *
  54942. * // --my-switch -> myHandler()
  54943. * protected function myHandler()
  54944. * {
  54945. * }
  54946. *
  54947. * // --my-secondswitch foo -> myOtherHandler('foo')
  54948. * protected function myOtherHandler ($value)
  54949. * {
  54950. * }
  54951. *
  54952. * // You will also need this - the static keyword in the
  54953. * // PHPUnit_TextUI_Command will mean that it'll be
  54954. * // PHPUnit_TextUI_Command that gets instantiated,
  54955. * // not MyCommand
  54956. * public static function main($exit = true)
  54957. * {
  54958. * $command = new static;
  54959. *
  54960. * return $command->run($_SERVER['argv'], $exit);
  54961. * }
  54962. *
  54963. * }
  54964. * </code>
  54965. *
  54966. * @param array $argv
  54967. */
  54968. protected function handleArguments(array $argv)
  54969. {
  54970. if (defined('__PHPUNIT_PHAR__')) {
  54971. $this->longOptions['selfupdate'] = null;
  54972. $this->longOptions['self-update'] = null;
  54973. }
  54974. try {
  54975. $this->options = PHPUnit_Util_Getopt::getopt(
  54976. $argv,
  54977. 'd:c:hv',
  54978. array_keys($this->longOptions)
  54979. );
  54980. } catch (PHPUnit_Framework_Exception $e) {
  54981. $this->showError($e->getMessage());
  54982. }
  54983. foreach ($this->options[0] as $option) {
  54984. switch ($option[0]) {
  54985. case '--colors':
  54986. $this->arguments['colors'] = $option[1] ?: PHPUnit_TextUI_ResultPrinter::COLOR_AUTO;
  54987. break;
  54988. case '--bootstrap':
  54989. $this->arguments['bootstrap'] = $option[1];
  54990. break;
  54991. case '--columns':
  54992. if (is_numeric($option[1])) {
  54993. $this->arguments['columns'] = (int) $option[1];
  54994. } elseif ($option[1] == 'max') {
  54995. $this->arguments['columns'] = 'max';
  54996. }
  54997. break;
  54998. case 'c':
  54999. case '--configuration':
  55000. $this->arguments['configuration'] = $option[1];
  55001. break;
  55002. case '--coverage-clover':
  55003. $this->arguments['coverageClover'] = $option[1];
  55004. break;
  55005. case '--coverage-crap4j':
  55006. $this->arguments['coverageCrap4J'] = $option[1];
  55007. break;
  55008. case '--coverage-html':
  55009. $this->arguments['coverageHtml'] = $option[1];
  55010. break;
  55011. case '--coverage-php':
  55012. $this->arguments['coveragePHP'] = $option[1];
  55013. break;
  55014. case '--coverage-text':
  55015. if ($option[1] === null) {
  55016. $option[1] = 'php://stdout';
  55017. }
  55018. $this->arguments['coverageText'] = $option[1];
  55019. $this->arguments['coverageTextShowUncoveredFiles'] = false;
  55020. $this->arguments['coverageTextShowOnlySummary'] = false;
  55021. break;
  55022. case '--coverage-xml':
  55023. $this->arguments['coverageXml'] = $option[1];
  55024. break;
  55025. case 'd':
  55026. $ini = explode('=', $option[1]);
  55027. if (isset($ini[0])) {
  55028. if (isset($ini[1])) {
  55029. ini_set($ini[0], $ini[1]);
  55030. } else {
  55031. ini_set($ini[0], true);
  55032. }
  55033. }
  55034. break;
  55035. case '--debug':
  55036. $this->arguments['debug'] = true;
  55037. break;
  55038. case 'h':
  55039. case '--help':
  55040. $this->showHelp();
  55041. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  55042. break;
  55043. case '--filter':
  55044. $this->arguments['filter'] = $option[1];
  55045. break;
  55046. case '--testsuite':
  55047. $this->arguments['testsuite'] = $option[1];
  55048. break;
  55049. case '--group':
  55050. $this->arguments['groups'] = explode(',', $option[1]);
  55051. break;
  55052. case '--exclude-group':
  55053. $this->arguments['excludeGroups'] = explode(
  55054. ',',
  55055. $option[1]
  55056. );
  55057. break;
  55058. case '--test-suffix':
  55059. $this->arguments['testSuffixes'] = explode(
  55060. ',',
  55061. $option[1]
  55062. );
  55063. break;
  55064. case '--include-path':
  55065. $includePath = $option[1];
  55066. break;
  55067. case '--list-groups':
  55068. $this->arguments['listGroups'] = true;
  55069. break;
  55070. case '--printer':
  55071. $this->arguments['printer'] = $option[1];
  55072. break;
  55073. case '--loader':
  55074. $this->arguments['loader'] = $option[1];
  55075. break;
  55076. case '--log-json':
  55077. $this->arguments['jsonLogfile'] = $option[1];
  55078. break;
  55079. case '--log-junit':
  55080. $this->arguments['junitLogfile'] = $option[1];
  55081. break;
  55082. case '--log-tap':
  55083. $this->arguments['tapLogfile'] = $option[1];
  55084. break;
  55085. case '--process-isolation':
  55086. $this->arguments['processIsolation'] = true;
  55087. break;
  55088. case '--repeat':
  55089. $this->arguments['repeat'] = (int) $option[1];
  55090. break;
  55091. case '--stderr':
  55092. $this->arguments['stderr'] = true;
  55093. break;
  55094. case '--stop-on-error':
  55095. $this->arguments['stopOnError'] = true;
  55096. break;
  55097. case '--stop-on-failure':
  55098. $this->arguments['stopOnFailure'] = true;
  55099. break;
  55100. case '--stop-on-incomplete':
  55101. $this->arguments['stopOnIncomplete'] = true;
  55102. break;
  55103. case '--stop-on-risky':
  55104. $this->arguments['stopOnRisky'] = true;
  55105. break;
  55106. case '--stop-on-skipped':
  55107. $this->arguments['stopOnSkipped'] = true;
  55108. break;
  55109. case '--tap':
  55110. $this->arguments['printer'] = 'PHPUnit_Util_Log_TAP';
  55111. break;
  55112. case '--testdox':
  55113. $this->arguments['printer'] = 'PHPUnit_Util_TestDox_ResultPrinter_Text';
  55114. break;
  55115. case '--testdox-html':
  55116. $this->arguments['testdoxHTMLFile'] = $option[1];
  55117. break;
  55118. case '--testdox-text':
  55119. $this->arguments['testdoxTextFile'] = $option[1];
  55120. break;
  55121. case '--no-configuration':
  55122. $this->arguments['useDefaultConfiguration'] = false;
  55123. break;
  55124. case '--no-globals-backup':
  55125. $this->arguments['backupGlobals'] = false;
  55126. break;
  55127. case '--static-backup':
  55128. $this->arguments['backupStaticAttributes'] = true;
  55129. break;
  55130. case 'v':
  55131. case '--verbose':
  55132. $this->arguments['verbose'] = true;
  55133. break;
  55134. case '--version':
  55135. $this->printVersionString();
  55136. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  55137. break;
  55138. case '--report-useless-tests':
  55139. $this->arguments['reportUselessTests'] = true;
  55140. break;
  55141. case '--strict-coverage':
  55142. $this->arguments['strictCoverage'] = true;
  55143. break;
  55144. case '--strict-global-state':
  55145. $this->arguments['disallowChangesToGlobalState'] = true;
  55146. break;
  55147. case '--disallow-test-output':
  55148. $this->arguments['disallowTestOutput'] = true;
  55149. break;
  55150. case '--enforce-time-limit':
  55151. $this->arguments['enforceTimeLimit'] = true;
  55152. break;
  55153. case '--disallow-todo-tests':
  55154. $this->arguments['disallowTodoAnnotatedTests'] = true;
  55155. break;
  55156. case '--strict':
  55157. $this->arguments['reportUselessTests'] = true;
  55158. $this->arguments['strictCoverage'] = true;
  55159. $this->arguments['disallowTestOutput'] = true;
  55160. $this->arguments['enforceTimeLimit'] = true;
  55161. $this->arguments['disallowTodoAnnotatedTests'] = true;
  55162. $this->arguments['deprecatedStrictModeOption'] = true;
  55163. break;
  55164. case '--selfupdate':
  55165. case '--self-update':
  55166. $this->handleSelfUpdate();
  55167. break;
  55168. default:
  55169. $optionName = str_replace('--', '', $option[0]);
  55170. if (isset($this->longOptions[$optionName])) {
  55171. $handler = $this->longOptions[$optionName];
  55172. } elseif (isset($this->longOptions[$optionName . '='])) {
  55173. $handler = $this->longOptions[$optionName . '='];
  55174. }
  55175. if (isset($handler) && is_callable(array($this, $handler))) {
  55176. $this->$handler($option[1]);
  55177. }
  55178. }
  55179. }
  55180. $this->handleCustomTestSuite();
  55181. if (!isset($this->arguments['test'])) {
  55182. if (isset($this->options[1][0])) {
  55183. $this->arguments['test'] = $this->options[1][0];
  55184. }
  55185. if (isset($this->options[1][1])) {
  55186. $this->arguments['testFile'] = realpath($this->options[1][1]);
  55187. } else {
  55188. $this->arguments['testFile'] = '';
  55189. }
  55190. if (isset($this->arguments['test']) &&
  55191. is_file($this->arguments['test']) &&
  55192. substr($this->arguments['test'], -5, 5) != '.phpt') {
  55193. $this->arguments['testFile'] = realpath($this->arguments['test']);
  55194. $this->arguments['test'] = substr($this->arguments['test'], 0, strrpos($this->arguments['test'], '.'));
  55195. }
  55196. }
  55197. if (!isset($this->arguments['testSuffixes'])) {
  55198. $this->arguments['testSuffixes'] = array('Test.php', '.phpt');
  55199. }
  55200. if (isset($includePath)) {
  55201. ini_set(
  55202. 'include_path',
  55203. $includePath . PATH_SEPARATOR . ini_get('include_path')
  55204. );
  55205. }
  55206. if ($this->arguments['loader'] !== null) {
  55207. $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']);
  55208. }
  55209. if (isset($this->arguments['configuration']) &&
  55210. is_dir($this->arguments['configuration'])) {
  55211. $configurationFile = $this->arguments['configuration'] . '/phpunit.xml';
  55212. if (file_exists($configurationFile)) {
  55213. $this->arguments['configuration'] = realpath(
  55214. $configurationFile
  55215. );
  55216. } elseif (file_exists($configurationFile . '.dist')) {
  55217. $this->arguments['configuration'] = realpath(
  55218. $configurationFile . '.dist'
  55219. );
  55220. }
  55221. } elseif (!isset($this->arguments['configuration']) &&
  55222. $this->arguments['useDefaultConfiguration']) {
  55223. if (file_exists('phpunit.xml')) {
  55224. $this->arguments['configuration'] = realpath('phpunit.xml');
  55225. } elseif (file_exists('phpunit.xml.dist')) {
  55226. $this->arguments['configuration'] = realpath(
  55227. 'phpunit.xml.dist'
  55228. );
  55229. }
  55230. }
  55231. if (isset($this->arguments['configuration'])) {
  55232. try {
  55233. $configuration = PHPUnit_Util_Configuration::getInstance(
  55234. $this->arguments['configuration']
  55235. );
  55236. } catch (Exception $e) {
  55237. print $e->getMessage() . "\n";
  55238. exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
  55239. }
  55240. $phpunit = $configuration->getPHPUnitConfiguration();
  55241. $configuration->handlePHPConfiguration();
  55242. /**
  55243. * Issue #1216
  55244. */
  55245. if (isset($this->arguments['bootstrap'])) {
  55246. $this->handleBootstrap($this->arguments['bootstrap']);
  55247. } elseif (isset($phpunit['bootstrap'])) {
  55248. $this->handleBootstrap($phpunit['bootstrap']);
  55249. }
  55250. /**
  55251. * Issue #657
  55252. */
  55253. if (isset($phpunit['stderr']) && ! isset($this->arguments['stderr'])) {
  55254. $this->arguments['stderr'] = $phpunit['stderr'];
  55255. }
  55256. if (isset($phpunit['printerClass'])) {
  55257. if (isset($phpunit['printerFile'])) {
  55258. $file = $phpunit['printerFile'];
  55259. } else {
  55260. $file = '';
  55261. }
  55262. $this->arguments['printer'] = $this->handlePrinter(
  55263. $phpunit['printerClass'],
  55264. $file
  55265. );
  55266. }
  55267. if (isset($phpunit['testSuiteLoaderClass'])) {
  55268. if (isset($phpunit['testSuiteLoaderFile'])) {
  55269. $file = $phpunit['testSuiteLoaderFile'];
  55270. } else {
  55271. $file = '';
  55272. }
  55273. $this->arguments['loader'] = $this->handleLoader(
  55274. $phpunit['testSuiteLoaderClass'],
  55275. $file
  55276. );
  55277. }
  55278. $browsers = $configuration->getSeleniumBrowserConfiguration();
  55279. if (!empty($browsers)) {
  55280. $this->arguments['deprecatedSeleniumConfiguration'] = true;
  55281. if (class_exists('PHPUnit_Extensions_SeleniumTestCase')) {
  55282. PHPUnit_Extensions_SeleniumTestCase::$browsers = $browsers;
  55283. }
  55284. }
  55285. if (!isset($this->arguments['test'])) {
  55286. $testSuite = $configuration->getTestSuiteConfiguration(isset($this->arguments['testsuite']) ? $this->arguments['testsuite'] : null);
  55287. if ($testSuite !== null) {
  55288. $this->arguments['test'] = $testSuite;
  55289. }
  55290. }
  55291. } elseif (isset($this->arguments['bootstrap'])) {
  55292. $this->handleBootstrap($this->arguments['bootstrap']);
  55293. }
  55294. if (isset($this->arguments['printer']) &&
  55295. is_string($this->arguments['printer'])) {
  55296. $this->arguments['printer'] = $this->handlePrinter($this->arguments['printer']);
  55297. }
  55298. if (isset($this->arguments['test']) && is_string($this->arguments['test']) && substr($this->arguments['test'], -5, 5) == '.phpt') {
  55299. $test = new PHPUnit_Extensions_PhptTestCase($this->arguments['test']);
  55300. $this->arguments['test'] = new PHPUnit_Framework_TestSuite;
  55301. $this->arguments['test']->addTest($test);
  55302. }
  55303. if (!isset($this->arguments['test']) ||
  55304. (isset($this->arguments['testDatabaseLogRevision']) && !isset($this->arguments['testDatabaseDSN']))) {
  55305. $this->showHelp();
  55306. exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
  55307. }
  55308. }
  55309. /**
  55310. * Handles the loading of the PHPUnit_Runner_TestSuiteLoader implementation.
  55311. *
  55312. * @param string $loaderClass
  55313. * @param string $loaderFile
  55314. * @return PHPUnit_Runner_TestSuiteLoader
  55315. */
  55316. protected function handleLoader($loaderClass, $loaderFile = '')
  55317. {
  55318. if (!class_exists($loaderClass, false)) {
  55319. if ($loaderFile == '') {
  55320. $loaderFile = PHPUnit_Util_Filesystem::classNameToFilename(
  55321. $loaderClass
  55322. );
  55323. }
  55324. $loaderFile = stream_resolve_include_path($loaderFile);
  55325. if ($loaderFile) {
  55326. require $loaderFile;
  55327. }
  55328. }
  55329. if (class_exists($loaderClass, false)) {
  55330. $class = new ReflectionClass($loaderClass);
  55331. if ($class->implementsInterface('PHPUnit_Runner_TestSuiteLoader') &&
  55332. $class->isInstantiable()) {
  55333. return $class->newInstance();
  55334. }
  55335. }
  55336. if ($loaderClass == 'PHPUnit_Runner_StandardTestSuiteLoader') {
  55337. return;
  55338. }
  55339. $this->showError(
  55340. sprintf(
  55341. 'Could not use "%s" as loader.',
  55342. $loaderClass
  55343. )
  55344. );
  55345. }
  55346. /**
  55347. * Handles the loading of the PHPUnit_Util_Printer implementation.
  55348. *
  55349. * @param string $printerClass
  55350. * @param string $printerFile
  55351. * @return PHPUnit_Util_Printer
  55352. */
  55353. protected function handlePrinter($printerClass, $printerFile = '')
  55354. {
  55355. if (!class_exists($printerClass, false)) {
  55356. if ($printerFile == '') {
  55357. $printerFile = PHPUnit_Util_Filesystem::classNameToFilename(
  55358. $printerClass
  55359. );
  55360. }
  55361. $printerFile = stream_resolve_include_path($printerFile);
  55362. if ($printerFile) {
  55363. require $printerFile;
  55364. }
  55365. }
  55366. if (class_exists($printerClass)) {
  55367. $class = new ReflectionClass($printerClass);
  55368. if ($class->implementsInterface('PHPUnit_Framework_TestListener') &&
  55369. $class->isSubclassOf('PHPUnit_Util_Printer') &&
  55370. $class->isInstantiable()) {
  55371. if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) {
  55372. return $printerClass;
  55373. }
  55374. $outputStream = isset($this->arguments['stderr']) ? 'php://stderr' : null;
  55375. return $class->newInstance($outputStream);
  55376. }
  55377. }
  55378. $this->showError(
  55379. sprintf(
  55380. 'Could not use "%s" as printer.',
  55381. $printerClass
  55382. )
  55383. );
  55384. }
  55385. /**
  55386. * Loads a bootstrap file.
  55387. *
  55388. * @param string $filename
  55389. */
  55390. protected function handleBootstrap($filename)
  55391. {
  55392. try {
  55393. PHPUnit_Util_Fileloader::checkAndLoad($filename);
  55394. } catch (PHPUnit_Framework_Exception $e) {
  55395. $this->showError($e->getMessage());
  55396. }
  55397. }
  55398. /**
  55399. * @since Method available since Release 4.0.0
  55400. */
  55401. protected function handleSelfUpdate()
  55402. {
  55403. $this->printVersionString();
  55404. $localFilename = realpath($_SERVER['argv'][0]);
  55405. if (!is_writable($localFilename)) {
  55406. print "No write permission to update " . $localFilename . "\n";
  55407. exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
  55408. }
  55409. if (!extension_loaded('openssl')) {
  55410. print "The OpenSSL extension is not loaded.\n";
  55411. exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
  55412. }
  55413. $remoteFilename = sprintf(
  55414. 'https://phar.phpunit.de/phpunit%s.phar',
  55415. PHPUnit_Runner_Version::getReleaseChannel()
  55416. );
  55417. $tempFilename = tempnam(sys_get_temp_dir(), 'phpunit') . '.phar';
  55418. // Workaround for https://bugs.php.net/bug.php?id=65538
  55419. $caFile = dirname($tempFilename) . '/ca.pem';
  55420. copy(__PHPUNIT_PHAR_ROOT__ . '/ca.pem', $caFile);
  55421. print 'Updating the PHPUnit PHAR ... ';
  55422. $options = array(
  55423. 'ssl' => array(
  55424. 'allow_self_signed' => false,
  55425. 'cafile' => $caFile,
  55426. 'verify_peer' => true
  55427. )
  55428. );
  55429. if (PHP_VERSION_ID < 50600) {
  55430. $options['ssl']['CN_match'] = 'phar.phpunit.de';
  55431. $options['ssl']['SNI_server_name'] = 'phar.phpunit.de';
  55432. }
  55433. file_put_contents(
  55434. $tempFilename,
  55435. file_get_contents(
  55436. $remoteFilename,
  55437. false,
  55438. stream_context_create($options)
  55439. )
  55440. );
  55441. chmod($tempFilename, 0777 & ~umask());
  55442. try {
  55443. $phar = new Phar($tempFilename);
  55444. unset($phar);
  55445. rename($tempFilename, $localFilename);
  55446. unlink($caFile);
  55447. } catch (Exception $e) {
  55448. unlink($caFile);
  55449. unlink($tempFilename);
  55450. print " done\n\n" . $e->getMessage() . "\n";
  55451. exit(2);
  55452. }
  55453. print " done\n";
  55454. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  55455. }
  55456. /**
  55457. * Show the help message.
  55458. */
  55459. protected function showHelp()
  55460. {
  55461. $this->printVersionString();
  55462. print <<<EOT
  55463. Usage: phpunit [options] UnitTest [UnitTest.php]
  55464. phpunit [options] <directory>
  55465. Code Coverage Options:
  55466. --coverage-clover <file> Generate code coverage report in Clover XML format.
  55467. --coverage-crap4j <file> Generate code coverage report in Crap4J XML format.
  55468. --coverage-html <dir> Generate code coverage report in HTML format.
  55469. --coverage-php <file> Export PHP_CodeCoverage object to file.
  55470. --coverage-text=<file> Generate code coverage report in text format.
  55471. Default: Standard output.
  55472. --coverage-xml <dir> Generate code coverage report in PHPUnit XML format.
  55473. Logging Options:
  55474. --log-junit <file> Log test execution in JUnit XML format to file.
  55475. --log-tap <file> Log test execution in TAP format to file.
  55476. --log-json <file> Log test execution in JSON format.
  55477. --testdox-html <file> Write agile documentation in HTML format to file.
  55478. --testdox-text <file> Write agile documentation in Text format to file.
  55479. Test Selection Options:
  55480. --filter <pattern> Filter which tests to run.
  55481. --testsuite <pattern> Filter which testsuite to run.
  55482. --group ... Only runs tests from the specified group(s).
  55483. --exclude-group ... Exclude tests from the specified group(s).
  55484. --list-groups List available test groups.
  55485. --test-suffix ... Only search for test in files with specified
  55486. suffix(es). Default: Test.php,.phpt
  55487. Test Execution Options:
  55488. --report-useless-tests Be strict about tests that do not test anything.
  55489. --strict-coverage Be strict about unintentionally covered code.
  55490. --strict-global-state Be strict about changes to global state
  55491. --disallow-test-output Be strict about output during tests.
  55492. --enforce-time-limit Enforce time limit based on test size.
  55493. --disallow-todo-tests Disallow @todo-annotated tests.
  55494. --process-isolation Run each test in a separate PHP process.
  55495. --no-globals-backup Do not backup and restore \$GLOBALS for each test.
  55496. --static-backup Backup and restore static attributes for each test.
  55497. --colors=<flag> Use colors in output ("never", "auto" or "always").
  55498. --columns <n> Number of columns to use for progress output.
  55499. --columns max Use maximum number of columns for progress output.
  55500. --stderr Write to STDERR instead of STDOUT.
  55501. --stop-on-error Stop execution upon first error.
  55502. --stop-on-failure Stop execution upon first error or failure.
  55503. --stop-on-risky Stop execution upon first risky test.
  55504. --stop-on-skipped Stop execution upon first skipped test.
  55505. --stop-on-incomplete Stop execution upon first incomplete test.
  55506. -v|--verbose Output more verbose information.
  55507. --debug Display debugging information during test execution.
  55508. --loader <loader> TestSuiteLoader implementation to use.
  55509. --repeat <times> Runs the test(s) repeatedly.
  55510. --tap Report test execution progress in TAP format.
  55511. --testdox Report test execution progress in TestDox format.
  55512. --printer <printer> TestListener implementation to use.
  55513. Configuration Options:
  55514. --bootstrap <file> A "bootstrap" PHP file that is run before the tests.
  55515. -c|--configuration <file> Read configuration from XML file.
  55516. --no-configuration Ignore default configuration file (phpunit.xml).
  55517. --include-path <path(s)> Prepend PHP's include_path with given path(s).
  55518. -d key[=value] Sets a php.ini value.
  55519. Miscellaneous Options:
  55520. -h|--help Prints this usage information.
  55521. --version Prints the version and exits.
  55522. EOT;
  55523. if (defined('__PHPUNIT_PHAR__')) {
  55524. print "\n --self-update Update PHPUnit to the latest version.\n";
  55525. }
  55526. }
  55527. /**
  55528. * Custom callback for test suite discovery.
  55529. */
  55530. protected function handleCustomTestSuite()
  55531. {
  55532. }
  55533. private function printVersionString()
  55534. {
  55535. if ($this->versionStringPrinted) {
  55536. return;
  55537. }
  55538. print PHPUnit_Runner_Version::getVersionString() . "\n\n";
  55539. $this->versionStringPrinted = true;
  55540. }
  55541. /**
  55542. */
  55543. private function showError($message)
  55544. {
  55545. $this->printVersionString();
  55546. print $message . "\n";
  55547. exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
  55548. }
  55549. }
  55550. <?php
  55551. /*
  55552. * This file is part of PHPUnit.
  55553. *
  55554. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55555. *
  55556. * For the full copyright and license information, please view the LICENSE
  55557. * file that was distributed with this source code.
  55558. */
  55559. use SebastianBergmann\Environment\Runtime;
  55560. /**
  55561. * A TestRunner for the Command Line Interface (CLI)
  55562. * PHP SAPI Module.
  55563. *
  55564. * @package PHPUnit
  55565. * @subpackage TextUI
  55566. * @author Sebastian Bergmann <sebastian@phpunit.de>
  55567. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  55568. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  55569. * @link http://www.phpunit.de/
  55570. * @since Class available since Release 2.0.0
  55571. */
  55572. class PHPUnit_TextUI_TestRunner extends PHPUnit_Runner_BaseTestRunner
  55573. {
  55574. const SUCCESS_EXIT = 0;
  55575. const FAILURE_EXIT = 1;
  55576. const EXCEPTION_EXIT = 2;
  55577. /**
  55578. * @var PHP_CodeCoverage_Filter
  55579. */
  55580. protected $codeCoverageFilter;
  55581. /**
  55582. * @var PHPUnit_Runner_TestSuiteLoader
  55583. */
  55584. protected $loader = null;
  55585. /**
  55586. * @var PHPUnit_TextUI_ResultPrinter
  55587. */
  55588. protected $printer = null;
  55589. /**
  55590. * @var boolean
  55591. */
  55592. protected static $versionStringPrinted = false;
  55593. /**
  55594. * @var array
  55595. */
  55596. private $missingExtensions = array();
  55597. /**
  55598. * @var Runtime
  55599. */
  55600. private $runtime;
  55601. /**
  55602. * @param PHPUnit_Runner_TestSuiteLoader $loader
  55603. * @param PHP_CodeCoverage_Filter $filter
  55604. * @since Method available since Release 3.4.0
  55605. */
  55606. public function __construct(PHPUnit_Runner_TestSuiteLoader $loader = null, PHP_CodeCoverage_Filter $filter = null)
  55607. {
  55608. if ($filter === null) {
  55609. $filter = $this->getCodeCoverageFilter();
  55610. }
  55611. $this->codeCoverageFilter = $filter;
  55612. $this->loader = $loader;
  55613. $this->runtime = new Runtime;
  55614. }
  55615. /**
  55616. * @param PHPUnit_Framework_Test|ReflectionClass $test
  55617. * @param array $arguments
  55618. * @return PHPUnit_Framework_TestResult
  55619. * @throws PHPUnit_Framework_Exception
  55620. */
  55621. public static function run($test, array $arguments = array())
  55622. {
  55623. if ($test instanceof ReflectionClass) {
  55624. $test = new PHPUnit_Framework_TestSuite($test);
  55625. }
  55626. if ($test instanceof PHPUnit_Framework_Test) {
  55627. $aTestRunner = new PHPUnit_TextUI_TestRunner;
  55628. return $aTestRunner->doRun(
  55629. $test,
  55630. $arguments
  55631. );
  55632. } else {
  55633. throw new PHPUnit_Framework_Exception(
  55634. 'No test case or test suite found.'
  55635. );
  55636. }
  55637. }
  55638. /**
  55639. * @return PHPUnit_Framework_TestResult
  55640. */
  55641. protected function createTestResult()
  55642. {
  55643. return new PHPUnit_Framework_TestResult;
  55644. }
  55645. private function processSuiteFilters(PHPUnit_Framework_TestSuite $suite, array $arguments)
  55646. {
  55647. if (!$arguments['filter'] &&
  55648. empty($arguments['groups']) &&
  55649. empty($arguments['excludeGroups'])) {
  55650. return;
  55651. }
  55652. $filterFactory = new PHPUnit_Runner_Filter_Factory();
  55653. if (!empty($arguments['excludeGroups'])) {
  55654. $filterFactory->addFilter(
  55655. new ReflectionClass('PHPUnit_Runner_Filter_Group_Exclude'),
  55656. $arguments['excludeGroups']
  55657. );
  55658. }
  55659. if (!empty($arguments['groups'])) {
  55660. $filterFactory->addFilter(
  55661. new ReflectionClass('PHPUnit_Runner_Filter_Group_Include'),
  55662. $arguments['groups']
  55663. );
  55664. }
  55665. if ($arguments['filter']) {
  55666. $filterFactory->addFilter(
  55667. new ReflectionClass('PHPUnit_Runner_Filter_Test'),
  55668. $arguments['filter']
  55669. );
  55670. }
  55671. $suite->injectFilter($filterFactory);
  55672. }
  55673. /**
  55674. * @param PHPUnit_Framework_Test $suite
  55675. * @param array $arguments
  55676. * @return PHPUnit_Framework_TestResult
  55677. */
  55678. public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array())
  55679. {
  55680. $this->handleConfiguration($arguments);
  55681. $this->processSuiteFilters($suite, $arguments);
  55682. if (isset($arguments['bootstrap'])) {
  55683. $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $arguments['bootstrap'];
  55684. }
  55685. if ($arguments['backupGlobals'] === false) {
  55686. $suite->setBackupGlobals(false);
  55687. }
  55688. if ($arguments['backupStaticAttributes'] === true) {
  55689. $suite->setBackupStaticAttributes(true);
  55690. }
  55691. if ($arguments['disallowChangesToGlobalState'] === true) {
  55692. $suite->setDisallowChangesToGlobalState(true);
  55693. }
  55694. if (is_integer($arguments['repeat'])) {
  55695. $test = new PHPUnit_Extensions_RepeatedTest(
  55696. $suite,
  55697. $arguments['repeat'],
  55698. $arguments['processIsolation']
  55699. );
  55700. $suite = new PHPUnit_Framework_TestSuite();
  55701. $suite->addTest($test);
  55702. }
  55703. $result = $this->createTestResult();
  55704. if (!$arguments['convertErrorsToExceptions']) {
  55705. $result->convertErrorsToExceptions(false);
  55706. }
  55707. if (!$arguments['convertNoticesToExceptions']) {
  55708. PHPUnit_Framework_Error_Notice::$enabled = false;
  55709. }
  55710. if (!$arguments['convertWarningsToExceptions']) {
  55711. PHPUnit_Framework_Error_Warning::$enabled = false;
  55712. }
  55713. if ($arguments['stopOnError']) {
  55714. $result->stopOnError(true);
  55715. }
  55716. if ($arguments['stopOnFailure']) {
  55717. $result->stopOnFailure(true);
  55718. }
  55719. if ($arguments['stopOnIncomplete']) {
  55720. $result->stopOnIncomplete(true);
  55721. }
  55722. if ($arguments['stopOnRisky']) {
  55723. $result->stopOnRisky(true);
  55724. }
  55725. if ($arguments['stopOnSkipped']) {
  55726. $result->stopOnSkipped(true);
  55727. }
  55728. if ($this->printer === null) {
  55729. if (isset($arguments['printer']) &&
  55730. $arguments['printer'] instanceof PHPUnit_Util_Printer) {
  55731. $this->printer = $arguments['printer'];
  55732. } else {
  55733. $printerClass = 'PHPUnit_TextUI_ResultPrinter';
  55734. if (isset($arguments['printer']) &&
  55735. is_string($arguments['printer']) &&
  55736. class_exists($arguments['printer'], false)) {
  55737. $class = new ReflectionClass($arguments['printer']);
  55738. if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) {
  55739. $printerClass = $arguments['printer'];
  55740. }
  55741. }
  55742. $this->printer = new $printerClass(
  55743. isset($arguments['stderr']) ? 'php://stderr' : null,
  55744. $arguments['verbose'],
  55745. $arguments['colors'],
  55746. $arguments['debug'],
  55747. $arguments['columns']
  55748. );
  55749. }
  55750. }
  55751. if (!$this->printer instanceof PHPUnit_Util_Log_TAP) {
  55752. $this->printer->write(
  55753. PHPUnit_Runner_Version::getVersionString() . "\n"
  55754. );
  55755. self::$versionStringPrinted = true;
  55756. if ($arguments['verbose']) {
  55757. $this->printer->write(
  55758. sprintf(
  55759. "\nRuntime:\t%s",
  55760. $this->runtime->getNameWithVersion()
  55761. )
  55762. );
  55763. if ($this->runtime->hasXdebug()) {
  55764. $this->printer->write(
  55765. sprintf(
  55766. " with Xdebug %s",
  55767. phpversion('xdebug')
  55768. )
  55769. );
  55770. }
  55771. if (isset($arguments['configuration'])) {
  55772. $this->printer->write(
  55773. sprintf(
  55774. "\nConfiguration:\t%s",
  55775. $arguments['configuration']->getFilename()
  55776. )
  55777. );
  55778. }
  55779. $this->printer->write("\n");
  55780. }
  55781. if (isset($arguments['deprecatedStrictModeOption'])) {
  55782. print "Warning:\tDeprecated option \"--strict\" used\n";
  55783. } elseif (isset($arguments['deprecatedStrictModeSetting'])) {
  55784. print "Warning:\tDeprecated configuration setting \"strict\" used\n";
  55785. }
  55786. if (isset($arguments['deprecatedSeleniumConfiguration'])) {
  55787. print "Warning:\tDeprecated configuration setting \"selenium\" used\n";
  55788. }
  55789. }
  55790. foreach ($arguments['listeners'] as $listener) {
  55791. $result->addListener($listener);
  55792. }
  55793. $result->addListener($this->printer);
  55794. if (isset($arguments['testdoxHTMLFile'])) {
  55795. $result->addListener(
  55796. new PHPUnit_Util_TestDox_ResultPrinter_HTML(
  55797. $arguments['testdoxHTMLFile']
  55798. )
  55799. );
  55800. }
  55801. if (isset($arguments['testdoxTextFile'])) {
  55802. $result->addListener(
  55803. new PHPUnit_Util_TestDox_ResultPrinter_Text(
  55804. $arguments['testdoxTextFile']
  55805. )
  55806. );
  55807. }
  55808. $codeCoverageReports = 0;
  55809. if (isset($arguments['coverageClover'])) {
  55810. $codeCoverageReports++;
  55811. }
  55812. if (isset($arguments['coverageCrap4J'])) {
  55813. $codeCoverageReports++;
  55814. }
  55815. if (isset($arguments['coverageHtml'])) {
  55816. $codeCoverageReports++;
  55817. }
  55818. if (isset($arguments['coveragePHP'])) {
  55819. $codeCoverageReports++;
  55820. }
  55821. if (isset($arguments['coverageText'])) {
  55822. $codeCoverageReports++;
  55823. }
  55824. if (isset($arguments['coverageXml'])) {
  55825. $codeCoverageReports++;
  55826. }
  55827. if (!$this->printer instanceof PHPUnit_Util_Log_TAP) {
  55828. if ($codeCoverageReports > 0 && !$this->codeCoverageFilter->hasWhitelist()) {
  55829. $this->printer->write("Warning:\tNo whitelist configured for code coverage\n");
  55830. }
  55831. $this->printer->write("\n");
  55832. }
  55833. if ($codeCoverageReports > 0 && (!extension_loaded('tokenizer') || !$this->runtime->canCollectCodeCoverage())) {
  55834. if (!extension_loaded('tokenizer')) {
  55835. $this->showExtensionNotLoadedMessage(
  55836. 'tokenizer',
  55837. 'No code coverage will be generated.'
  55838. );
  55839. } elseif (!extension_loaded('Xdebug')) {
  55840. $this->showExtensionNotLoadedMessage(
  55841. 'Xdebug',
  55842. 'No code coverage will be generated.'
  55843. );
  55844. }
  55845. $codeCoverageReports = 0;
  55846. }
  55847. if ($codeCoverageReports > 0) {
  55848. $codeCoverage = new PHP_CodeCoverage(
  55849. null,
  55850. $this->codeCoverageFilter
  55851. );
  55852. $codeCoverage->setAddUncoveredFilesFromWhitelist(
  55853. $arguments['addUncoveredFilesFromWhitelist']
  55854. );
  55855. $codeCoverage->setCheckForUnintentionallyCoveredCode(
  55856. $arguments['strictCoverage']
  55857. );
  55858. $codeCoverage->setProcessUncoveredFilesFromWhitelist(
  55859. $arguments['processUncoveredFilesFromWhitelist']
  55860. );
  55861. if (isset($arguments['forceCoversAnnotation'])) {
  55862. $codeCoverage->setForceCoversAnnotation(
  55863. $arguments['forceCoversAnnotation']
  55864. );
  55865. }
  55866. if (isset($arguments['mapTestClassNameToCoveredClassName'])) {
  55867. $codeCoverage->setMapTestClassNameToCoveredClassName(
  55868. $arguments['mapTestClassNameToCoveredClassName']
  55869. );
  55870. }
  55871. $result->setCodeCoverage($codeCoverage);
  55872. }
  55873. if ($codeCoverageReports > 1) {
  55874. if (isset($arguments['cacheTokens'])) {
  55875. $codeCoverage->setCacheTokens($arguments['cacheTokens']);
  55876. }
  55877. }
  55878. if (isset($arguments['jsonLogfile'])) {
  55879. $result->addListener(
  55880. new PHPUnit_Util_Log_JSON($arguments['jsonLogfile'])
  55881. );
  55882. }
  55883. if (isset($arguments['tapLogfile'])) {
  55884. $result->addListener(
  55885. new PHPUnit_Util_Log_TAP($arguments['tapLogfile'])
  55886. );
  55887. }
  55888. if (isset($arguments['junitLogfile'])) {
  55889. $result->addListener(
  55890. new PHPUnit_Util_Log_JUnit(
  55891. $arguments['junitLogfile'],
  55892. $arguments['logIncompleteSkipped']
  55893. )
  55894. );
  55895. }
  55896. $result->beStrictAboutTestsThatDoNotTestAnything($arguments['reportUselessTests']);
  55897. $result->beStrictAboutOutputDuringTests($arguments['disallowTestOutput']);
  55898. $result->beStrictAboutTodoAnnotatedTests($arguments['disallowTodoAnnotatedTests']);
  55899. $result->beStrictAboutTestSize($arguments['enforceTimeLimit']);
  55900. $result->setTimeoutForSmallTests($arguments['timeoutForSmallTests']);
  55901. $result->setTimeoutForMediumTests($arguments['timeoutForMediumTests']);
  55902. $result->setTimeoutForLargeTests($arguments['timeoutForLargeTests']);
  55903. if ($suite instanceof PHPUnit_Framework_TestSuite) {
  55904. $suite->setRunTestInSeparateProcess($arguments['processIsolation']);
  55905. }
  55906. $suite->run($result);
  55907. unset($suite);
  55908. $result->flushListeners();
  55909. if ($this->printer instanceof PHPUnit_TextUI_ResultPrinter) {
  55910. $this->printer->printResult($result);
  55911. }
  55912. if (isset($codeCoverage)) {
  55913. if (isset($arguments['coverageClover'])) {
  55914. $this->printer->write(
  55915. "\nGenerating code coverage report in Clover XML format ..."
  55916. );
  55917. $writer = new PHP_CodeCoverage_Report_Clover;
  55918. $writer->process($codeCoverage, $arguments['coverageClover']);
  55919. $this->printer->write(" done\n");
  55920. unset($writer);
  55921. }
  55922. if (isset($arguments['coverageCrap4J'])) {
  55923. $this->printer->write(
  55924. "\nGenerating Crap4J report XML file ..."
  55925. );
  55926. $writer = new PHP_CodeCoverage_Report_Crap4j;
  55927. $writer->process($codeCoverage, $arguments['coverageCrap4J']);
  55928. $this->printer->write(" done\n");
  55929. unset($writer);
  55930. }
  55931. if (isset($arguments['coverageHtml'])) {
  55932. $this->printer->write(
  55933. "\nGenerating code coverage report in HTML format ..."
  55934. );
  55935. $writer = new PHP_CodeCoverage_Report_HTML(
  55936. $arguments['reportLowUpperBound'],
  55937. $arguments['reportHighLowerBound'],
  55938. sprintf(
  55939. ' and <a href="http://phpunit.de/">PHPUnit %s</a>',
  55940. PHPUnit_Runner_Version::id()
  55941. )
  55942. );
  55943. $writer->process($codeCoverage, $arguments['coverageHtml']);
  55944. $this->printer->write(" done\n");
  55945. unset($writer);
  55946. }
  55947. if (isset($arguments['coveragePHP'])) {
  55948. $this->printer->write(
  55949. "\nGenerating code coverage report in PHP format ..."
  55950. );
  55951. $writer = new PHP_CodeCoverage_Report_PHP;
  55952. $writer->process($codeCoverage, $arguments['coveragePHP']);
  55953. $this->printer->write(" done\n");
  55954. unset($writer);
  55955. }
  55956. if (isset($arguments['coverageText'])) {
  55957. if ($arguments['coverageText'] == 'php://stdout') {
  55958. $outputStream = $this->printer;
  55959. $colors = $arguments['colors'];
  55960. } else {
  55961. $outputStream = new PHPUnit_Util_Printer($arguments['coverageText']);
  55962. $colors = false;
  55963. }
  55964. $processor = new PHP_CodeCoverage_Report_Text(
  55965. $arguments['reportLowUpperBound'],
  55966. $arguments['reportHighLowerBound'],
  55967. $arguments['coverageTextShowUncoveredFiles'],
  55968. $arguments['coverageTextShowOnlySummary']
  55969. );
  55970. $outputStream->write(
  55971. $processor->process($codeCoverage, $colors)
  55972. );
  55973. }
  55974. if (isset($arguments['coverageXml'])) {
  55975. $this->printer->write(
  55976. "\nGenerating code coverage report in PHPUnit XML format ..."
  55977. );
  55978. $writer = new PHP_CodeCoverage_Report_XML;
  55979. $writer->process($codeCoverage, $arguments['coverageXml']);
  55980. $this->printer->write(" done\n");
  55981. unset($writer);
  55982. }
  55983. }
  55984. return $result;
  55985. }
  55986. /**
  55987. * @param PHPUnit_TextUI_ResultPrinter $resultPrinter
  55988. */
  55989. public function setPrinter(PHPUnit_TextUI_ResultPrinter $resultPrinter)
  55990. {
  55991. $this->printer = $resultPrinter;
  55992. }
  55993. /**
  55994. * Override to define how to handle a failed loading of
  55995. * a test suite.
  55996. *
  55997. * @param string $message
  55998. */
  55999. protected function runFailed($message)
  56000. {
  56001. $this->write($message . PHP_EOL);
  56002. exit(self::FAILURE_EXIT);
  56003. }
  56004. /**
  56005. * @param string $buffer
  56006. * @since Method available since Release 3.1.0
  56007. */
  56008. protected function write($buffer)
  56009. {
  56010. if (PHP_SAPI != 'cli') {
  56011. $buffer = htmlspecialchars($buffer);
  56012. }
  56013. if ($this->printer !== null) {
  56014. $this->printer->write($buffer);
  56015. } else {
  56016. print $buffer;
  56017. }
  56018. }
  56019. /**
  56020. * Returns the loader to be used.
  56021. *
  56022. * @return PHPUnit_Runner_TestSuiteLoader
  56023. * @since Method available since Release 2.2.0
  56024. */
  56025. public function getLoader()
  56026. {
  56027. if ($this->loader === null) {
  56028. $this->loader = new PHPUnit_Runner_StandardTestSuiteLoader;
  56029. }
  56030. return $this->loader;
  56031. }
  56032. /**
  56033. * @param array $arguments
  56034. * @since Method available since Release 3.2.1
  56035. */
  56036. protected function handleConfiguration(array &$arguments)
  56037. {
  56038. if (isset($arguments['configuration']) &&
  56039. !$arguments['configuration'] instanceof PHPUnit_Util_Configuration) {
  56040. $arguments['configuration'] = PHPUnit_Util_Configuration::getInstance(
  56041. $arguments['configuration']
  56042. );
  56043. }
  56044. $arguments['debug'] = isset($arguments['debug']) ? $arguments['debug'] : false;
  56045. $arguments['filter'] = isset($arguments['filter']) ? $arguments['filter'] : false;
  56046. $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array();
  56047. if (isset($arguments['configuration'])) {
  56048. $arguments['configuration']->handlePHPConfiguration();
  56049. $phpunitConfiguration = $arguments['configuration']->getPHPUnitConfiguration();
  56050. if (isset($phpunitConfiguration['deprecatedStrictModeSetting'])) {
  56051. $arguments['deprecatedStrictModeSetting'] = true;
  56052. }
  56053. if (isset($phpunitConfiguration['backupGlobals']) &&
  56054. !isset($arguments['backupGlobals'])) {
  56055. $arguments['backupGlobals'] = $phpunitConfiguration['backupGlobals'];
  56056. }
  56057. if (isset($phpunitConfiguration['backupStaticAttributes']) &&
  56058. !isset($arguments['backupStaticAttributes'])) {
  56059. $arguments['backupStaticAttributes'] = $phpunitConfiguration['backupStaticAttributes'];
  56060. }
  56061. if (isset($phpunitConfiguration['disallowChangesToGlobalState']) &&
  56062. !isset($arguments['disallowChangesToGlobalState'])) {
  56063. $arguments['disallowChangesToGlobalState'] = $phpunitConfiguration['disallowChangesToGlobalState'];
  56064. }
  56065. if (isset($phpunitConfiguration['bootstrap']) &&
  56066. !isset($arguments['bootstrap'])) {
  56067. $arguments['bootstrap'] = $phpunitConfiguration['bootstrap'];
  56068. }
  56069. if (isset($phpunitConfiguration['cacheTokens']) &&
  56070. !isset($arguments['cacheTokens'])) {
  56071. $arguments['cacheTokens'] = $phpunitConfiguration['cacheTokens'];
  56072. }
  56073. if (isset($phpunitConfiguration['colors']) &&
  56074. !isset($arguments['colors'])) {
  56075. $arguments['colors'] = $phpunitConfiguration['colors'];
  56076. }
  56077. if (isset($phpunitConfiguration['convertErrorsToExceptions']) &&
  56078. !isset($arguments['convertErrorsToExceptions'])) {
  56079. $arguments['convertErrorsToExceptions'] = $phpunitConfiguration['convertErrorsToExceptions'];
  56080. }
  56081. if (isset($phpunitConfiguration['convertNoticesToExceptions']) &&
  56082. !isset($arguments['convertNoticesToExceptions'])) {
  56083. $arguments['convertNoticesToExceptions'] = $phpunitConfiguration['convertNoticesToExceptions'];
  56084. }
  56085. if (isset($phpunitConfiguration['convertWarningsToExceptions']) &&
  56086. !isset($arguments['convertWarningsToExceptions'])) {
  56087. $arguments['convertWarningsToExceptions'] = $phpunitConfiguration['convertWarningsToExceptions'];
  56088. }
  56089. if (isset($phpunitConfiguration['processIsolation']) &&
  56090. !isset($arguments['processIsolation'])) {
  56091. $arguments['processIsolation'] = $phpunitConfiguration['processIsolation'];
  56092. }
  56093. if (isset($phpunitConfiguration['stopOnFailure']) &&
  56094. !isset($arguments['stopOnFailure'])) {
  56095. $arguments['stopOnFailure'] = $phpunitConfiguration['stopOnFailure'];
  56096. }
  56097. if (isset($phpunitConfiguration['timeoutForSmallTests']) &&
  56098. !isset($arguments['timeoutForSmallTests'])) {
  56099. $arguments['timeoutForSmallTests'] = $phpunitConfiguration['timeoutForSmallTests'];
  56100. }
  56101. if (isset($phpunitConfiguration['timeoutForMediumTests']) &&
  56102. !isset($arguments['timeoutForMediumTests'])) {
  56103. $arguments['timeoutForMediumTests'] = $phpunitConfiguration['timeoutForMediumTests'];
  56104. }
  56105. if (isset($phpunitConfiguration['timeoutForLargeTests']) &&
  56106. !isset($arguments['timeoutForLargeTests'])) {
  56107. $arguments['timeoutForLargeTests'] = $phpunitConfiguration['timeoutForLargeTests'];
  56108. }
  56109. if (isset($phpunitConfiguration['reportUselessTests']) &&
  56110. !isset($arguments['reportUselessTests'])) {
  56111. $arguments['reportUselessTests'] = $phpunitConfiguration['reportUselessTests'];
  56112. }
  56113. if (isset($phpunitConfiguration['strictCoverage']) &&
  56114. !isset($arguments['strictCoverage'])) {
  56115. $arguments['strictCoverage'] = $phpunitConfiguration['strictCoverage'];
  56116. }
  56117. if (isset($phpunitConfiguration['disallowTestOutput']) &&
  56118. !isset($arguments['disallowTestOutput'])) {
  56119. $arguments['disallowTestOutput'] = $phpunitConfiguration['disallowTestOutput'];
  56120. }
  56121. if (isset($phpunitConfiguration['enforceTimeLimit']) &&
  56122. !isset($arguments['enforceTimeLimit'])) {
  56123. $arguments['enforceTimeLimit'] = $phpunitConfiguration['enforceTimeLimit'];
  56124. }
  56125. if (isset($phpunitConfiguration['disallowTodoAnnotatedTests']) &&
  56126. !isset($arguments['disallowTodoAnnotatedTests'])) {
  56127. $arguments['disallowTodoAnnotatedTests'] = $phpunitConfiguration['disallowTodoAnnotatedTests'];
  56128. }
  56129. if (isset($phpunitConfiguration['verbose']) &&
  56130. !isset($arguments['verbose'])) {
  56131. $arguments['verbose'] = $phpunitConfiguration['verbose'];
  56132. }
  56133. if (isset($phpunitConfiguration['forceCoversAnnotation']) &&
  56134. !isset($arguments['forceCoversAnnotation'])) {
  56135. $arguments['forceCoversAnnotation'] = $phpunitConfiguration['forceCoversAnnotation'];
  56136. }
  56137. if (isset($phpunitConfiguration['mapTestClassNameToCoveredClassName']) &&
  56138. !isset($arguments['mapTestClassNameToCoveredClassName'])) {
  56139. $arguments['mapTestClassNameToCoveredClassName'] = $phpunitConfiguration['mapTestClassNameToCoveredClassName'];
  56140. }
  56141. $groupCliArgs = array();
  56142. if (!empty($arguments['groups'])) {
  56143. $groupCliArgs = $arguments['groups'];
  56144. }
  56145. $groupConfiguration = $arguments['configuration']->getGroupConfiguration();
  56146. if (!empty($groupConfiguration['include']) &&
  56147. !isset($arguments['groups'])) {
  56148. $arguments['groups'] = $groupConfiguration['include'];
  56149. }
  56150. if (!empty($groupConfiguration['exclude']) &&
  56151. !isset($arguments['excludeGroups'])) {
  56152. $arguments['excludeGroups'] = array_diff($groupConfiguration['exclude'], $groupCliArgs);
  56153. }
  56154. foreach ($arguments['configuration']->getListenerConfiguration() as $listener) {
  56155. if (!class_exists($listener['class'], false) &&
  56156. $listener['file'] !== '') {
  56157. require_once $listener['file'];
  56158. }
  56159. if (class_exists($listener['class'])) {
  56160. if (count($listener['arguments']) == 0) {
  56161. $listener = new $listener['class'];
  56162. } else {
  56163. $listenerClass = new ReflectionClass(
  56164. $listener['class']
  56165. );
  56166. $listener = $listenerClass->newInstanceArgs(
  56167. $listener['arguments']
  56168. );
  56169. }
  56170. if ($listener instanceof PHPUnit_Framework_TestListener) {
  56171. $arguments['listeners'][] = $listener;
  56172. }
  56173. }
  56174. }
  56175. $loggingConfiguration = $arguments['configuration']->getLoggingConfiguration();
  56176. if (isset($loggingConfiguration['coverage-clover']) &&
  56177. !isset($arguments['coverageClover'])) {
  56178. $arguments['coverageClover'] = $loggingConfiguration['coverage-clover'];
  56179. }
  56180. if (isset($loggingConfiguration['coverage-crap4j']) &&
  56181. !isset($arguments['coverageCrap4J'])) {
  56182. $arguments['coverageCrap4J'] = $loggingConfiguration['coverage-crap4j'];
  56183. }
  56184. if (isset($loggingConfiguration['coverage-html']) &&
  56185. !isset($arguments['coverageHtml'])) {
  56186. if (isset($loggingConfiguration['lowUpperBound']) &&
  56187. !isset($arguments['reportLowUpperBound'])) {
  56188. $arguments['reportLowUpperBound'] = $loggingConfiguration['lowUpperBound'];
  56189. }
  56190. if (isset($loggingConfiguration['highLowerBound']) &&
  56191. !isset($arguments['reportHighLowerBound'])) {
  56192. $arguments['reportHighLowerBound'] = $loggingConfiguration['highLowerBound'];
  56193. }
  56194. $arguments['coverageHtml'] = $loggingConfiguration['coverage-html'];
  56195. }
  56196. if (isset($loggingConfiguration['coverage-php']) &&
  56197. !isset($arguments['coveragePHP'])) {
  56198. $arguments['coveragePHP'] = $loggingConfiguration['coverage-php'];
  56199. }
  56200. if (isset($loggingConfiguration['coverage-text']) &&
  56201. !isset($arguments['coverageText'])) {
  56202. $arguments['coverageText'] = $loggingConfiguration['coverage-text'];
  56203. if (isset($loggingConfiguration['coverageTextShowUncoveredFiles'])) {
  56204. $arguments['coverageTextShowUncoveredFiles'] = $loggingConfiguration['coverageTextShowUncoveredFiles'];
  56205. } else {
  56206. $arguments['coverageTextShowUncoveredFiles'] = false;
  56207. }
  56208. if (isset($loggingConfiguration['coverageTextShowOnlySummary'])) {
  56209. $arguments['coverageTextShowOnlySummary'] = $loggingConfiguration['coverageTextShowOnlySummary'];
  56210. } else {
  56211. $arguments['coverageTextShowOnlySummary'] = false;
  56212. }
  56213. }
  56214. if (isset($loggingConfiguration['coverage-xml']) &&
  56215. !isset($arguments['coverageXml'])) {
  56216. $arguments['coverageXml'] = $loggingConfiguration['coverage-xml'];
  56217. }
  56218. if (isset($loggingConfiguration['json']) &&
  56219. !isset($arguments['jsonLogfile'])) {
  56220. $arguments['jsonLogfile'] = $loggingConfiguration['json'];
  56221. }
  56222. if (isset($loggingConfiguration['plain'])) {
  56223. $arguments['listeners'][] = new PHPUnit_TextUI_ResultPrinter(
  56224. $loggingConfiguration['plain'],
  56225. true
  56226. );
  56227. }
  56228. if (isset($loggingConfiguration['tap']) &&
  56229. !isset($arguments['tapLogfile'])) {
  56230. $arguments['tapLogfile'] = $loggingConfiguration['tap'];
  56231. }
  56232. if (isset($loggingConfiguration['junit']) &&
  56233. !isset($arguments['junitLogfile'])) {
  56234. $arguments['junitLogfile'] = $loggingConfiguration['junit'];
  56235. if (isset($loggingConfiguration['logIncompleteSkipped']) &&
  56236. !isset($arguments['logIncompleteSkipped'])) {
  56237. $arguments['logIncompleteSkipped'] = $loggingConfiguration['logIncompleteSkipped'];
  56238. }
  56239. }
  56240. if (isset($loggingConfiguration['testdox-html']) &&
  56241. !isset($arguments['testdoxHTMLFile'])) {
  56242. $arguments['testdoxHTMLFile'] = $loggingConfiguration['testdox-html'];
  56243. }
  56244. if (isset($loggingConfiguration['testdox-text']) &&
  56245. !isset($arguments['testdoxTextFile'])) {
  56246. $arguments['testdoxTextFile'] = $loggingConfiguration['testdox-text'];
  56247. }
  56248. if ((isset($arguments['coverageClover']) ||
  56249. isset($arguments['coverageCrap4J']) ||
  56250. isset($arguments['coverageHtml']) ||
  56251. isset($arguments['coveragePHP']) ||
  56252. isset($arguments['coverageText']) ||
  56253. isset($arguments['coverageXml'])) &&
  56254. $this->runtime->canCollectCodeCoverage()) {
  56255. $filterConfiguration = $arguments['configuration']->getFilterConfiguration();
  56256. $arguments['addUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist'];
  56257. $arguments['processUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['processUncoveredFilesFromWhitelist'];
  56258. if (empty($filterConfiguration['whitelist']['include']['directory']) &&
  56259. empty($filterConfiguration['whitelist']['include']['file'])) {
  56260. foreach ($filterConfiguration['blacklist']['include']['directory'] as $dir) {
  56261. $this->codeCoverageFilter->addDirectoryToBlacklist(
  56262. $dir['path'],
  56263. $dir['suffix'],
  56264. $dir['prefix'],
  56265. $dir['group']
  56266. );
  56267. }
  56268. foreach ($filterConfiguration['blacklist']['include']['file'] as $file) {
  56269. $this->codeCoverageFilter->addFileToBlacklist($file);
  56270. }
  56271. foreach ($filterConfiguration['blacklist']['exclude']['directory'] as $dir) {
  56272. $this->codeCoverageFilter->removeDirectoryFromBlacklist(
  56273. $dir['path'],
  56274. $dir['suffix'],
  56275. $dir['prefix'],
  56276. $dir['group']
  56277. );
  56278. }
  56279. foreach ($filterConfiguration['blacklist']['exclude']['file'] as $file) {
  56280. $this->codeCoverageFilter->removeFileFromBlacklist($file);
  56281. }
  56282. }
  56283. foreach ($filterConfiguration['whitelist']['include']['directory'] as $dir) {
  56284. $this->codeCoverageFilter->addDirectoryToWhitelist(
  56285. $dir['path'],
  56286. $dir['suffix'],
  56287. $dir['prefix']
  56288. );
  56289. }
  56290. foreach ($filterConfiguration['whitelist']['include']['file'] as $file) {
  56291. $this->codeCoverageFilter->addFileToWhitelist($file);
  56292. }
  56293. foreach ($filterConfiguration['whitelist']['exclude']['directory'] as $dir) {
  56294. $this->codeCoverageFilter->removeDirectoryFromWhitelist(
  56295. $dir['path'],
  56296. $dir['suffix'],
  56297. $dir['prefix']
  56298. );
  56299. }
  56300. foreach ($filterConfiguration['whitelist']['exclude']['file'] as $file) {
  56301. $this->codeCoverageFilter->removeFileFromWhitelist($file);
  56302. }
  56303. }
  56304. }
  56305. $arguments['addUncoveredFilesFromWhitelist'] = isset($arguments['addUncoveredFilesFromWhitelist']) ? $arguments['addUncoveredFilesFromWhitelist'] : true;
  56306. $arguments['processUncoveredFilesFromWhitelist'] = isset($arguments['processUncoveredFilesFromWhitelist']) ? $arguments['processUncoveredFilesFromWhitelist'] : false;
  56307. $arguments['backupGlobals'] = isset($arguments['backupGlobals']) ? $arguments['backupGlobals'] : null;
  56308. $arguments['backupStaticAttributes'] = isset($arguments['backupStaticAttributes']) ? $arguments['backupStaticAttributes'] : null;
  56309. $arguments['disallowChangesToGlobalState'] = isset($arguments['disallowChangesToGlobalState']) ? $arguments['disallowChangesToGlobalState'] : null;
  56310. $arguments['cacheTokens'] = isset($arguments['cacheTokens']) ? $arguments['cacheTokens'] : false;
  56311. $arguments['columns'] = isset($arguments['columns']) ? $arguments['columns'] : 80;
  56312. $arguments['colors'] = isset($arguments['colors']) ? $arguments['colors'] : PHPUnit_TextUI_ResultPrinter::COLOR_DEFAULT;
  56313. $arguments['convertErrorsToExceptions'] = isset($arguments['convertErrorsToExceptions']) ? $arguments['convertErrorsToExceptions'] : true;
  56314. $arguments['convertNoticesToExceptions'] = isset($arguments['convertNoticesToExceptions']) ? $arguments['convertNoticesToExceptions'] : true;
  56315. $arguments['convertWarningsToExceptions'] = isset($arguments['convertWarningsToExceptions']) ? $arguments['convertWarningsToExceptions'] : true;
  56316. $arguments['excludeGroups'] = isset($arguments['excludeGroups']) ? $arguments['excludeGroups'] : array();
  56317. $arguments['groups'] = isset($arguments['groups']) ? $arguments['groups'] : array();
  56318. $arguments['logIncompleteSkipped'] = isset($arguments['logIncompleteSkipped']) ? $arguments['logIncompleteSkipped'] : false;
  56319. $arguments['processIsolation'] = isset($arguments['processIsolation']) ? $arguments['processIsolation'] : false;
  56320. $arguments['repeat'] = isset($arguments['repeat']) ? $arguments['repeat'] : false;
  56321. $arguments['reportHighLowerBound'] = isset($arguments['reportHighLowerBound']) ? $arguments['reportHighLowerBound'] : 90;
  56322. $arguments['reportLowUpperBound'] = isset($arguments['reportLowUpperBound']) ? $arguments['reportLowUpperBound'] : 50;
  56323. $arguments['stopOnError'] = isset($arguments['stopOnError']) ? $arguments['stopOnError'] : false;
  56324. $arguments['stopOnFailure'] = isset($arguments['stopOnFailure']) ? $arguments['stopOnFailure'] : false;
  56325. $arguments['stopOnIncomplete'] = isset($arguments['stopOnIncomplete']) ? $arguments['stopOnIncomplete'] : false;
  56326. $arguments['stopOnRisky'] = isset($arguments['stopOnRisky']) ? $arguments['stopOnRisky'] : false;
  56327. $arguments['stopOnSkipped'] = isset($arguments['stopOnSkipped']) ? $arguments['stopOnSkipped'] : false;
  56328. $arguments['timeoutForSmallTests'] = isset($arguments['timeoutForSmallTests']) ? $arguments['timeoutForSmallTests'] : 1;
  56329. $arguments['timeoutForMediumTests'] = isset($arguments['timeoutForMediumTests']) ? $arguments['timeoutForMediumTests'] : 10;
  56330. $arguments['timeoutForLargeTests'] = isset($arguments['timeoutForLargeTests']) ? $arguments['timeoutForLargeTests'] : 60;
  56331. $arguments['reportUselessTests'] = isset($arguments['reportUselessTests']) ? $arguments['reportUselessTests'] : false;
  56332. $arguments['strictCoverage'] = isset($arguments['strictCoverage']) ? $arguments['strictCoverage'] : false;
  56333. $arguments['disallowTestOutput'] = isset($arguments['disallowTestOutput']) ? $arguments['disallowTestOutput'] : false;
  56334. $arguments['enforceTimeLimit'] = isset($arguments['enforceTimeLimit']) ? $arguments['enforceTimeLimit'] : false;
  56335. $arguments['disallowTodoAnnotatedTests'] = isset($arguments['disallowTodoAnnotatedTests']) ? $arguments['disallowTodoAnnotatedTests'] : false;
  56336. $arguments['verbose'] = isset($arguments['verbose']) ? $arguments['verbose'] : false;
  56337. }
  56338. /**
  56339. * @param $extension
  56340. * @param string $message
  56341. * @since Method available since Release 4.0.0
  56342. */
  56343. private function showExtensionNotLoadedMessage($extension, $message = '')
  56344. {
  56345. if (isset($this->missingExtensions[$extension])) {
  56346. return;
  56347. }
  56348. if (!empty($message)) {
  56349. $message = ' ' . $message;
  56350. }
  56351. $this->showMessage(
  56352. 'The ' . $extension . ' extension is not loaded.' . $message . "\n"
  56353. );
  56354. $this->missingExtensions[$extension] = true;
  56355. }
  56356. /**
  56357. * Shows a message.
  56358. *
  56359. * @param string $message
  56360. * @param boolean $exit
  56361. * @since Method available since Release 4.0.0
  56362. */
  56363. private function showMessage($message, $exit = false)
  56364. {
  56365. $this->write($message . "\n");
  56366. if ($exit) {
  56367. exit(self::EXCEPTION_EXIT);
  56368. }
  56369. }
  56370. /**
  56371. * @return PHP_CodeCoverage_Filter
  56372. */
  56373. private function getCodeCoverageFilter()
  56374. {
  56375. $filter = new PHP_CodeCoverage_Filter;
  56376. if (defined('__PHPUNIT_PHAR__')) {
  56377. $filter->addFileToBlacklist(__PHPUNIT_PHAR__);
  56378. }
  56379. $blacklist = new PHPUnit_Util_Blacklist;
  56380. foreach ($blacklist->getBlacklistedDirectories() as $directory) {
  56381. $filter->addDirectoryToBlacklist($directory);
  56382. }
  56383. return $filter;
  56384. }
  56385. }
  56386. <?php
  56387. /*
  56388. * This file is part of PHPUnit.
  56389. *
  56390. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56391. *
  56392. * For the full copyright and license information, please view the LICENSE
  56393. * file that was distributed with this source code.
  56394. */
  56395. use SebastianBergmann\Environment\Console;
  56396. /**
  56397. * Prints the result of a TextUI TestRunner run.
  56398. *
  56399. * @package PHPUnit
  56400. * @subpackage TextUI
  56401. * @author Sebastian Bergmann <sebastian@phpunit.de>
  56402. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  56403. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  56404. * @link http://www.phpunit.de/
  56405. * @since Class available since Release 2.0.0
  56406. */
  56407. class PHPUnit_TextUI_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
  56408. {
  56409. const EVENT_TEST_START = 0;
  56410. const EVENT_TEST_END = 1;
  56411. const EVENT_TESTSUITE_START = 2;
  56412. const EVENT_TESTSUITE_END = 3;
  56413. const COLOR_NEVER = 'never';
  56414. const COLOR_AUTO = 'auto';
  56415. const COLOR_ALWAYS = 'always';
  56416. const COLOR_DEFAULT = self::COLOR_NEVER;
  56417. /**
  56418. * @var array
  56419. */
  56420. private static $ansiCodes = array(
  56421. 'bold' => 1,
  56422. 'fg-black' => 30,
  56423. 'fg-red' => 31,
  56424. 'fg-green' => 32,
  56425. 'fg-yellow' => 33,
  56426. 'fg-blue' => 34,
  56427. 'fg-magenta' => 35,
  56428. 'fg-cyan' => 36,
  56429. 'fg-white' => 37,
  56430. 'bg-black' => 40,
  56431. 'bg-red' => 41,
  56432. 'bg-green' => 42,
  56433. 'bg-yellow' => 43,
  56434. 'bg-blue' => 44,
  56435. 'bg-magenta' => 45,
  56436. 'bg-cyan' => 46,
  56437. 'bg-white' => 47
  56438. );
  56439. /**
  56440. * @var integer
  56441. */
  56442. protected $column = 0;
  56443. /**
  56444. * @var integer
  56445. */
  56446. protected $maxColumn;
  56447. /**
  56448. * @var boolean
  56449. */
  56450. protected $lastTestFailed = false;
  56451. /**
  56452. * @var integer
  56453. */
  56454. protected $numAssertions = 0;
  56455. /**
  56456. * @var integer
  56457. */
  56458. protected $numTests = -1;
  56459. /**
  56460. * @var integer
  56461. */
  56462. protected $numTestsRun = 0;
  56463. /**
  56464. * @var integer
  56465. */
  56466. protected $numTestsWidth;
  56467. /**
  56468. * @var boolean
  56469. */
  56470. protected $colors = false;
  56471. /**
  56472. * @var boolean
  56473. */
  56474. protected $debug = false;
  56475. /**
  56476. * @var boolean
  56477. */
  56478. protected $verbose = false;
  56479. /**
  56480. * @var integer
  56481. */
  56482. private $numberOfColumns;
  56483. /**
  56484. * Constructor.
  56485. *
  56486. * @param mixed $out
  56487. * @param boolean $verbose
  56488. * @param string $colors
  56489. * @param boolean $debug
  56490. * @param integer|string $numberOfColumns
  56491. * @throws PHPUnit_Framework_Exception
  56492. * @since Method available since Release 3.0.0
  56493. */
  56494. public function __construct($out = null, $verbose = false, $colors = self::COLOR_DEFAULT, $debug = false, $numberOfColumns = 80)
  56495. {
  56496. parent::__construct($out);
  56497. if (!is_bool($verbose)) {
  56498. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
  56499. }
  56500. $availableColors = array(self::COLOR_NEVER, self::COLOR_AUTO, self::COLOR_ALWAYS);
  56501. if (!in_array($colors, $availableColors)) {
  56502. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  56503. 3,
  56504. vsprintf('value from "%s", "%s" or "%s"', $availableColors)
  56505. );
  56506. }
  56507. if (!is_bool($debug)) {
  56508. throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean');
  56509. }
  56510. if (!is_int($numberOfColumns) && $numberOfColumns != 'max') {
  56511. throw PHPUnit_Util_InvalidArgumentHelper::factory(5, 'integer or "max"');
  56512. }
  56513. $console = new Console;
  56514. $maxNumberOfColumns = $console->getNumberOfColumns();
  56515. if ($numberOfColumns == 'max' || $numberOfColumns > $maxNumberOfColumns) {
  56516. $numberOfColumns = $maxNumberOfColumns;
  56517. }
  56518. $this->numberOfColumns = $numberOfColumns;
  56519. $this->verbose = $verbose;
  56520. $this->debug = $debug;
  56521. if ($colors === self::COLOR_AUTO && $console->hasColorSupport()) {
  56522. $this->colors = true;
  56523. } else {
  56524. $this->colors = (self::COLOR_ALWAYS === $colors);
  56525. }
  56526. }
  56527. /**
  56528. * @param PHPUnit_Framework_TestResult $result
  56529. */
  56530. public function printResult(PHPUnit_Framework_TestResult $result)
  56531. {
  56532. $this->printHeader();
  56533. $this->printErrors($result);
  56534. $printSeparator = $result->errorCount() > 0;
  56535. if ($printSeparator && $result->failureCount() > 0) {
  56536. $this->write("\n--\n\n");
  56537. }
  56538. $printSeparator = $printSeparator || $result->failureCount() > 0;
  56539. $this->printFailures($result);
  56540. if ($this->verbose) {
  56541. if ($printSeparator && $result->riskyCount() > 0) {
  56542. $this->write("\n--\n\n");
  56543. }
  56544. $printSeparator = $printSeparator ||
  56545. $result->riskyCount() > 0;
  56546. $this->printRisky($result);
  56547. if ($printSeparator && $result->notImplementedCount() > 0) {
  56548. $this->write("\n--\n\n");
  56549. }
  56550. $printSeparator = $printSeparator ||
  56551. $result->notImplementedCount() > 0;
  56552. $this->printIncompletes($result);
  56553. if ($printSeparator && $result->skippedCount() > 0) {
  56554. $this->write("\n--\n\n");
  56555. }
  56556. $this->printSkipped($result);
  56557. }
  56558. $this->printFooter($result);
  56559. }
  56560. /**
  56561. * @param array $defects
  56562. * @param string $type
  56563. */
  56564. protected function printDefects(array $defects, $type)
  56565. {
  56566. $count = count($defects);
  56567. if ($count == 0) {
  56568. return;
  56569. }
  56570. $this->write(
  56571. sprintf(
  56572. "There %s %d %s%s:\n",
  56573. ($count == 1) ? 'was' : 'were',
  56574. $count,
  56575. $type,
  56576. ($count == 1) ? '' : 's'
  56577. )
  56578. );
  56579. $i = 1;
  56580. foreach ($defects as $defect) {
  56581. $this->printDefect($defect, $i++);
  56582. }
  56583. }
  56584. /**
  56585. * @param PHPUnit_Framework_TestFailure $defect
  56586. * @param integer $count
  56587. */
  56588. protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count)
  56589. {
  56590. $this->printDefectHeader($defect, $count);
  56591. $this->printDefectTrace($defect);
  56592. }
  56593. /**
  56594. * @param PHPUnit_Framework_TestFailure $defect
  56595. * @param integer $count
  56596. */
  56597. protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count)
  56598. {
  56599. $this->write(
  56600. sprintf(
  56601. "\n%d) %s\n",
  56602. $count,
  56603. $defect->getTestName()
  56604. )
  56605. );
  56606. }
  56607. /**
  56608. * @param PHPUnit_Framework_TestFailure $defect
  56609. */
  56610. protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect)
  56611. {
  56612. $e = $defect->thrownException();
  56613. $this->write((string) $e);
  56614. while ($e = $e->getPrevious()) {
  56615. $this->write("\nCaused by\n" . $e);
  56616. }
  56617. }
  56618. /**
  56619. * @param PHPUnit_Framework_TestResult $result
  56620. */
  56621. protected function printErrors(PHPUnit_Framework_TestResult $result)
  56622. {
  56623. $this->printDefects($result->errors(), 'error');
  56624. }
  56625. /**
  56626. * @param PHPUnit_Framework_TestResult $result
  56627. */
  56628. protected function printFailures(PHPUnit_Framework_TestResult $result)
  56629. {
  56630. $this->printDefects($result->failures(), 'failure');
  56631. }
  56632. /**
  56633. * @param PHPUnit_Framework_TestResult $result
  56634. */
  56635. protected function printIncompletes(PHPUnit_Framework_TestResult $result)
  56636. {
  56637. $this->printDefects($result->notImplemented(), 'incomplete test');
  56638. }
  56639. /**
  56640. * @param PHPUnit_Framework_TestResult $result
  56641. * @since Method available since Release 4.0.0
  56642. */
  56643. protected function printRisky(PHPUnit_Framework_TestResult $result)
  56644. {
  56645. $this->printDefects($result->risky(), 'risky test');
  56646. }
  56647. /**
  56648. * @param PHPUnit_Framework_TestResult $result
  56649. * @since Method available since Release 3.0.0
  56650. */
  56651. protected function printSkipped(PHPUnit_Framework_TestResult $result)
  56652. {
  56653. $this->printDefects($result->skipped(), 'skipped test');
  56654. }
  56655. protected function printHeader()
  56656. {
  56657. $this->write("\n\n" . PHP_Timer::resourceUsage() . "\n\n");
  56658. }
  56659. /**
  56660. * @param PHPUnit_Framework_TestResult $result
  56661. */
  56662. protected function printFooter(PHPUnit_Framework_TestResult $result)
  56663. {
  56664. if (count($result) === 0) {
  56665. $this->writeWithColor(
  56666. 'fg-black, bg-yellow',
  56667. 'No tests executed!'
  56668. );
  56669. } elseif ($result->wasSuccessful() &&
  56670. $result->allHarmless() &&
  56671. $result->allCompletelyImplemented() &&
  56672. $result->noneSkipped()) {
  56673. $this->writeWithColor(
  56674. 'fg-black, bg-green',
  56675. sprintf(
  56676. 'OK (%d test%s, %d assertion%s)',
  56677. count($result),
  56678. (count($result) == 1) ? '' : 's',
  56679. $this->numAssertions,
  56680. ($this->numAssertions == 1) ? '' : 's'
  56681. )
  56682. );
  56683. } else {
  56684. if ($result->wasSuccessful()) {
  56685. $color = 'fg-black, bg-yellow';
  56686. if ($this->verbose) {
  56687. $this->write("\n");
  56688. }
  56689. $this->writeWithColor(
  56690. $color,
  56691. 'OK, but incomplete, skipped, or risky tests!'
  56692. );
  56693. } else {
  56694. $color = 'fg-white, bg-red';
  56695. $this->write("\n");
  56696. $this->writeWithColor($color, 'FAILURES!');
  56697. }
  56698. $this->writeCountString(count($result), 'Tests', $color, true);
  56699. $this->writeCountString($this->numAssertions, 'Assertions', $color, true);
  56700. $this->writeCountString($result->errorCount(), 'Errors', $color);
  56701. $this->writeCountString($result->failureCount(), 'Failures', $color);
  56702. $this->writeCountString($result->skippedCount(), 'Skipped', $color);
  56703. $this->writeCountString($result->notImplementedCount(), 'Incomplete', $color);
  56704. $this->writeCountString($result->riskyCount(), 'Risky', $color);
  56705. $this->writeWithColor($color, '.', true);
  56706. }
  56707. }
  56708. /**
  56709. */
  56710. public function printWaitPrompt()
  56711. {
  56712. $this->write("\n<RETURN> to continue\n");
  56713. }
  56714. /**
  56715. * An error occurred.
  56716. *
  56717. * @param PHPUnit_Framework_Test $test
  56718. * @param Exception $e
  56719. * @param float $time
  56720. */
  56721. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  56722. {
  56723. $this->writeProgressWithColor('fg-red, bold', 'E');
  56724. $this->lastTestFailed = true;
  56725. }
  56726. /**
  56727. * A failure occurred.
  56728. *
  56729. * @param PHPUnit_Framework_Test $test
  56730. * @param PHPUnit_Framework_AssertionFailedError $e
  56731. * @param float $time
  56732. */
  56733. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  56734. {
  56735. $this->writeProgressWithColor('bg-red, fg-white', 'F');
  56736. $this->lastTestFailed = true;
  56737. }
  56738. /**
  56739. * Incomplete test.
  56740. *
  56741. * @param PHPUnit_Framework_Test $test
  56742. * @param Exception $e
  56743. * @param float $time
  56744. */
  56745. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  56746. {
  56747. $this->writeProgressWithColor('fg-yellow, bold', 'I');
  56748. $this->lastTestFailed = true;
  56749. }
  56750. /**
  56751. * Risky test.
  56752. *
  56753. * @param PHPUnit_Framework_Test $test
  56754. * @param Exception $e
  56755. * @param float $time
  56756. * @since Method available since Release 4.0.0
  56757. */
  56758. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  56759. {
  56760. $this->writeProgressWithColor('fg-yellow, bold', 'R');
  56761. $this->lastTestFailed = true;
  56762. }
  56763. /**
  56764. * Skipped test.
  56765. *
  56766. * @param PHPUnit_Framework_Test $test
  56767. * @param Exception $e
  56768. * @param float $time
  56769. * @since Method available since Release 3.0.0
  56770. */
  56771. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  56772. {
  56773. $this->writeProgressWithColor('fg-cyan, bold', 'S');
  56774. $this->lastTestFailed = true;
  56775. }
  56776. /**
  56777. * A testsuite started.
  56778. *
  56779. * @param PHPUnit_Framework_TestSuite $suite
  56780. * @since Method available since Release 2.2.0
  56781. */
  56782. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  56783. {
  56784. if ($this->numTests == -1) {
  56785. $this->numTests = count($suite);
  56786. $this->numTestsWidth = strlen((string) $this->numTests);
  56787. $this->maxColumn = $this->numberOfColumns - strlen(' / (XXX%)') - (2 * $this->numTestsWidth);
  56788. }
  56789. }
  56790. /**
  56791. * A testsuite ended.
  56792. *
  56793. * @param PHPUnit_Framework_TestSuite $suite
  56794. * @since Method available since Release 2.2.0
  56795. */
  56796. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  56797. {
  56798. }
  56799. /**
  56800. * A test started.
  56801. *
  56802. * @param PHPUnit_Framework_Test $test
  56803. */
  56804. public function startTest(PHPUnit_Framework_Test $test)
  56805. {
  56806. if ($this->debug) {
  56807. $this->write(
  56808. sprintf(
  56809. "\nStarting test '%s'.\n",
  56810. PHPUnit_Util_Test::describe($test)
  56811. )
  56812. );
  56813. }
  56814. }
  56815. /**
  56816. * A test ended.
  56817. *
  56818. * @param PHPUnit_Framework_Test $test
  56819. * @param float $time
  56820. */
  56821. public function endTest(PHPUnit_Framework_Test $test, $time)
  56822. {
  56823. if (!$this->lastTestFailed) {
  56824. $this->writeProgress('.');
  56825. }
  56826. if ($test instanceof PHPUnit_Framework_TestCase) {
  56827. $this->numAssertions += $test->getNumAssertions();
  56828. } elseif ($test instanceof PHPUnit_Extensions_PhptTestCase) {
  56829. $this->numAssertions++;
  56830. }
  56831. $this->lastTestFailed = false;
  56832. if ($test instanceof PHPUnit_Framework_TestCase) {
  56833. if (!$test->hasExpectationOnOutput()) {
  56834. $this->write($test->getActualOutput());
  56835. }
  56836. }
  56837. }
  56838. /**
  56839. * @param string $progress
  56840. */
  56841. protected function writeProgress($progress)
  56842. {
  56843. $this->write($progress);
  56844. $this->column++;
  56845. $this->numTestsRun++;
  56846. if ($this->column == $this->maxColumn) {
  56847. $this->write(
  56848. sprintf(
  56849. ' %' . $this->numTestsWidth . 'd / %' .
  56850. $this->numTestsWidth . 'd (%3s%%)',
  56851. $this->numTestsRun,
  56852. $this->numTests,
  56853. floor(($this->numTestsRun / $this->numTests) * 100)
  56854. )
  56855. );
  56856. $this->writeNewLine();
  56857. }
  56858. }
  56859. protected function writeNewLine()
  56860. {
  56861. $this->column = 0;
  56862. $this->write("\n");
  56863. }
  56864. /**
  56865. * Formats a buffer with a specified ANSI color sequence if colors are
  56866. * enabled.
  56867. *
  56868. * @param string $color
  56869. * @param string $buffer
  56870. * @return string
  56871. * @since Method available since Release 4.0.0
  56872. */
  56873. protected function formatWithColor($color, $buffer)
  56874. {
  56875. if (!$this->colors) {
  56876. return $buffer;
  56877. }
  56878. $codes = array_map('trim', explode(',', $color));
  56879. $lines = explode("\n", $buffer);
  56880. $padding = max(array_map('strlen', $lines));
  56881. $styles = array();
  56882. foreach ($codes as $code) {
  56883. $styles[] = self::$ansiCodes[$code];
  56884. }
  56885. $style = sprintf("\x1b[%sm", implode(';', $styles));
  56886. $styledLines = array();
  56887. foreach ($lines as $line) {
  56888. $styledLines[] = $style . str_pad($line, $padding) . "\x1b[0m";
  56889. }
  56890. return implode("\n", $styledLines);
  56891. }
  56892. /**
  56893. * Writes a buffer out with a color sequence if colors are enabled.
  56894. *
  56895. * @param string $color
  56896. * @param string $buffer
  56897. * @param boolean $lf
  56898. * @since Method available since Release 4.0.0
  56899. */
  56900. protected function writeWithColor($color, $buffer, $lf = true)
  56901. {
  56902. $this->write($this->formatWithColor($color, $buffer));
  56903. if ($lf) {
  56904. $this->write("\n");
  56905. }
  56906. }
  56907. /**
  56908. * Writes progress with a color sequence if colors are enabled.
  56909. *
  56910. * @param string $color
  56911. * @param string $buffer
  56912. * @since Method available since Release 4.0.0
  56913. */
  56914. protected function writeProgressWithColor($color, $buffer)
  56915. {
  56916. $buffer = $this->formatWithColor($color, $buffer);
  56917. $this->writeProgress($buffer);
  56918. }
  56919. /**
  56920. * @param integer $count
  56921. * @param string $name
  56922. * @param string $color
  56923. * @param boolean $always
  56924. * @since Method available since Release 4.6.5
  56925. */
  56926. private function writeCountString($count, $name, $color, $always = false)
  56927. {
  56928. static $first = true;
  56929. if ($always || $count > 0) {
  56930. $this->writeWithColor(
  56931. $color,
  56932. sprintf(
  56933. '%s%s: %d',
  56934. !$first ? ', ' : '',
  56935. $name,
  56936. $count
  56937. ),
  56938. false
  56939. );
  56940. $first = false;
  56941. }
  56942. }
  56943. }
  56944. <?php
  56945. /*
  56946. * This file is part of PHPUnit.
  56947. *
  56948. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56949. *
  56950. * For the full copyright and license information, please view the LICENSE
  56951. * file that was distributed with this source code.
  56952. */
  56953. if (!function_exists('trait_exists')) {
  56954. function trait_exists($traitname, $autoload = true)
  56955. {
  56956. return false;
  56957. }
  56958. }
  56959. /**
  56960. * Test helpers.
  56961. *
  56962. * @package PHPUnit
  56963. * @subpackage Util
  56964. * @author Sebastian Bergmann <sebastian@phpunit.de>
  56965. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  56966. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  56967. * @link http://www.phpunit.de/
  56968. * @since Class available since Release 3.0.0
  56969. */
  56970. class PHPUnit_Util_Test
  56971. {
  56972. const REGEX_DATA_PROVIDER = '/@dataProvider\s+([a-zA-Z0-9._:-\\\\x7f-\xff]+)/';
  56973. const REGEX_EXPECTED_EXCEPTION = '(@expectedException\s+([:.\w\\\\x7f-\xff]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m';
  56974. const REGEX_REQUIRES_VERSION = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<value>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
  56975. const REGEX_REQUIRES_OS = '/@requires\s+OS\s+(?P<value>.+?)[ \t]*\r?$/m';
  56976. const REGEX_REQUIRES = '/@requires\s+(?P<name>function|extension)\s+(?P<value>([^ ]+?))[ \t]*\r?$/m';
  56977. const UNKNOWN = -1;
  56978. const SMALL = 0;
  56979. const MEDIUM = 1;
  56980. const LARGE = 2;
  56981. private static $annotationCache = array();
  56982. private static $hookMethods = array();
  56983. /**
  56984. * @param PHPUnit_Framework_Test $test
  56985. * @param boolean $asString
  56986. * @return mixed
  56987. */
  56988. public static function describe(PHPUnit_Framework_Test $test, $asString = true)
  56989. {
  56990. if ($asString) {
  56991. if ($test instanceof PHPUnit_Framework_SelfDescribing) {
  56992. return $test->toString();
  56993. } else {
  56994. return get_class($test);
  56995. }
  56996. } else {
  56997. if ($test instanceof PHPUnit_Framework_TestCase) {
  56998. return array(
  56999. get_class($test), $test->getName()
  57000. );
  57001. } elseif ($test instanceof PHPUnit_Framework_SelfDescribing) {
  57002. return array('', $test->toString());
  57003. } else {
  57004. return array('', get_class($test));
  57005. }
  57006. }
  57007. }
  57008. /**
  57009. * @param string $className
  57010. * @param string $methodName
  57011. * @return array|bool
  57012. * @throws PHPUnit_Framework_CodeCoverageException
  57013. * @since Method available since Release 4.0.0
  57014. */
  57015. public static function getLinesToBeCovered($className, $methodName)
  57016. {
  57017. $annotations = self::parseTestMethodAnnotations(
  57018. $className,
  57019. $methodName
  57020. );
  57021. if (isset($annotations['class']['coversNothing']) || isset($annotations['method']['coversNothing'])) {
  57022. return false;
  57023. }
  57024. return self::getLinesToBeCoveredOrUsed($className, $methodName, 'covers');
  57025. }
  57026. /**
  57027. * Returns lines of code specified with the @uses annotation.
  57028. *
  57029. * @param string $className
  57030. * @param string $methodName
  57031. * @return array
  57032. * @since Method available since Release 4.0.0
  57033. */
  57034. public static function getLinesToBeUsed($className, $methodName)
  57035. {
  57036. return self::getLinesToBeCoveredOrUsed($className, $methodName, 'uses');
  57037. }
  57038. /**
  57039. * @param string $className
  57040. * @param string $methodName
  57041. * @param string $mode
  57042. * @return array
  57043. * @throws PHPUnit_Framework_CodeCoverageException
  57044. * @since Method available since Release 4.2.0
  57045. */
  57046. private static function getLinesToBeCoveredOrUsed($className, $methodName, $mode)
  57047. {
  57048. $annotations = self::parseTestMethodAnnotations(
  57049. $className,
  57050. $methodName
  57051. );
  57052. $classShortcut = null;
  57053. if (!empty($annotations['class'][$mode . 'DefaultClass'])) {
  57054. if (count($annotations['class'][$mode . 'DefaultClass']) > 1) {
  57055. throw new PHPUnit_Framework_CodeCoverageException(
  57056. sprintf(
  57057. 'More than one @%sClass annotation in class or interface "%s".',
  57058. $mode,
  57059. $className
  57060. )
  57061. );
  57062. }
  57063. $classShortcut = $annotations['class'][$mode . 'DefaultClass'][0];
  57064. }
  57065. $list = array();
  57066. if (isset($annotations['class'][$mode])) {
  57067. $list = $annotations['class'][$mode];
  57068. }
  57069. if (isset($annotations['method'][$mode])) {
  57070. $list = array_merge($list, $annotations['method'][$mode]);
  57071. }
  57072. $codeList = array();
  57073. foreach (array_unique($list) as $element) {
  57074. if ($classShortcut && strncmp($element, '::', 2) === 0) {
  57075. $element = $classShortcut . $element;
  57076. }
  57077. $element = preg_replace('/[\s()]+$/', '', $element);
  57078. $codeList = array_merge(
  57079. $codeList,
  57080. self::resolveElementToReflectionObjects($element)
  57081. );
  57082. }
  57083. return self::resolveReflectionObjectsToLines($codeList);
  57084. }
  57085. /**
  57086. * Returns the requirements for a test.
  57087. *
  57088. * @param string $className
  57089. * @param string $methodName
  57090. * @return array
  57091. * @since Method available since Release 3.6.0
  57092. */
  57093. public static function getRequirements($className, $methodName)
  57094. {
  57095. $reflector = new ReflectionClass($className);
  57096. $docComment = $reflector->getDocComment();
  57097. $reflector = new ReflectionMethod($className, $methodName);
  57098. $docComment .= "\n" . $reflector->getDocComment();
  57099. $requires = array();
  57100. if ($count = preg_match_all(self::REGEX_REQUIRES_OS, $docComment, $matches)) {
  57101. $requires['OS'] = sprintf(
  57102. '/%s/i',
  57103. addcslashes($matches['value'][$count - 1], '/')
  57104. );
  57105. }
  57106. if ($count = preg_match_all(self::REGEX_REQUIRES_VERSION, $docComment, $matches)) {
  57107. for ($i = 0; $i < $count; $i++) {
  57108. $requires[$matches['name'][$i]] = $matches['value'][$i];
  57109. }
  57110. }
  57111. // https://bugs.php.net/bug.php?id=63055
  57112. $matches = array();
  57113. if ($count = preg_match_all(self::REGEX_REQUIRES, $docComment, $matches)) {
  57114. for ($i = 0; $i < $count; $i++) {
  57115. $name = $matches['name'][$i] . 's';
  57116. if (!isset($requires[$name])) {
  57117. $requires[$name] = array();
  57118. }
  57119. $requires[$name][] = $matches['value'][$i];
  57120. }
  57121. }
  57122. return $requires;
  57123. }
  57124. /**
  57125. * Returns the missing requirements for a test.
  57126. *
  57127. * @param string $className
  57128. * @param string $methodName
  57129. * @return array
  57130. * @since Method available since Release 4.3.0
  57131. */
  57132. public static function getMissingRequirements($className, $methodName)
  57133. {
  57134. $required = static::getRequirements($className, $methodName);
  57135. $missing = array();
  57136. if (!empty($required['PHP']) && version_compare(PHP_VERSION, $required['PHP'], '<')) {
  57137. $missing[] = sprintf('PHP %s (or later) is required.', $required['PHP']);
  57138. }
  57139. if (!empty($required['PHPUnit'])) {
  57140. $phpunitVersion = PHPUnit_Runner_Version::id();
  57141. if (version_compare($phpunitVersion, $required['PHPUnit'], '<')) {
  57142. $missing[] = sprintf('PHPUnit %s (or later) is required.', $required['PHPUnit']);
  57143. }
  57144. }
  57145. if (!empty($required['OS']) && !preg_match($required['OS'], PHP_OS)) {
  57146. $missing[] = sprintf('Operating system matching %s is required.', $required['OS']);
  57147. }
  57148. if (!empty($required['functions'])) {
  57149. foreach ($required['functions'] as $function) {
  57150. $pieces = explode('::', $function);
  57151. if (2 === count($pieces) && method_exists($pieces[0], $pieces[1])) {
  57152. continue;
  57153. }
  57154. if (function_exists($function)) {
  57155. continue;
  57156. }
  57157. $missing[] = sprintf('Function %s is required.', $function);
  57158. }
  57159. }
  57160. if (!empty($required['extensions'])) {
  57161. foreach ($required['extensions'] as $extension) {
  57162. if (!extension_loaded($extension)) {
  57163. $missing[] = sprintf('Extension %s is required.', $extension);
  57164. }
  57165. }
  57166. }
  57167. return $missing;
  57168. }
  57169. /**
  57170. * Returns the expected exception for a test.
  57171. *
  57172. * @param string $className
  57173. * @param string $methodName
  57174. * @return array
  57175. * @since Method available since Release 3.3.6
  57176. */
  57177. public static function getExpectedException($className, $methodName)
  57178. {
  57179. $reflector = new ReflectionMethod($className, $methodName);
  57180. $docComment = $reflector->getDocComment();
  57181. $docComment = substr($docComment, 3, -2);
  57182. if (preg_match(self::REGEX_EXPECTED_EXCEPTION, $docComment, $matches)) {
  57183. $annotations = self::parseTestMethodAnnotations(
  57184. $className,
  57185. $methodName
  57186. );
  57187. $class = $matches[1];
  57188. $code = null;
  57189. $message = '';
  57190. $messageRegExp = '';
  57191. if (isset($matches[2])) {
  57192. $message = trim($matches[2]);
  57193. } elseif (isset($annotations['method']['expectedExceptionMessage'])) {
  57194. $message = self::parseAnnotationContent(
  57195. $annotations['method']['expectedExceptionMessage'][0]
  57196. );
  57197. }
  57198. if (isset($annotations['method']['expectedExceptionMessageRegExp'])) {
  57199. $messageRegExp = self::parseAnnotationContent(
  57200. $annotations['method']['expectedExceptionMessageRegExp'][0]
  57201. );
  57202. }
  57203. if (isset($matches[3])) {
  57204. $code = $matches[3];
  57205. } elseif (isset($annotations['method']['expectedExceptionCode'])) {
  57206. $code = self::parseAnnotationContent(
  57207. $annotations['method']['expectedExceptionCode'][0]
  57208. );
  57209. }
  57210. if (is_numeric($code)) {
  57211. $code = (int) $code;
  57212. } elseif (is_string($code) && defined($code)) {
  57213. $code = (int) constant($code);
  57214. }
  57215. return array(
  57216. 'class' => $class, 'code' => $code, 'message' => $message, 'message_regex' => $messageRegExp
  57217. );
  57218. }
  57219. return false;
  57220. }
  57221. /**
  57222. * Parse annotation content to use constant/class constant values
  57223. *
  57224. * Constants are specified using a starting '@'. For example: @ClassName::CONST_NAME
  57225. *
  57226. * If the constant is not found the string is used as is to ensure maximum BC.
  57227. *
  57228. * @param string $message
  57229. * @return string
  57230. */
  57231. private static function parseAnnotationContent($message)
  57232. {
  57233. if (strpos($message, '::') !== false && count(explode('::', $message) == 2)) {
  57234. if (defined($message)) {
  57235. $message = constant($message);
  57236. }
  57237. }
  57238. return $message;
  57239. }
  57240. /**
  57241. * Returns the provided data for a method.
  57242. *
  57243. * @param string $className
  57244. * @param string $methodName
  57245. * @return array|Iterator when a data provider is specified and exists
  57246. * false when a data provider is specified but does not exist
  57247. * null when no data provider is specified
  57248. * @throws PHPUnit_Framework_Exception
  57249. * @since Method available since Release 3.2.0
  57250. */
  57251. public static function getProvidedData($className, $methodName)
  57252. {
  57253. $reflector = new ReflectionMethod($className, $methodName);
  57254. $docComment = $reflector->getDocComment();
  57255. $data = null;
  57256. if (preg_match(self::REGEX_DATA_PROVIDER, $docComment, $matches)) {
  57257. $dataProviderMethodNameNamespace = explode('\\', $matches[1]);
  57258. $leaf = explode('::', array_pop($dataProviderMethodNameNamespace));
  57259. $dataProviderMethodName = array_pop($leaf);
  57260. if (!empty($dataProviderMethodNameNamespace)) {
  57261. $dataProviderMethodNameNamespace = implode('\\', $dataProviderMethodNameNamespace) . '\\';
  57262. } else {
  57263. $dataProviderMethodNameNamespace = '';
  57264. }
  57265. if (!empty($leaf)) {
  57266. $dataProviderClassName = $dataProviderMethodNameNamespace . array_pop($leaf);
  57267. } else {
  57268. $dataProviderClassName = $className;
  57269. }
  57270. $dataProviderClass = new ReflectionClass($dataProviderClassName);
  57271. $dataProviderMethod = $dataProviderClass->getMethod(
  57272. $dataProviderMethodName
  57273. );
  57274. if ($dataProviderMethod->isStatic()) {
  57275. $object = null;
  57276. } else {
  57277. $object = $dataProviderClass->newInstance();
  57278. }
  57279. if ($dataProviderMethod->getNumberOfParameters() == 0) {
  57280. $data = $dataProviderMethod->invoke($object);
  57281. } else {
  57282. $data = $dataProviderMethod->invoke($object, $methodName);
  57283. }
  57284. }
  57285. if ($data !== null) {
  57286. if (is_object($data)) {
  57287. $data = iterator_to_array($data);
  57288. }
  57289. foreach ($data as $key => $value) {
  57290. if (!is_array($value)) {
  57291. throw new PHPUnit_Framework_Exception(
  57292. sprintf(
  57293. 'Data set %s is invalid.',
  57294. is_int($key) ? '#' . $key : '"' . $key . '"'
  57295. )
  57296. );
  57297. }
  57298. }
  57299. }
  57300. return $data;
  57301. }
  57302. /**
  57303. * @param string $className
  57304. * @param string $methodName
  57305. * @return array
  57306. * @throws ReflectionException
  57307. * @since Method available since Release 3.4.0
  57308. */
  57309. public static function parseTestMethodAnnotations($className, $methodName = '')
  57310. {
  57311. if (!isset(self::$annotationCache[$className])) {
  57312. $class = new ReflectionClass($className);
  57313. self::$annotationCache[$className] = self::parseAnnotations($class->getDocComment());
  57314. }
  57315. if (!empty($methodName) && !isset(self::$annotationCache[$className . '::' . $methodName])) {
  57316. try {
  57317. $method = new ReflectionMethod($className, $methodName);
  57318. $annotations = self::parseAnnotations($method->getDocComment());
  57319. } catch (ReflectionException $e) {
  57320. $annotations = array();
  57321. }
  57322. self::$annotationCache[$className . '::' . $methodName] = $annotations;
  57323. }
  57324. return array(
  57325. 'class' => self::$annotationCache[$className],
  57326. 'method' => !empty($methodName) ? self::$annotationCache[$className . '::' . $methodName] : array()
  57327. );
  57328. }
  57329. /**
  57330. * @param string $docblock
  57331. * @return array
  57332. * @since Method available since Release 3.4.0
  57333. */
  57334. private static function parseAnnotations($docblock)
  57335. {
  57336. $annotations = array();
  57337. // Strip away the docblock header and footer to ease parsing of one line annotations
  57338. $docblock = substr($docblock, 3, -2);
  57339. if (preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m', $docblock, $matches)) {
  57340. $numMatches = count($matches[0]);
  57341. for ($i = 0; $i < $numMatches; ++$i) {
  57342. $annotations[$matches['name'][$i]][] = $matches['value'][$i];
  57343. }
  57344. }
  57345. return $annotations;
  57346. }
  57347. /**
  57348. * Returns the backup settings for a test.
  57349. *
  57350. * @param string $className
  57351. * @param string $methodName
  57352. * @return array
  57353. * @since Method available since Release 3.4.0
  57354. */
  57355. public static function getBackupSettings($className, $methodName)
  57356. {
  57357. return array(
  57358. 'backupGlobals' => self::getBooleanAnnotationSetting(
  57359. $className,
  57360. $methodName,
  57361. 'backupGlobals'
  57362. ),
  57363. 'backupStaticAttributes' => self::getBooleanAnnotationSetting(
  57364. $className,
  57365. $methodName,
  57366. 'backupStaticAttributes'
  57367. )
  57368. );
  57369. }
  57370. /**
  57371. * Returns the dependencies for a test class or method.
  57372. *
  57373. * @param string $className
  57374. * @param string $methodName
  57375. * @return array
  57376. * @since Method available since Release 3.4.0
  57377. */
  57378. public static function getDependencies($className, $methodName)
  57379. {
  57380. $annotations = self::parseTestMethodAnnotations(
  57381. $className,
  57382. $methodName
  57383. );
  57384. $dependencies = array();
  57385. if (isset($annotations['class']['depends'])) {
  57386. $dependencies = $annotations['class']['depends'];
  57387. }
  57388. if (isset($annotations['method']['depends'])) {
  57389. $dependencies = array_merge(
  57390. $dependencies,
  57391. $annotations['method']['depends']
  57392. );
  57393. }
  57394. return array_unique($dependencies);
  57395. }
  57396. /**
  57397. * Returns the error handler settings for a test.
  57398. *
  57399. * @param string $className
  57400. * @param string $methodName
  57401. * @return boolean
  57402. * @since Method available since Release 3.4.0
  57403. */
  57404. public static function getErrorHandlerSettings($className, $methodName)
  57405. {
  57406. return self::getBooleanAnnotationSetting(
  57407. $className,
  57408. $methodName,
  57409. 'errorHandler'
  57410. );
  57411. }
  57412. /**
  57413. * Returns the groups for a test class or method.
  57414. *
  57415. * @param string $className
  57416. * @param string $methodName
  57417. * @return array
  57418. * @since Method available since Release 3.2.0
  57419. */
  57420. public static function getGroups($className, $methodName = '')
  57421. {
  57422. $annotations = self::parseTestMethodAnnotations(
  57423. $className,
  57424. $methodName
  57425. );
  57426. $groups = array();
  57427. if (isset($annotations['method']['author'])) {
  57428. $groups = $annotations['method']['author'];
  57429. } elseif (isset($annotations['class']['author'])) {
  57430. $groups = $annotations['class']['author'];
  57431. }
  57432. if (isset($annotations['class']['group'])) {
  57433. $groups = array_merge($groups, $annotations['class']['group']);
  57434. }
  57435. if (isset($annotations['method']['group'])) {
  57436. $groups = array_merge($groups, $annotations['method']['group']);
  57437. }
  57438. if (isset($annotations['class']['ticket'])) {
  57439. $groups = array_merge($groups, $annotations['class']['ticket']);
  57440. }
  57441. if (isset($annotations['method']['ticket'])) {
  57442. $groups = array_merge($groups, $annotations['method']['ticket']);
  57443. }
  57444. foreach (array('small', 'medium', 'large') as $size) {
  57445. if (isset($annotations['method'][$size])) {
  57446. $groups[] = $size;
  57447. } elseif (isset($annotations['class'][$size])) {
  57448. $groups[] = $size;
  57449. }
  57450. }
  57451. return array_unique($groups);
  57452. }
  57453. /**
  57454. * Returns the size of the test.
  57455. *
  57456. * @param string $className
  57457. * @param string $methodName
  57458. * @return integer
  57459. * @since Method available since Release 3.6.0
  57460. */
  57461. public static function getSize($className, $methodName)
  57462. {
  57463. $groups = array_flip(self::getGroups($className, $methodName));
  57464. $size = self::UNKNOWN;
  57465. $class = new ReflectionClass($className);
  57466. if (isset($groups['large']) ||
  57467. (class_exists('PHPUnit_Extensions_Database_TestCase', false) &&
  57468. $class->isSubclassOf('PHPUnit_Extensions_Database_TestCase')) ||
  57469. (class_exists('PHPUnit_Extensions_SeleniumTestCase', false) &&
  57470. $class->isSubclassOf('PHPUnit_Extensions_SeleniumTestCase'))) {
  57471. $size = self::LARGE;
  57472. } elseif (isset($groups['medium'])) {
  57473. $size = self::MEDIUM;
  57474. } elseif (isset($groups['small'])) {
  57475. $size = self::SMALL;
  57476. }
  57477. return $size;
  57478. }
  57479. /**
  57480. * Returns the tickets for a test class or method.
  57481. *
  57482. * @param string $className
  57483. * @param string $methodName
  57484. * @return array
  57485. * @since Method available since Release 3.4.0
  57486. */
  57487. public static function getTickets($className, $methodName)
  57488. {
  57489. $annotations = self::parseTestMethodAnnotations(
  57490. $className,
  57491. $methodName
  57492. );
  57493. $tickets = array();
  57494. if (isset($annotations['class']['ticket'])) {
  57495. $tickets = $annotations['class']['ticket'];
  57496. }
  57497. if (isset($annotations['method']['ticket'])) {
  57498. $tickets = array_merge($tickets, $annotations['method']['ticket']);
  57499. }
  57500. return array_unique($tickets);
  57501. }
  57502. /**
  57503. * Returns the process isolation settings for a test.
  57504. *
  57505. * @param string $className
  57506. * @param string $methodName
  57507. * @return boolean
  57508. * @since Method available since Release 3.4.1
  57509. */
  57510. public static function getProcessIsolationSettings($className, $methodName)
  57511. {
  57512. $annotations = self::parseTestMethodAnnotations(
  57513. $className,
  57514. $methodName
  57515. );
  57516. if (isset($annotations['class']['runTestsInSeparateProcesses']) ||
  57517. isset($annotations['method']['runInSeparateProcess'])) {
  57518. return true;
  57519. } else {
  57520. return false;
  57521. }
  57522. }
  57523. /**
  57524. * Returns the preserve global state settings for a test.
  57525. *
  57526. * @param string $className
  57527. * @param string $methodName
  57528. * @return boolean
  57529. * @since Method available since Release 3.4.0
  57530. */
  57531. public static function getPreserveGlobalStateSettings($className, $methodName)
  57532. {
  57533. return self::getBooleanAnnotationSetting(
  57534. $className,
  57535. $methodName,
  57536. 'preserveGlobalState'
  57537. );
  57538. }
  57539. /**
  57540. * @param string $className
  57541. * @return array
  57542. * @since Method available since Release 4.0.8
  57543. */
  57544. public static function getHookMethods($className)
  57545. {
  57546. if (!class_exists($className, false)) {
  57547. return self::emptyHookMethodsArray();
  57548. }
  57549. if (!isset(self::$hookMethods[$className])) {
  57550. self::$hookMethods[$className] = self::emptyHookMethodsArray();
  57551. try {
  57552. $class = new ReflectionClass($className);
  57553. foreach ($class->getMethods() as $method) {
  57554. if ($method->getDeclaringClass()->getName() != $className) {
  57555. continue;
  57556. }
  57557. if (self::isBeforeClassMethod($method)) {
  57558. self::$hookMethods[$className]['beforeClass'][] = $method->getName();
  57559. }
  57560. if (self::isBeforeMethod($method)) {
  57561. self::$hookMethods[$className]['before'][] = $method->getName();
  57562. }
  57563. if (self::isAfterMethod($method)) {
  57564. self::$hookMethods[$className]['after'][] = $method->getName();
  57565. }
  57566. if (self::isAfterClassMethod($method)) {
  57567. self::$hookMethods[$className]['afterClass'][] = $method->getName();
  57568. }
  57569. }
  57570. } catch (ReflectionException $e) {
  57571. }
  57572. }
  57573. return self::$hookMethods[$className];
  57574. }
  57575. /**
  57576. * @return array
  57577. * @since Method available since Release 4.0.9
  57578. */
  57579. private static function emptyHookMethodsArray()
  57580. {
  57581. return array(
  57582. 'beforeClass' => array('setUpBeforeClass'),
  57583. 'before' => array('setUp'),
  57584. 'after' => array('tearDown'),
  57585. 'afterClass' => array('tearDownAfterClass')
  57586. );
  57587. }
  57588. /**
  57589. * @param string $className
  57590. * @param string $methodName
  57591. * @param string $settingName
  57592. * @return boolean
  57593. * @since Method available since Release 3.4.0
  57594. */
  57595. private static function getBooleanAnnotationSetting($className, $methodName, $settingName)
  57596. {
  57597. $annotations = self::parseTestMethodAnnotations(
  57598. $className,
  57599. $methodName
  57600. );
  57601. $result = null;
  57602. if (isset($annotations['class'][$settingName])) {
  57603. if ($annotations['class'][$settingName][0] == 'enabled') {
  57604. $result = true;
  57605. } elseif ($annotations['class'][$settingName][0] == 'disabled') {
  57606. $result = false;
  57607. }
  57608. }
  57609. if (isset($annotations['method'][$settingName])) {
  57610. if ($annotations['method'][$settingName][0] == 'enabled') {
  57611. $result = true;
  57612. } elseif ($annotations['method'][$settingName][0] == 'disabled') {
  57613. $result = false;
  57614. }
  57615. }
  57616. return $result;
  57617. }
  57618. /**
  57619. * @param string $element
  57620. * @return array
  57621. * @throws PHPUnit_Framework_InvalidCoversTargetException
  57622. * @since Method available since Release 4.0.0
  57623. */
  57624. private static function resolveElementToReflectionObjects($element)
  57625. {
  57626. $codeToCoverList = array();
  57627. if (strpos($element, '::') !== false) {
  57628. list($className, $methodName) = explode('::', $element);
  57629. if (isset($methodName[0]) && $methodName[0] == '<') {
  57630. $classes = array($className);
  57631. foreach ($classes as $className) {
  57632. if (!class_exists($className) &&
  57633. !interface_exists($className)) {
  57634. throw new PHPUnit_Framework_InvalidCoversTargetException(
  57635. sprintf(
  57636. 'Trying to @cover or @use not existing class or ' .
  57637. 'interface "%s".',
  57638. $className
  57639. )
  57640. );
  57641. }
  57642. $class = new ReflectionClass($className);
  57643. $methods = $class->getMethods();
  57644. $inverse = isset($methodName[1]) && $methodName[1] == '!';
  57645. if (strpos($methodName, 'protected')) {
  57646. $visibility = 'isProtected';
  57647. } elseif (strpos($methodName, 'private')) {
  57648. $visibility = 'isPrivate';
  57649. } elseif (strpos($methodName, 'public')) {
  57650. $visibility = 'isPublic';
  57651. }
  57652. foreach ($methods as $method) {
  57653. if ($inverse && !$method->$visibility()) {
  57654. $codeToCoverList[] = $method;
  57655. } elseif (!$inverse && $method->$visibility()) {
  57656. $codeToCoverList[] = $method;
  57657. }
  57658. }
  57659. }
  57660. } else {
  57661. $classes = array($className);
  57662. foreach ($classes as $className) {
  57663. if ($className == '' && function_exists($methodName)) {
  57664. $codeToCoverList[] = new ReflectionFunction(
  57665. $methodName
  57666. );
  57667. } else {
  57668. if (!((class_exists($className) ||
  57669. interface_exists($className) ||
  57670. trait_exists($className)) &&
  57671. method_exists($className, $methodName))) {
  57672. throw new PHPUnit_Framework_InvalidCoversTargetException(
  57673. sprintf(
  57674. 'Trying to @cover or @use not existing method "%s::%s".',
  57675. $className,
  57676. $methodName
  57677. )
  57678. );
  57679. }
  57680. $codeToCoverList[] = new ReflectionMethod(
  57681. $className,
  57682. $methodName
  57683. );
  57684. }
  57685. }
  57686. }
  57687. } else {
  57688. $extended = false;
  57689. if (strpos($element, '<extended>') !== false) {
  57690. $element = str_replace('<extended>', '', $element);
  57691. $extended = true;
  57692. }
  57693. $classes = array($element);
  57694. if ($extended) {
  57695. $classes = array_merge(
  57696. $classes,
  57697. class_implements($element),
  57698. class_parents($element)
  57699. );
  57700. }
  57701. foreach ($classes as $className) {
  57702. if (!class_exists($className) &&
  57703. !interface_exists($className) &&
  57704. !trait_exists($className)) {
  57705. throw new PHPUnit_Framework_InvalidCoversTargetException(
  57706. sprintf(
  57707. 'Trying to @cover or @use not existing class or ' .
  57708. 'interface "%s".',
  57709. $className
  57710. )
  57711. );
  57712. }
  57713. $codeToCoverList[] = new ReflectionClass($className);
  57714. }
  57715. }
  57716. return $codeToCoverList;
  57717. }
  57718. /**
  57719. * @param array $reflectors
  57720. * @return array
  57721. */
  57722. private static function resolveReflectionObjectsToLines(array $reflectors)
  57723. {
  57724. $result = array();
  57725. foreach ($reflectors as $reflector) {
  57726. $filename = $reflector->getFileName();
  57727. if (!isset($result[$filename])) {
  57728. $result[$filename] = array();
  57729. }
  57730. $result[$filename] = array_unique(
  57731. array_merge(
  57732. $result[$filename],
  57733. range($reflector->getStartLine(), $reflector->getEndLine())
  57734. )
  57735. );
  57736. }
  57737. return $result;
  57738. }
  57739. /**
  57740. * @param ReflectionMethod $method
  57741. * @return boolean
  57742. * @since Method available since Release 4.0.8
  57743. */
  57744. private static function isBeforeClassMethod(ReflectionMethod $method)
  57745. {
  57746. return $method->isStatic() && strpos($method->getDocComment(), '@beforeClass') !== false;
  57747. }
  57748. /**
  57749. * @param ReflectionMethod $method
  57750. * @return boolean
  57751. * @since Method available since Release 4.0.8
  57752. */
  57753. private static function isBeforeMethod(ReflectionMethod $method)
  57754. {
  57755. return preg_match('/@before\b/', $method->getDocComment());
  57756. }
  57757. /**
  57758. * @param ReflectionMethod $method
  57759. * @return boolean
  57760. * @since Method available since Release 4.0.8
  57761. */
  57762. private static function isAfterClassMethod(ReflectionMethod $method)
  57763. {
  57764. return $method->isStatic() && strpos($method->getDocComment(), '@afterClass') !== false;
  57765. }
  57766. /**
  57767. * @param ReflectionMethod $method
  57768. * @return boolean
  57769. * @since Method available since Release 4.0.8
  57770. */
  57771. private static function isAfterMethod(ReflectionMethod $method)
  57772. {
  57773. return preg_match('/@after\b/', $method->getDocComment());
  57774. }
  57775. }
  57776. <?php
  57777. /*
  57778. * This file is part of PHPUnit.
  57779. *
  57780. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57781. *
  57782. * For the full copyright and license information, please view the LICENSE
  57783. * file that was distributed with this source code.
  57784. */
  57785. /**
  57786. * Filesystem helpers.
  57787. *
  57788. * @package PHPUnit
  57789. * @subpackage Util
  57790. * @author Sebastian Bergmann <sebastian@phpunit.de>
  57791. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  57792. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  57793. * @link http://www.phpunit.de/
  57794. * @since Class available since Release 3.0.0
  57795. */
  57796. class PHPUnit_Util_Filesystem
  57797. {
  57798. /**
  57799. * @var array
  57800. */
  57801. protected static $buffer = array();
  57802. /**
  57803. * Maps class names to source file names:
  57804. * - PEAR CS: Foo_Bar_Baz -> Foo/Bar/Baz.php
  57805. * - Namespace: Foo\Bar\Baz -> Foo/Bar/Baz.php
  57806. *
  57807. * @param string $className
  57808. * @return string
  57809. * @since Method available since Release 3.4.0
  57810. */
  57811. public static function classNameToFilename($className)
  57812. {
  57813. return str_replace(
  57814. array('_', '\\'),
  57815. DIRECTORY_SEPARATOR,
  57816. $className
  57817. ) . '.php';
  57818. }
  57819. }
  57820. <?php
  57821. /*
  57822. * This file is part of PHPUnit.
  57823. *
  57824. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57825. *
  57826. * For the full copyright and license information, please view the LICENSE
  57827. * file that was distributed with this source code.
  57828. */
  57829. /**
  57830. * Command-line options parsing class.
  57831. *
  57832. * @package PHPUnit
  57833. * @subpackage Util
  57834. * @author Andrei Zmievski <andrei@php.net>
  57835. * @author Sebastian Bergmann <sebastian@phpunit.de>
  57836. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  57837. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  57838. * @link http://www.phpunit.de/
  57839. * @since Class available since Release 3.0.0
  57840. */
  57841. class PHPUnit_Util_Getopt
  57842. {
  57843. public static function getopt(array $args, $short_options, $long_options = null)
  57844. {
  57845. if (empty($args)) {
  57846. return array(array(), array());
  57847. }
  57848. $opts = array();
  57849. $non_opts = array();
  57850. if ($long_options) {
  57851. sort($long_options);
  57852. }
  57853. if (isset($args[0][0]) && $args[0][0] != '-') {
  57854. array_shift($args);
  57855. }
  57856. reset($args);
  57857. array_map('trim', $args);
  57858. while (list($i, $arg) = each($args)) {
  57859. if ($arg == '') {
  57860. continue;
  57861. }
  57862. if ($arg == '--') {
  57863. $non_opts = array_merge($non_opts, array_slice($args, $i + 1));
  57864. break;
  57865. }
  57866. if ($arg[0] != '-' ||
  57867. (strlen($arg) > 1 && $arg[1] == '-' && !$long_options)) {
  57868. $non_opts = array_merge($non_opts, array_slice($args, $i));
  57869. break;
  57870. } elseif (strlen($arg) > 1 && $arg[1] == '-') {
  57871. self::parseLongOption(
  57872. substr($arg, 2),
  57873. $long_options,
  57874. $opts,
  57875. $args
  57876. );
  57877. } else {
  57878. self::parseShortOption(
  57879. substr($arg, 1),
  57880. $short_options,
  57881. $opts,
  57882. $args
  57883. );
  57884. }
  57885. }
  57886. return array($opts, $non_opts);
  57887. }
  57888. protected static function parseShortOption($arg, $short_options, &$opts, &$args)
  57889. {
  57890. $argLen = strlen($arg);
  57891. for ($i = 0; $i < $argLen; $i++) {
  57892. $opt = $arg[$i];
  57893. $opt_arg = null;
  57894. if (($spec = strstr($short_options, $opt)) === false ||
  57895. $arg[$i] == ':') {
  57896. throw new PHPUnit_Framework_Exception(
  57897. "unrecognized option -- $opt"
  57898. );
  57899. }
  57900. if (strlen($spec) > 1 && $spec[1] == ':') {
  57901. if (strlen($spec) > 2 && $spec[2] == ':') {
  57902. if ($i + 1 < $argLen) {
  57903. $opts[] = array($opt, substr($arg, $i + 1));
  57904. break;
  57905. }
  57906. } else {
  57907. if ($i + 1 < $argLen) {
  57908. $opts[] = array($opt, substr($arg, $i + 1));
  57909. break;
  57910. } elseif (list(, $opt_arg) = each($args)) {
  57911. } else {
  57912. throw new PHPUnit_Framework_Exception(
  57913. "option requires an argument -- $opt"
  57914. );
  57915. }
  57916. }
  57917. }
  57918. $opts[] = array($opt, $opt_arg);
  57919. }
  57920. }
  57921. protected static function parseLongOption($arg, $long_options, &$opts, &$args)
  57922. {
  57923. $count = count($long_options);
  57924. $list = explode('=', $arg);
  57925. $opt = $list[0];
  57926. $opt_arg = null;
  57927. if (count($list) > 1) {
  57928. $opt_arg = $list[1];
  57929. }
  57930. $opt_len = strlen($opt);
  57931. for ($i = 0; $i < $count; $i++) {
  57932. $long_opt = $long_options[$i];
  57933. $opt_start = substr($long_opt, 0, $opt_len);
  57934. if ($opt_start != $opt) {
  57935. continue;
  57936. }
  57937. $opt_rest = substr($long_opt, $opt_len);
  57938. if ($opt_rest != '' && $opt[0] != '=' && $i + 1 < $count &&
  57939. $opt == substr($long_options[$i+1], 0, $opt_len)) {
  57940. throw new PHPUnit_Framework_Exception(
  57941. "option --$opt is ambiguous"
  57942. );
  57943. }
  57944. if (substr($long_opt, -1) == '=') {
  57945. if (substr($long_opt, -2) != '==') {
  57946. if (!strlen($opt_arg) &&
  57947. !(list(, $opt_arg) = each($args))) {
  57948. throw new PHPUnit_Framework_Exception(
  57949. "option --$opt requires an argument"
  57950. );
  57951. }
  57952. }
  57953. } elseif ($opt_arg) {
  57954. throw new PHPUnit_Framework_Exception(
  57955. "option --$opt doesn't allow an argument"
  57956. );
  57957. }
  57958. $full_option = '--' . preg_replace('/={1,2}$/', '', $long_opt);
  57959. $opts[] = array($full_option, $opt_arg);
  57960. return;
  57961. }
  57962. throw new PHPUnit_Framework_Exception("unrecognized option --$opt");
  57963. }
  57964. }
  57965. <?php
  57966. /*
  57967. * This file is part of PHPUnit.
  57968. *
  57969. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57970. *
  57971. * For the full copyright and license information, please view the LICENSE
  57972. * file that was distributed with this source code.
  57973. */
  57974. // Workaround for http://bugs.php.net/bug.php?id=47987,
  57975. // see https://github.com/sebastianbergmann/phpunit/issues#issue/125 for details
  57976. // Use dirname(__DIR__) instead of using /../ because of https://github.com/facebook/hhvm/issues/5215
  57977. require_once dirname(__DIR__) . '/Framework/Error.php';
  57978. require_once dirname(__DIR__) . '/Framework/Error/Notice.php';
  57979. require_once dirname(__DIR__) . '/Framework/Error/Warning.php';
  57980. require_once dirname(__DIR__) . '/Framework/Error/Deprecated.php';
  57981. /**
  57982. * Error handler that converts PHP errors and warnings to exceptions.
  57983. *
  57984. * @package PHPUnit
  57985. * @subpackage Util
  57986. * @author Sebastian Bergmann <sebastian@phpunit.de>
  57987. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  57988. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  57989. * @link http://www.phpunit.de/
  57990. * @since Class available since Release 3.3.0
  57991. */
  57992. class PHPUnit_Util_ErrorHandler
  57993. {
  57994. protected static $errorStack = array();
  57995. /**
  57996. * Returns the error stack.
  57997. *
  57998. * @return array
  57999. */
  58000. public static function getErrorStack()
  58001. {
  58002. return self::$errorStack;
  58003. }
  58004. /**
  58005. * @param integer $errno
  58006. * @param string $errstr
  58007. * @param string $errfile
  58008. * @param integer $errline
  58009. * @throws PHPUnit_Framework_Error
  58010. */
  58011. public static function handleError($errno, $errstr, $errfile, $errline)
  58012. {
  58013. if (!($errno & error_reporting())) {
  58014. return false;
  58015. }
  58016. self::$errorStack[] = array($errno, $errstr, $errfile, $errline);
  58017. $trace = debug_backtrace(false);
  58018. array_shift($trace);
  58019. foreach ($trace as $frame) {
  58020. if ($frame['function'] == '__toString') {
  58021. return false;
  58022. }
  58023. }
  58024. if ($errno == E_NOTICE || $errno == E_USER_NOTICE || $errno == E_STRICT) {
  58025. if (PHPUnit_Framework_Error_Notice::$enabled !== true) {
  58026. return false;
  58027. }
  58028. $exception = 'PHPUnit_Framework_Error_Notice';
  58029. } elseif ($errno == E_WARNING || $errno == E_USER_WARNING) {
  58030. if (PHPUnit_Framework_Error_Warning::$enabled !== true) {
  58031. return false;
  58032. }
  58033. $exception = 'PHPUnit_Framework_Error_Warning';
  58034. } elseif ($errno == E_DEPRECATED || $errno == E_USER_DEPRECATED) {
  58035. if (PHPUnit_Framework_Error_Deprecated::$enabled !== true) {
  58036. return false;
  58037. }
  58038. $exception = 'PHPUnit_Framework_Error_Deprecated';
  58039. } else {
  58040. $exception = 'PHPUnit_Framework_Error';
  58041. }
  58042. throw new $exception($errstr, $errno, $errfile, $errline);
  58043. }
  58044. /**
  58045. * Registers an error handler and returns a function that will restore
  58046. * the previous handler when invoked
  58047. * @param integer $severity PHP predefined error constant
  58048. * @link http://www.php.net/manual/en/errorfunc.constants.php
  58049. * @throws Exception if event of specified severity is emitted
  58050. */
  58051. public static function handleErrorOnce($severity = E_WARNING)
  58052. {
  58053. $terminator = function () {
  58054. static $expired = false;
  58055. if (!$expired) {
  58056. $expired = true;
  58057. // cleans temporary error handler
  58058. return restore_error_handler();
  58059. }
  58060. };
  58061. set_error_handler(function ($errno, $errstr) use ($severity) {
  58062. if ($errno === $severity) {
  58063. return;
  58064. }
  58065. return false;
  58066. });
  58067. return $terminator;
  58068. }
  58069. }
  58070. <?php
  58071. /*
  58072. * This file is part of PHPUnit.
  58073. *
  58074. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58075. *
  58076. * For the full copyright and license information, please view the LICENSE
  58077. * file that was distributed with this source code.
  58078. */
  58079. /**
  58080. * String helpers.
  58081. *
  58082. * @package PHPUnit
  58083. * @subpackage Util
  58084. * @author Sebastian Bergmann <sebastian@phpunit.de>
  58085. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  58086. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  58087. * @link http://www.phpunit.de/
  58088. * @since Class available since Release 3.6.0
  58089. */
  58090. class PHPUnit_Util_String
  58091. {
  58092. /**
  58093. * Converts a string to UTF-8 encoding.
  58094. *
  58095. * @param string $string
  58096. * @return string
  58097. */
  58098. public static function convertToUtf8($string)
  58099. {
  58100. if (!self::isUtf8($string)) {
  58101. if (function_exists('mb_convert_encoding')) {
  58102. $string = mb_convert_encoding($string, 'UTF-8');
  58103. } else {
  58104. $string = utf8_encode($string);
  58105. }
  58106. }
  58107. return $string;
  58108. }
  58109. /**
  58110. * Checks a string for UTF-8 encoding.
  58111. *
  58112. * @param string $string
  58113. * @return boolean
  58114. */
  58115. protected static function isUtf8($string)
  58116. {
  58117. $length = strlen($string);
  58118. for ($i = 0; $i < $length; $i++) {
  58119. if (ord($string[$i]) < 0x80) {
  58120. $n = 0;
  58121. } elseif ((ord($string[$i]) & 0xE0) == 0xC0) {
  58122. $n = 1;
  58123. } elseif ((ord($string[$i]) & 0xF0) == 0xE0) {
  58124. $n = 2;
  58125. } elseif ((ord($string[$i]) & 0xF0) == 0xF0) {
  58126. $n = 3;
  58127. } else {
  58128. return false;
  58129. }
  58130. for ($j = 0; $j < $n; $j++) {
  58131. if ((++$i == $length) || ((ord($string[$i]) & 0xC0) != 0x80)) {
  58132. return false;
  58133. }
  58134. }
  58135. }
  58136. return true;
  58137. }
  58138. }
  58139. <?php
  58140. /*
  58141. * This file is part of PHPUnit.
  58142. *
  58143. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58144. *
  58145. * For the full copyright and license information, please view the LICENSE
  58146. * file that was distributed with this source code.
  58147. */
  58148. /**
  58149. * Factory for PHPUnit_Framework_Exception objects that are used to describe
  58150. * invalid arguments passed to a function or method.
  58151. *
  58152. * @package PHPUnit
  58153. * @subpackage Util
  58154. * @author Sebastian Bergmann <sebastian@phpunit.de>
  58155. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  58156. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  58157. * @link http://www.phpunit.de/
  58158. * @since Class available since Release 3.4.0
  58159. */
  58160. class PHPUnit_Util_InvalidArgumentHelper
  58161. {
  58162. /**
  58163. * @param integer $argument
  58164. * @param string $type
  58165. * @param mixed $value
  58166. * @return PHPUnit_Framework_Exception
  58167. */
  58168. public static function factory($argument, $type, $value = null)
  58169. {
  58170. $stack = debug_backtrace(false);
  58171. return new PHPUnit_Framework_Exception(
  58172. sprintf(
  58173. 'Argument #%d%sof %s::%s() must be a %s',
  58174. $argument,
  58175. $value !== null ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ',
  58176. $stack[1]['class'],
  58177. $stack[1]['function'],
  58178. $type
  58179. )
  58180. );
  58181. }
  58182. }
  58183. <?php
  58184. /*
  58185. * This file is part of PHPUnit.
  58186. *
  58187. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58188. *
  58189. * For the full copyright and license information, please view the LICENSE
  58190. * file that was distributed with this source code.
  58191. */
  58192. /**
  58193. * Utility class that can print to STDOUT or write to a file.
  58194. *
  58195. * @package PHPUnit
  58196. * @subpackage Util
  58197. * @author Sebastian Bergmann <sebastian@phpunit.de>
  58198. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  58199. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  58200. * @link http://www.phpunit.de/
  58201. * @since Class available since Release 2.0.0
  58202. */
  58203. class PHPUnit_Util_Printer
  58204. {
  58205. /**
  58206. * If true, flush output after every write.
  58207. *
  58208. * @var boolean
  58209. */
  58210. protected $autoFlush = false;
  58211. /**
  58212. * @var resource
  58213. */
  58214. protected $out;
  58215. /**
  58216. * @var string
  58217. */
  58218. protected $outTarget;
  58219. /**
  58220. * @var boolean
  58221. */
  58222. protected $printsHTML = false;
  58223. /**
  58224. * Constructor.
  58225. *
  58226. * @param mixed $out
  58227. * @throws PHPUnit_Framework_Exception
  58228. */
  58229. public function __construct($out = null)
  58230. {
  58231. if ($out !== null) {
  58232. if (is_string($out)) {
  58233. if (strpos($out, 'socket://') === 0) {
  58234. $out = explode(':', str_replace('socket://', '', $out));
  58235. if (sizeof($out) != 2) {
  58236. throw new PHPUnit_Framework_Exception;
  58237. }
  58238. $this->out = fsockopen($out[0], $out[1]);
  58239. } else {
  58240. if (strpos($out, 'php://') === false &&
  58241. !is_dir(dirname($out))) {
  58242. mkdir(dirname($out), 0777, true);
  58243. }
  58244. $this->out = fopen($out, 'wt');
  58245. }
  58246. $this->outTarget = $out;
  58247. } else {
  58248. $this->out = $out;
  58249. }
  58250. }
  58251. }
  58252. /**
  58253. * Flush buffer, optionally tidy up HTML, and close output if it's not to a php stream
  58254. */
  58255. public function flush()
  58256. {
  58257. if ($this->out && strncmp($this->outTarget, 'php://', 6) !== 0) {
  58258. fclose($this->out);
  58259. }
  58260. if ($this->printsHTML === true &&
  58261. $this->outTarget !== null &&
  58262. strpos($this->outTarget, 'php://') !== 0 &&
  58263. strpos($this->outTarget, 'socket://') !== 0 &&
  58264. extension_loaded('tidy')) {
  58265. file_put_contents(
  58266. $this->outTarget,
  58267. tidy_repair_file(
  58268. $this->outTarget,
  58269. array('indent' => true, 'wrap' => 0),
  58270. 'utf8'
  58271. )
  58272. );
  58273. }
  58274. }
  58275. /**
  58276. * Performs a safe, incremental flush.
  58277. *
  58278. * Do not confuse this function with the flush() function of this class,
  58279. * since the flush() function may close the file being written to, rendering
  58280. * the current object no longer usable.
  58281. *
  58282. * @since Method available since Release 3.3.0
  58283. */
  58284. public function incrementalFlush()
  58285. {
  58286. if ($this->out) {
  58287. fflush($this->out);
  58288. } else {
  58289. flush();
  58290. }
  58291. }
  58292. /**
  58293. * @param string $buffer
  58294. */
  58295. public function write($buffer)
  58296. {
  58297. if ($this->out) {
  58298. fwrite($this->out, $buffer);
  58299. if ($this->autoFlush) {
  58300. $this->incrementalFlush();
  58301. }
  58302. } else {
  58303. if (PHP_SAPI != 'cli') {
  58304. $buffer = htmlspecialchars($buffer);
  58305. }
  58306. print $buffer;
  58307. if ($this->autoFlush) {
  58308. $this->incrementalFlush();
  58309. }
  58310. }
  58311. }
  58312. /**
  58313. * Check auto-flush mode.
  58314. *
  58315. * @return boolean
  58316. * @since Method available since Release 3.3.0
  58317. */
  58318. public function getAutoFlush()
  58319. {
  58320. return $this->autoFlush;
  58321. }
  58322. /**
  58323. * Set auto-flushing mode.
  58324. *
  58325. * If set, *incremental* flushes will be done after each write. This should
  58326. * not be confused with the different effects of this class' flush() method.
  58327. *
  58328. * @param boolean $autoFlush
  58329. * @since Method available since Release 3.3.0
  58330. */
  58331. public function setAutoFlush($autoFlush)
  58332. {
  58333. if (is_bool($autoFlush)) {
  58334. $this->autoFlush = $autoFlush;
  58335. } else {
  58336. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  58337. }
  58338. }
  58339. }
  58340. <?php
  58341. /*
  58342. * This file is part of PHPUnit.
  58343. *
  58344. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58345. *
  58346. * For the full copyright and license information, please view the LICENSE
  58347. * file that was distributed with this source code.
  58348. */
  58349. /**
  58350. * Wrapper for the PHPUnit XML configuration file.
  58351. *
  58352. * Example XML configuration file:
  58353. * <code>
  58354. * <?xml version="1.0" encoding="utf-8" ?>
  58355. *
  58356. * <phpunit backupGlobals="true"
  58357. * backupStaticAttributes="false"
  58358. * bootstrap="/path/to/bootstrap.php"
  58359. * cacheTokens="false"
  58360. * columns="80"
  58361. * colors="false"
  58362. * stderr="false"
  58363. * convertErrorsToExceptions="true"
  58364. * convertNoticesToExceptions="true"
  58365. * convertWarningsToExceptions="true"
  58366. * forceCoversAnnotation="false"
  58367. * mapTestClassNameToCoveredClassName="false"
  58368. * printerClass="PHPUnit_TextUI_ResultPrinter"
  58369. * processIsolation="false"
  58370. * stopOnError="false"
  58371. * stopOnFailure="false"
  58372. * stopOnIncomplete="false"
  58373. * stopOnRisky="false"
  58374. * stopOnSkipped="false"
  58375. * testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
  58376. * timeoutForSmallTests="1"
  58377. * timeoutForMediumTests="10"
  58378. * timeoutForLargeTests="60"
  58379. * beStrictAboutTestsThatDoNotTestAnything="false"
  58380. * beStrictAboutOutputDuringTests="false"
  58381. * beStrictAboutTestSize="false"
  58382. * beStrictAboutTodoAnnotatedTests="false"
  58383. * checkForUnintentionallyCoveredCode="false"
  58384. * disallowChangesToGlobalState="false"
  58385. * verbose="false">
  58386. * <testsuites>
  58387. * <testsuite name="My Test Suite">
  58388. * <directory suffix="Test.php" phpVersion="5.3.0" phpVersionOperator=">=">/path/to/files</directory>
  58389. * <file phpVersion="5.3.0" phpVersionOperator=">=">/path/to/MyTest.php</file>
  58390. * <exclude>/path/to/files/exclude</exclude>
  58391. * </testsuite>
  58392. * </testsuites>
  58393. *
  58394. * <groups>
  58395. * <include>
  58396. * <group>name</group>
  58397. * </include>
  58398. * <exclude>
  58399. * <group>name</group>
  58400. * </exclude>
  58401. * </groups>
  58402. *
  58403. * <filter>
  58404. * <blacklist>
  58405. * <directory suffix=".php">/path/to/files</directory>
  58406. * <file>/path/to/file</file>
  58407. * <exclude>
  58408. * <directory suffix=".php">/path/to/files</directory>
  58409. * <file>/path/to/file</file>
  58410. * </exclude>
  58411. * </blacklist>
  58412. * <whitelist addUncoveredFilesFromWhitelist="true"
  58413. * processUncoveredFilesFromWhitelist="false">
  58414. * <directory suffix=".php">/path/to/files</directory>
  58415. * <file>/path/to/file</file>
  58416. * <exclude>
  58417. * <directory suffix=".php">/path/to/files</directory>
  58418. * <file>/path/to/file</file>
  58419. * </exclude>
  58420. * </whitelist>
  58421. * </filter>
  58422. *
  58423. * <listeners>
  58424. * <listener class="MyListener" file="/optional/path/to/MyListener.php">
  58425. * <arguments>
  58426. * <array>
  58427. * <element key="0">
  58428. * <string>Sebastian</string>
  58429. * </element>
  58430. * </array>
  58431. * <integer>22</integer>
  58432. * <string>April</string>
  58433. * <double>19.78</double>
  58434. * <null/>
  58435. * <object class="stdClass"/>
  58436. * <file>MyRelativeFile.php</file>
  58437. * <directory>MyRelativeDir</directory>
  58438. * </arguments>
  58439. * </listener>
  58440. * </listeners>
  58441. *
  58442. * <logging>
  58443. * <log type="coverage-html" target="/tmp/report" lowUpperBound="50" highLowerBound="90"/>
  58444. * <log type="coverage-clover" target="/tmp/clover.xml"/>
  58445. * <log type="json" target="/tmp/logfile.json"/>
  58446. * <log type="plain" target="/tmp/logfile.txt"/>
  58447. * <log type="tap" target="/tmp/logfile.tap"/>
  58448. * <log type="junit" target="/tmp/logfile.xml" logIncompleteSkipped="false"/>
  58449. * <log type="testdox-html" target="/tmp/testdox.html"/>
  58450. * <log type="testdox-text" target="/tmp/testdox.txt"/>
  58451. * <log type="coverage-crap4j" target="/tmp/crap.xml"/>
  58452. * </logging>
  58453. *
  58454. * <php>
  58455. * <includePath>.</includePath>
  58456. * <ini name="foo" value="bar"/>
  58457. * <const name="foo" value="bar"/>
  58458. * <var name="foo" value="bar"/>
  58459. * <env name="foo" value="bar"/>
  58460. * <post name="foo" value="bar"/>
  58461. * <get name="foo" value="bar"/>
  58462. * <cookie name="foo" value="bar"/>
  58463. * <server name="foo" value="bar"/>
  58464. * <files name="foo" value="bar"/>
  58465. * <request name="foo" value="bar"/>
  58466. * </php>
  58467. *
  58468. * <selenium>
  58469. * <browser name="Firefox on Linux"
  58470. * browser="*firefox /usr/lib/firefox/firefox-bin"
  58471. * host="my.linux.box"
  58472. * port="4444"
  58473. * timeout="30000"/>
  58474. * </selenium>
  58475. * </phpunit>
  58476. * </code>
  58477. *
  58478. * @package PHPUnit
  58479. * @subpackage Util
  58480. * @author Sebastian Bergmann <sebastian@phpunit.de>
  58481. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  58482. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  58483. * @link http://www.phpunit.de/
  58484. * @since Class available since Release 3.2.0
  58485. */
  58486. class PHPUnit_Util_Configuration
  58487. {
  58488. private static $instances = array();
  58489. protected $document;
  58490. protected $xpath;
  58491. protected $filename;
  58492. /**
  58493. * Loads a PHPUnit configuration file.
  58494. *
  58495. * @param string $filename
  58496. */
  58497. protected function __construct($filename)
  58498. {
  58499. $this->filename = $filename;
  58500. $this->document = PHPUnit_Util_XML::loadFile($filename, false, true, true);
  58501. $this->xpath = new DOMXPath($this->document);
  58502. }
  58503. /**
  58504. * @since Method available since Release 3.4.0
  58505. */
  58506. final private function __clone()
  58507. {
  58508. }
  58509. /**
  58510. * Returns a PHPUnit configuration object.
  58511. *
  58512. * @param string $filename
  58513. * @return PHPUnit_Util_Configuration
  58514. * @since Method available since Release 3.4.0
  58515. */
  58516. public static function getInstance($filename)
  58517. {
  58518. $realpath = realpath($filename);
  58519. if ($realpath === false) {
  58520. throw new PHPUnit_Framework_Exception(
  58521. sprintf(
  58522. 'Could not read "%s".',
  58523. $filename
  58524. )
  58525. );
  58526. }
  58527. if (!isset(self::$instances[$realpath])) {
  58528. self::$instances[$realpath] = new PHPUnit_Util_Configuration($realpath);
  58529. }
  58530. return self::$instances[$realpath];
  58531. }
  58532. /**
  58533. * Returns the realpath to the configuration file.
  58534. *
  58535. * @return string
  58536. * @since Method available since Release 3.6.0
  58537. */
  58538. public function getFilename()
  58539. {
  58540. return $this->filename;
  58541. }
  58542. /**
  58543. * Returns the configuration for SUT filtering.
  58544. *
  58545. * @return array
  58546. * @since Method available since Release 3.2.1
  58547. */
  58548. public function getFilterConfiguration()
  58549. {
  58550. $addUncoveredFilesFromWhitelist = true;
  58551. $processUncoveredFilesFromWhitelist = false;
  58552. $tmp = $this->xpath->query('filter/whitelist');
  58553. if ($tmp->length == 1) {
  58554. if ($tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) {
  58555. $addUncoveredFilesFromWhitelist = $this->getBoolean(
  58556. (string) $tmp->item(0)->getAttribute(
  58557. 'addUncoveredFilesFromWhitelist'
  58558. ),
  58559. true
  58560. );
  58561. }
  58562. if ($tmp->item(0)->hasAttribute('processUncoveredFilesFromWhitelist')) {
  58563. $processUncoveredFilesFromWhitelist = $this->getBoolean(
  58564. (string) $tmp->item(0)->getAttribute(
  58565. 'processUncoveredFilesFromWhitelist'
  58566. ),
  58567. false
  58568. );
  58569. }
  58570. }
  58571. return array(
  58572. 'blacklist' => array(
  58573. 'include' => array(
  58574. 'directory' => $this->readFilterDirectories(
  58575. 'filter/blacklist/directory'
  58576. ),
  58577. 'file' => $this->readFilterFiles(
  58578. 'filter/blacklist/file'
  58579. )
  58580. ),
  58581. 'exclude' => array(
  58582. 'directory' => $this->readFilterDirectories(
  58583. 'filter/blacklist/exclude/directory'
  58584. ),
  58585. 'file' => $this->readFilterFiles(
  58586. 'filter/blacklist/exclude/file'
  58587. )
  58588. )
  58589. ),
  58590. 'whitelist' => array(
  58591. 'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist,
  58592. 'processUncoveredFilesFromWhitelist' => $processUncoveredFilesFromWhitelist,
  58593. 'include' => array(
  58594. 'directory' => $this->readFilterDirectories(
  58595. 'filter/whitelist/directory'
  58596. ),
  58597. 'file' => $this->readFilterFiles(
  58598. 'filter/whitelist/file'
  58599. )
  58600. ),
  58601. 'exclude' => array(
  58602. 'directory' => $this->readFilterDirectories(
  58603. 'filter/whitelist/exclude/directory'
  58604. ),
  58605. 'file' => $this->readFilterFiles(
  58606. 'filter/whitelist/exclude/file'
  58607. )
  58608. )
  58609. )
  58610. );
  58611. }
  58612. /**
  58613. * Returns the configuration for groups.
  58614. *
  58615. * @return array
  58616. * @since Method available since Release 3.2.1
  58617. */
  58618. public function getGroupConfiguration()
  58619. {
  58620. $groups = array(
  58621. 'include' => array(),
  58622. 'exclude' => array()
  58623. );
  58624. foreach ($this->xpath->query('groups/include/group') as $group) {
  58625. $groups['include'][] = (string) $group->nodeValue;
  58626. }
  58627. foreach ($this->xpath->query('groups/exclude/group') as $group) {
  58628. $groups['exclude'][] = (string) $group->nodeValue;
  58629. }
  58630. return $groups;
  58631. }
  58632. /**
  58633. * Returns the configuration for listeners.
  58634. *
  58635. * @return array
  58636. * @since Method available since Release 3.4.0
  58637. */
  58638. public function getListenerConfiguration()
  58639. {
  58640. $result = array();
  58641. foreach ($this->xpath->query('listeners/listener') as $listener) {
  58642. $class = (string) $listener->getAttribute('class');
  58643. $file = '';
  58644. $arguments = array();
  58645. if ($listener->getAttribute('file')) {
  58646. $file = $this->toAbsolutePath(
  58647. (string) $listener->getAttribute('file'),
  58648. true
  58649. );
  58650. }
  58651. foreach ($listener->childNodes as $node) {
  58652. if ($node instanceof DOMElement && $node->tagName == 'arguments') {
  58653. foreach ($node->childNodes as $argument) {
  58654. if ($argument instanceof DOMElement) {
  58655. if ($argument->tagName == 'file' ||
  58656. $argument->tagName == 'directory') {
  58657. $arguments[] = $this->toAbsolutePath((string) $argument->nodeValue);
  58658. } else {
  58659. $arguments[] = PHPUnit_Util_XML::xmlToVariable($argument);
  58660. }
  58661. }
  58662. }
  58663. }
  58664. }
  58665. $result[] = array(
  58666. 'class' => $class,
  58667. 'file' => $file,
  58668. 'arguments' => $arguments
  58669. );
  58670. }
  58671. return $result;
  58672. }
  58673. /**
  58674. * Returns the logging configuration.
  58675. *
  58676. * @return array
  58677. */
  58678. public function getLoggingConfiguration()
  58679. {
  58680. $result = array();
  58681. foreach ($this->xpath->query('logging/log') as $log) {
  58682. $type = (string) $log->getAttribute('type');
  58683. $target = (string) $log->getAttribute('target');
  58684. if (!$target) {
  58685. continue;
  58686. }
  58687. $target = $this->toAbsolutePath($target);
  58688. if ($type == 'coverage-html') {
  58689. if ($log->hasAttribute('lowUpperBound')) {
  58690. $result['lowUpperBound'] = (string) $log->getAttribute('lowUpperBound');
  58691. }
  58692. if ($log->hasAttribute('highLowerBound')) {
  58693. $result['highLowerBound'] = (string) $log->getAttribute('highLowerBound');
  58694. }
  58695. } elseif ($type == 'junit') {
  58696. if ($log->hasAttribute('logIncompleteSkipped')) {
  58697. $result['logIncompleteSkipped'] = $this->getBoolean(
  58698. (string) $log->getAttribute('logIncompleteSkipped'),
  58699. false
  58700. );
  58701. }
  58702. } elseif ($type == 'coverage-text') {
  58703. if ($log->hasAttribute('showUncoveredFiles')) {
  58704. $result['coverageTextShowUncoveredFiles'] = $this->getBoolean(
  58705. (string) $log->getAttribute('showUncoveredFiles'),
  58706. false
  58707. );
  58708. }
  58709. if ($log->hasAttribute('showOnlySummary')) {
  58710. $result['coverageTextShowOnlySummary'] = $this->getBoolean(
  58711. (string) $log->getAttribute('showOnlySummary'),
  58712. false
  58713. );
  58714. }
  58715. }
  58716. $result[$type] = $target;
  58717. }
  58718. return $result;
  58719. }
  58720. /**
  58721. * Returns the PHP configuration.
  58722. *
  58723. * @return array
  58724. * @since Method available since Release 3.2.1
  58725. */
  58726. public function getPHPConfiguration()
  58727. {
  58728. $result = array(
  58729. 'include_path' => array(),
  58730. 'ini' => array(),
  58731. 'const' => array(),
  58732. 'var' => array(),
  58733. 'env' => array(),
  58734. 'post' => array(),
  58735. 'get' => array(),
  58736. 'cookie' => array(),
  58737. 'server' => array(),
  58738. 'files' => array(),
  58739. 'request' => array()
  58740. );
  58741. foreach ($this->xpath->query('php/includePath') as $includePath) {
  58742. $path = (string) $includePath->nodeValue;
  58743. if ($path) {
  58744. $result['include_path'][] = $this->toAbsolutePath($path);
  58745. }
  58746. }
  58747. foreach ($this->xpath->query('php/ini') as $ini) {
  58748. $name = (string) $ini->getAttribute('name');
  58749. $value = (string) $ini->getAttribute('value');
  58750. $result['ini'][$name] = $value;
  58751. }
  58752. foreach ($this->xpath->query('php/const') as $const) {
  58753. $name = (string) $const->getAttribute('name');
  58754. $value = (string) $const->getAttribute('value');
  58755. $result['const'][$name] = $this->getBoolean($value, $value);
  58756. }
  58757. foreach (array('var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
  58758. foreach ($this->xpath->query('php/' . $array) as $var) {
  58759. $name = (string) $var->getAttribute('name');
  58760. $value = (string) $var->getAttribute('value');
  58761. $result[$array][$name] = $this->getBoolean($value, $value);
  58762. }
  58763. }
  58764. return $result;
  58765. }
  58766. /**
  58767. * Handles the PHP configuration.
  58768. *
  58769. * @since Method available since Release 3.2.20
  58770. */
  58771. public function handlePHPConfiguration()
  58772. {
  58773. $configuration = $this->getPHPConfiguration();
  58774. if (! empty($configuration['include_path'])) {
  58775. ini_set(
  58776. 'include_path',
  58777. implode(PATH_SEPARATOR, $configuration['include_path']) .
  58778. PATH_SEPARATOR .
  58779. ini_get('include_path')
  58780. );
  58781. }
  58782. foreach ($configuration['ini'] as $name => $value) {
  58783. if (defined($value)) {
  58784. $value = constant($value);
  58785. }
  58786. ini_set($name, $value);
  58787. }
  58788. foreach ($configuration['const'] as $name => $value) {
  58789. if (!defined($name)) {
  58790. define($name, $value);
  58791. }
  58792. }
  58793. foreach (array('var', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
  58794. // See https://github.com/sebastianbergmann/phpunit/issues/277
  58795. switch ($array) {
  58796. case 'var':
  58797. $target = &$GLOBALS;
  58798. break;
  58799. case 'server':
  58800. $target = &$_SERVER;
  58801. break;
  58802. default:
  58803. $target = &$GLOBALS['_' . strtoupper($array)];
  58804. break;
  58805. }
  58806. foreach ($configuration[$array] as $name => $value) {
  58807. $target[$name] = $value;
  58808. }
  58809. }
  58810. foreach ($configuration['env'] as $name => $value) {
  58811. if (false === getenv($name)) {
  58812. putenv("{$name}={$value}");
  58813. }
  58814. if (!isset($_ENV[$name])) {
  58815. $_ENV[$name] = $value;
  58816. }
  58817. }
  58818. }
  58819. /**
  58820. * Returns the PHPUnit configuration.
  58821. *
  58822. * @return array
  58823. * @since Method available since Release 3.2.14
  58824. */
  58825. public function getPHPUnitConfiguration()
  58826. {
  58827. $result = array();
  58828. $root = $this->document->documentElement;
  58829. if ($root->hasAttribute('cacheTokens')) {
  58830. $result['cacheTokens'] = $this->getBoolean(
  58831. (string) $root->getAttribute('cacheTokens'),
  58832. false
  58833. );
  58834. }
  58835. if ($root->hasAttribute('columns')) {
  58836. $columns = (string) $root->getAttribute('columns');
  58837. if ($columns == 'max') {
  58838. $result['columns'] = 'max';
  58839. } else {
  58840. $result['columns'] = $this->getInteger($columns, 80);
  58841. }
  58842. }
  58843. if ($root->hasAttribute('colors')) {
  58844. /* only allow boolean for compatibility with previous versions
  58845. 'always' only allowed from command line */
  58846. if ($this->getBoolean($root->getAttribute('colors'), false)) {
  58847. $result['colors'] = PHPUnit_TextUI_ResultPrinter::COLOR_AUTO;
  58848. } else {
  58849. $result['colors'] = PHPUnit_TextUI_ResultPrinter::COLOR_NEVER;
  58850. }
  58851. }
  58852. /**
  58853. * Issue #657
  58854. */
  58855. if ($root->hasAttribute('stderr')) {
  58856. $result['stderr'] = $this->getBoolean(
  58857. (string)$root->getAttribute('stderr'),
  58858. false
  58859. );
  58860. }
  58861. if ($root->hasAttribute('backupGlobals')) {
  58862. $result['backupGlobals'] = $this->getBoolean(
  58863. (string) $root->getAttribute('backupGlobals'),
  58864. true
  58865. );
  58866. }
  58867. if ($root->hasAttribute('backupStaticAttributes')) {
  58868. $result['backupStaticAttributes'] = $this->getBoolean(
  58869. (string) $root->getAttribute('backupStaticAttributes'),
  58870. false
  58871. );
  58872. }
  58873. if ($root->getAttribute('bootstrap')) {
  58874. $result['bootstrap'] = $this->toAbsolutePath(
  58875. (string) $root->getAttribute('bootstrap')
  58876. );
  58877. }
  58878. if ($root->hasAttribute('convertErrorsToExceptions')) {
  58879. $result['convertErrorsToExceptions'] = $this->getBoolean(
  58880. (string) $root->getAttribute('convertErrorsToExceptions'),
  58881. true
  58882. );
  58883. }
  58884. if ($root->hasAttribute('convertNoticesToExceptions')) {
  58885. $result['convertNoticesToExceptions'] = $this->getBoolean(
  58886. (string) $root->getAttribute('convertNoticesToExceptions'),
  58887. true
  58888. );
  58889. }
  58890. if ($root->hasAttribute('convertWarningsToExceptions')) {
  58891. $result['convertWarningsToExceptions'] = $this->getBoolean(
  58892. (string) $root->getAttribute('convertWarningsToExceptions'),
  58893. true
  58894. );
  58895. }
  58896. if ($root->hasAttribute('forceCoversAnnotation')) {
  58897. $result['forceCoversAnnotation'] = $this->getBoolean(
  58898. (string) $root->getAttribute('forceCoversAnnotation'),
  58899. false
  58900. );
  58901. }
  58902. if ($root->hasAttribute('mapTestClassNameToCoveredClassName')) {
  58903. $result['mapTestClassNameToCoveredClassName'] = $this->getBoolean(
  58904. (string) $root->getAttribute('mapTestClassNameToCoveredClassName'),
  58905. false
  58906. );
  58907. }
  58908. if ($root->hasAttribute('processIsolation')) {
  58909. $result['processIsolation'] = $this->getBoolean(
  58910. (string) $root->getAttribute('processIsolation'),
  58911. false
  58912. );
  58913. }
  58914. if ($root->hasAttribute('stopOnError')) {
  58915. $result['stopOnError'] = $this->getBoolean(
  58916. (string) $root->getAttribute('stopOnError'),
  58917. false
  58918. );
  58919. }
  58920. if ($root->hasAttribute('stopOnFailure')) {
  58921. $result['stopOnFailure'] = $this->getBoolean(
  58922. (string) $root->getAttribute('stopOnFailure'),
  58923. false
  58924. );
  58925. }
  58926. if ($root->hasAttribute('stopOnIncomplete')) {
  58927. $result['stopOnIncomplete'] = $this->getBoolean(
  58928. (string) $root->getAttribute('stopOnIncomplete'),
  58929. false
  58930. );
  58931. }
  58932. if ($root->hasAttribute('stopOnRisky')) {
  58933. $result['stopOnRisky'] = $this->getBoolean(
  58934. (string) $root->getAttribute('stopOnRisky'),
  58935. false
  58936. );
  58937. }
  58938. if ($root->hasAttribute('stopOnSkipped')) {
  58939. $result['stopOnSkipped'] = $this->getBoolean(
  58940. (string) $root->getAttribute('stopOnSkipped'),
  58941. false
  58942. );
  58943. }
  58944. if ($root->hasAttribute('testSuiteLoaderClass')) {
  58945. $result['testSuiteLoaderClass'] = (string) $root->getAttribute(
  58946. 'testSuiteLoaderClass'
  58947. );
  58948. }
  58949. if ($root->getAttribute('testSuiteLoaderFile')) {
  58950. $result['testSuiteLoaderFile'] = $this->toAbsolutePath(
  58951. (string) $root->getAttribute('testSuiteLoaderFile')
  58952. );
  58953. }
  58954. if ($root->hasAttribute('printerClass')) {
  58955. $result['printerClass'] = (string) $root->getAttribute(
  58956. 'printerClass'
  58957. );
  58958. }
  58959. if ($root->getAttribute('printerFile')) {
  58960. $result['printerFile'] = $this->toAbsolutePath(
  58961. (string) $root->getAttribute('printerFile')
  58962. );
  58963. }
  58964. if ($root->hasAttribute('timeoutForSmallTests')) {
  58965. $result['timeoutForSmallTests'] = $this->getInteger(
  58966. (string) $root->getAttribute('timeoutForSmallTests'),
  58967. 1
  58968. );
  58969. }
  58970. if ($root->hasAttribute('timeoutForMediumTests')) {
  58971. $result['timeoutForMediumTests'] = $this->getInteger(
  58972. (string) $root->getAttribute('timeoutForMediumTests'),
  58973. 10
  58974. );
  58975. }
  58976. if ($root->hasAttribute('timeoutForLargeTests')) {
  58977. $result['timeoutForLargeTests'] = $this->getInteger(
  58978. (string) $root->getAttribute('timeoutForLargeTests'),
  58979. 60
  58980. );
  58981. }
  58982. if ($root->hasAttribute('beStrictAboutTestsThatDoNotTestAnything')) {
  58983. $result['reportUselessTests'] = $this->getBoolean(
  58984. (string) $root->getAttribute('beStrictAboutTestsThatDoNotTestAnything'),
  58985. false
  58986. );
  58987. }
  58988. if ($root->hasAttribute('checkForUnintentionallyCoveredCode')) {
  58989. $result['strictCoverage'] = $this->getBoolean(
  58990. (string) $root->getAttribute('checkForUnintentionallyCoveredCode'),
  58991. false
  58992. );
  58993. }
  58994. if ($root->hasAttribute('beStrictAboutOutputDuringTests')) {
  58995. $result['disallowTestOutput'] = $this->getBoolean(
  58996. (string) $root->getAttribute('beStrictAboutOutputDuringTests'),
  58997. false
  58998. );
  58999. }
  59000. if ($root->hasAttribute('beStrictAboutChangesToGlobalState')) {
  59001. $result['disallowChangesToGlobalState'] = $this->getBoolean(
  59002. (string) $root->getAttribute('beStrictAboutChangesToGlobalState'),
  59003. false
  59004. );
  59005. }
  59006. if ($root->hasAttribute('beStrictAboutTestSize')) {
  59007. $result['enforceTimeLimit'] = $this->getBoolean(
  59008. (string) $root->getAttribute('beStrictAboutTestSize'),
  59009. false
  59010. );
  59011. }
  59012. if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) {
  59013. $result['disallowTodoAnnotatedTests'] = $this->getBoolean(
  59014. (string) $root->getAttribute('beStrictAboutTodoAnnotatedTests'),
  59015. false
  59016. );
  59017. }
  59018. if ($root->hasAttribute('strict')) {
  59019. $flag = $this->getBoolean(
  59020. (string) $root->getAttribute('strict'),
  59021. false
  59022. );
  59023. $result['reportUselessTests'] = $flag;
  59024. $result['strictCoverage'] = $flag;
  59025. $result['disallowTestOutput'] = $flag;
  59026. $result['enforceTimeLimit'] = $flag;
  59027. $result['disallowTodoAnnotatedTests'] = $flag;
  59028. $result['deprecatedStrictModeSetting'] = true;
  59029. }
  59030. if ($root->hasAttribute('verbose')) {
  59031. $result['verbose'] = $this->getBoolean(
  59032. (string) $root->getAttribute('verbose'),
  59033. false
  59034. );
  59035. }
  59036. return $result;
  59037. }
  59038. /**
  59039. * Returns the SeleniumTestCase browser configuration.
  59040. *
  59041. * @return array
  59042. * @since Method available since Release 3.2.9
  59043. */
  59044. public function getSeleniumBrowserConfiguration()
  59045. {
  59046. $result = array();
  59047. foreach ($this->xpath->query('selenium/browser') as $config) {
  59048. $name = (string) $config->getAttribute('name');
  59049. $browser = (string) $config->getAttribute('browser');
  59050. if ($config->hasAttribute('host')) {
  59051. $host = (string) $config->getAttribute('host');
  59052. } else {
  59053. $host = 'localhost';
  59054. }
  59055. if ($config->hasAttribute('port')) {
  59056. $port = $this->getInteger(
  59057. (string) $config->getAttribute('port'),
  59058. 4444
  59059. );
  59060. } else {
  59061. $port = 4444;
  59062. }
  59063. if ($config->hasAttribute('timeout')) {
  59064. $timeout = $this->getInteger(
  59065. (string) $config->getAttribute('timeout'),
  59066. 30000
  59067. );
  59068. } else {
  59069. $timeout = 30000;
  59070. }
  59071. $result[] = array(
  59072. 'name' => $name,
  59073. 'browser' => $browser,
  59074. 'host' => $host,
  59075. 'port' => $port,
  59076. 'timeout' => $timeout
  59077. );
  59078. }
  59079. return $result;
  59080. }
  59081. /**
  59082. * Returns the test suite configuration.
  59083. *
  59084. * @return PHPUnit_Framework_TestSuite
  59085. * @since Method available since Release 3.2.1
  59086. */
  59087. public function getTestSuiteConfiguration($testSuiteFilter = null)
  59088. {
  59089. $testSuiteNodes = $this->xpath->query('testsuites/testsuite');
  59090. if ($testSuiteNodes->length == 0) {
  59091. $testSuiteNodes = $this->xpath->query('testsuite');
  59092. }
  59093. if ($testSuiteNodes->length == 1) {
  59094. return $this->getTestSuite($testSuiteNodes->item(0), $testSuiteFilter);
  59095. }
  59096. if ($testSuiteNodes->length > 1) {
  59097. $suite = new PHPUnit_Framework_TestSuite;
  59098. foreach ($testSuiteNodes as $testSuiteNode) {
  59099. $suite->addTestSuite(
  59100. $this->getTestSuite($testSuiteNode, $testSuiteFilter)
  59101. );
  59102. }
  59103. return $suite;
  59104. }
  59105. }
  59106. /**
  59107. * @param DOMElement $testSuiteNode
  59108. * @return PHPUnit_Framework_TestSuite
  59109. * @since Method available since Release 3.4.0
  59110. */
  59111. protected function getTestSuite(DOMElement $testSuiteNode, $testSuiteFilter = null)
  59112. {
  59113. if ($testSuiteNode->hasAttribute('name')) {
  59114. $suite = new PHPUnit_Framework_TestSuite(
  59115. (string) $testSuiteNode->getAttribute('name')
  59116. );
  59117. } else {
  59118. $suite = new PHPUnit_Framework_TestSuite;
  59119. }
  59120. $exclude = array();
  59121. foreach ($testSuiteNode->getElementsByTagName('exclude') as $excludeNode) {
  59122. $excludeFile = (string) $excludeNode->nodeValue;
  59123. if ($excludeFile) {
  59124. $exclude[] = $this->toAbsolutePath($excludeFile);
  59125. }
  59126. }
  59127. $fileIteratorFacade = new File_Iterator_Facade;
  59128. foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) {
  59129. if ($testSuiteFilter && $directoryNode->parentNode->getAttribute('name') != $testSuiteFilter) {
  59130. continue;
  59131. }
  59132. $directory = (string) $directoryNode->nodeValue;
  59133. if (empty($directory)) {
  59134. continue;
  59135. }
  59136. if ($directoryNode->hasAttribute('phpVersion')) {
  59137. $phpVersion = (string) $directoryNode->getAttribute('phpVersion');
  59138. } else {
  59139. $phpVersion = PHP_VERSION;
  59140. }
  59141. if ($directoryNode->hasAttribute('phpVersionOperator')) {
  59142. $phpVersionOperator = (string) $directoryNode->getAttribute('phpVersionOperator');
  59143. } else {
  59144. $phpVersionOperator = '>=';
  59145. }
  59146. if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) {
  59147. continue;
  59148. }
  59149. if ($directoryNode->hasAttribute('prefix')) {
  59150. $prefix = (string) $directoryNode->getAttribute('prefix');
  59151. } else {
  59152. $prefix = '';
  59153. }
  59154. if ($directoryNode->hasAttribute('suffix')) {
  59155. $suffix = (string) $directoryNode->getAttribute('suffix');
  59156. } else {
  59157. $suffix = 'Test.php';
  59158. }
  59159. $files = $fileIteratorFacade->getFilesAsArray(
  59160. $this->toAbsolutePath($directory),
  59161. $suffix,
  59162. $prefix,
  59163. $exclude
  59164. );
  59165. $suite->addTestFiles($files);
  59166. }
  59167. foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) {
  59168. if ($testSuiteFilter && $fileNode->parentNode->getAttribute('name') != $testSuiteFilter) {
  59169. continue;
  59170. }
  59171. $file = (string) $fileNode->nodeValue;
  59172. if (empty($file)) {
  59173. continue;
  59174. }
  59175. // Get the absolute path to the file
  59176. $file = $fileIteratorFacade->getFilesAsArray(
  59177. $this->toAbsolutePath($file)
  59178. );
  59179. if (!isset($file[0])) {
  59180. continue;
  59181. }
  59182. $file = $file[0];
  59183. if ($fileNode->hasAttribute('phpVersion')) {
  59184. $phpVersion = (string) $fileNode->getAttribute('phpVersion');
  59185. } else {
  59186. $phpVersion = PHP_VERSION;
  59187. }
  59188. if ($fileNode->hasAttribute('phpVersionOperator')) {
  59189. $phpVersionOperator = (string) $fileNode->getAttribute('phpVersionOperator');
  59190. } else {
  59191. $phpVersionOperator = '>=';
  59192. }
  59193. if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) {
  59194. continue;
  59195. }
  59196. $suite->addTestFile($file);
  59197. }
  59198. return $suite;
  59199. }
  59200. /**
  59201. * @param string $value
  59202. * @param boolean $default
  59203. * @return boolean
  59204. * @since Method available since Release 3.2.3
  59205. */
  59206. protected function getBoolean($value, $default)
  59207. {
  59208. if (strtolower($value) == 'false') {
  59209. return false;
  59210. } elseif (strtolower($value) == 'true') {
  59211. return true;
  59212. }
  59213. return $default;
  59214. }
  59215. /**
  59216. * @param string $value
  59217. * @param boolean $default
  59218. * @return boolean
  59219. * @since Method available since Release 3.6.0
  59220. */
  59221. protected function getInteger($value, $default)
  59222. {
  59223. if (is_numeric($value)) {
  59224. return (int) $value;
  59225. }
  59226. return $default;
  59227. }
  59228. /**
  59229. * @param string $query
  59230. * @return array
  59231. * @since Method available since Release 3.2.3
  59232. */
  59233. protected function readFilterDirectories($query)
  59234. {
  59235. $directories = array();
  59236. foreach ($this->xpath->query($query) as $directory) {
  59237. $directoryPath = (string) $directory->nodeValue;
  59238. if (!$directoryPath) {
  59239. continue;
  59240. }
  59241. if ($directory->hasAttribute('prefix')) {
  59242. $prefix = (string) $directory->getAttribute('prefix');
  59243. } else {
  59244. $prefix = '';
  59245. }
  59246. if ($directory->hasAttribute('suffix')) {
  59247. $suffix = (string) $directory->getAttribute('suffix');
  59248. } else {
  59249. $suffix = '.php';
  59250. }
  59251. if ($directory->hasAttribute('group')) {
  59252. $group = (string) $directory->getAttribute('group');
  59253. } else {
  59254. $group = 'DEFAULT';
  59255. }
  59256. $directories[] = array(
  59257. 'path' => $this->toAbsolutePath($directoryPath),
  59258. 'prefix' => $prefix,
  59259. 'suffix' => $suffix,
  59260. 'group' => $group
  59261. );
  59262. }
  59263. return $directories;
  59264. }
  59265. /**
  59266. * @param string $query
  59267. * @return array
  59268. * @since Method available since Release 3.2.3
  59269. */
  59270. protected function readFilterFiles($query)
  59271. {
  59272. $files = array();
  59273. foreach ($this->xpath->query($query) as $file) {
  59274. $filePath = (string) $file->nodeValue;
  59275. if ($filePath) {
  59276. $files[] = $this->toAbsolutePath($filePath);
  59277. }
  59278. }
  59279. return $files;
  59280. }
  59281. /**
  59282. * @param string $path
  59283. * @param boolean $useIncludePath
  59284. * @return string
  59285. * @since Method available since Release 3.5.0
  59286. */
  59287. protected function toAbsolutePath($path, $useIncludePath = false)
  59288. {
  59289. if ($path[0] === '/') {
  59290. return $path;
  59291. }
  59292. // Matches the following on Windows:
  59293. // - \\NetworkComputer\Path
  59294. // - \\.\D:
  59295. // - \\.\c:
  59296. // - C:\Windows
  59297. // - C:\windows
  59298. // - C:/windows
  59299. // - c:/windows
  59300. if (defined('PHP_WINDOWS_VERSION_BUILD') &&
  59301. ($path[0] === '\\' ||
  59302. (strlen($path) >= 3 && preg_match('#^[A-Z]\:[/\\\]#i', substr($path, 0, 3))))) {
  59303. return $path;
  59304. }
  59305. // Stream
  59306. if (strpos($path, '://') !== false) {
  59307. return $path;
  59308. }
  59309. $file = dirname($this->filename) . DIRECTORY_SEPARATOR . $path;
  59310. if ($useIncludePath && !file_exists($file)) {
  59311. $includePathFile = stream_resolve_include_path($path);
  59312. if ($includePathFile) {
  59313. $file = $includePathFile;
  59314. }
  59315. }
  59316. return $file;
  59317. }
  59318. }
  59319. <?php
  59320. /*
  59321. * This file is part of PHPUnit.
  59322. *
  59323. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59324. *
  59325. * For the full copyright and license information, please view the LICENSE
  59326. * file that was distributed with this source code.
  59327. */
  59328. /**
  59329. *
  59330. *
  59331. * @package PHPUnit
  59332. * @subpackage Util
  59333. * @author Sebastian Bergmann <sebastian@phpunit.de>
  59334. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  59335. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  59336. * @link http://www.phpunit.de/
  59337. * @since Class available since Release 3.4.0
  59338. */
  59339. class PHPUnit_Util_GlobalState
  59340. {
  59341. /**
  59342. * @var array
  59343. */
  59344. protected static $superGlobalArrays = array(
  59345. '_ENV',
  59346. '_POST',
  59347. '_GET',
  59348. '_COOKIE',
  59349. '_SERVER',
  59350. '_FILES',
  59351. '_REQUEST'
  59352. );
  59353. /**
  59354. * @var array
  59355. */
  59356. protected static $superGlobalArraysLong = array(
  59357. 'HTTP_ENV_VARS',
  59358. 'HTTP_POST_VARS',
  59359. 'HTTP_GET_VARS',
  59360. 'HTTP_COOKIE_VARS',
  59361. 'HTTP_SERVER_VARS',
  59362. 'HTTP_POST_FILES'
  59363. );
  59364. public static function getIncludedFilesAsString()
  59365. {
  59366. return static::processIncludedFilesAsString(get_included_files());
  59367. }
  59368. public static function processIncludedFilesAsString(array $files)
  59369. {
  59370. $blacklist = new PHPUnit_Util_Blacklist;
  59371. $prefix = false;
  59372. $result = '';
  59373. if (defined('__PHPUNIT_PHAR__')) {
  59374. $prefix = 'phar://' . __PHPUNIT_PHAR__ . '/';
  59375. }
  59376. for ($i = count($files) - 1; $i > 0; $i--) {
  59377. $file = $files[$i];
  59378. if ($prefix !== false && strpos($file, $prefix) === 0) {
  59379. continue;
  59380. }
  59381. // Skip virtual file system protocols
  59382. if (preg_match('/^(vfs|phpvfs[a-z0-9]+):/', $file)) {
  59383. continue;
  59384. }
  59385. if (!$blacklist->isBlacklisted($file) && is_file($file)) {
  59386. $result = 'require_once \'' . $file . "';\n" . $result;
  59387. }
  59388. }
  59389. return $result;
  59390. }
  59391. public static function getIniSettingsAsString()
  59392. {
  59393. $result = '';
  59394. $iniSettings = ini_get_all(null, false);
  59395. foreach ($iniSettings as $key => $value) {
  59396. $result .= sprintf(
  59397. '@ini_set(%s, %s);' . "\n",
  59398. self::exportVariable($key),
  59399. self::exportVariable($value)
  59400. );
  59401. }
  59402. return $result;
  59403. }
  59404. public static function getConstantsAsString()
  59405. {
  59406. $constants = get_defined_constants(true);
  59407. $result = '';
  59408. if (isset($constants['user'])) {
  59409. foreach ($constants['user'] as $name => $value) {
  59410. $result .= sprintf(
  59411. 'if (!defined(\'%s\')) define(\'%s\', %s);' . "\n",
  59412. $name,
  59413. $name,
  59414. self::exportVariable($value)
  59415. );
  59416. }
  59417. }
  59418. return $result;
  59419. }
  59420. public static function getGlobalsAsString()
  59421. {
  59422. $result = '';
  59423. $superGlobalArrays = self::getSuperGlobalArrays();
  59424. foreach ($superGlobalArrays as $superGlobalArray) {
  59425. if (isset($GLOBALS[$superGlobalArray]) &&
  59426. is_array($GLOBALS[$superGlobalArray])) {
  59427. foreach (array_keys($GLOBALS[$superGlobalArray]) as $key) {
  59428. if ($GLOBALS[$superGlobalArray][$key] instanceof Closure) {
  59429. continue;
  59430. }
  59431. $result .= sprintf(
  59432. '$GLOBALS[\'%s\'][\'%s\'] = %s;' . "\n",
  59433. $superGlobalArray,
  59434. $key,
  59435. self::exportVariable($GLOBALS[$superGlobalArray][$key])
  59436. );
  59437. }
  59438. }
  59439. }
  59440. $blacklist = $superGlobalArrays;
  59441. $blacklist[] = 'GLOBALS';
  59442. foreach (array_keys($GLOBALS) as $key) {
  59443. if (!in_array($key, $blacklist) && !$GLOBALS[$key] instanceof Closure) {
  59444. $result .= sprintf(
  59445. '$GLOBALS[\'%s\'] = %s;' . "\n",
  59446. $key,
  59447. self::exportVariable($GLOBALS[$key])
  59448. );
  59449. }
  59450. }
  59451. return $result;
  59452. }
  59453. protected static function getSuperGlobalArrays()
  59454. {
  59455. if (ini_get('register_long_arrays') == '1') {
  59456. return array_merge(
  59457. self::$superGlobalArrays,
  59458. self::$superGlobalArraysLong
  59459. );
  59460. } else {
  59461. return self::$superGlobalArrays;
  59462. }
  59463. }
  59464. protected static function exportVariable($variable)
  59465. {
  59466. if (is_scalar($variable) || is_null($variable) ||
  59467. (is_array($variable) && self::arrayOnlyContainsScalars($variable))) {
  59468. return var_export($variable, true);
  59469. }
  59470. return 'unserialize(' .
  59471. var_export(serialize($variable), true) .
  59472. ')';
  59473. }
  59474. protected static function arrayOnlyContainsScalars(array $array)
  59475. {
  59476. $result = true;
  59477. foreach ($array as $element) {
  59478. if (is_array($element)) {
  59479. $result = self::arrayOnlyContainsScalars($element);
  59480. } elseif (!is_scalar($element) && !is_null($element)) {
  59481. $result = false;
  59482. }
  59483. if ($result === false) {
  59484. break;
  59485. }
  59486. }
  59487. return $result;
  59488. }
  59489. }
  59490. <?php
  59491. /*
  59492. * This file is part of PHPUnit.
  59493. *
  59494. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59495. *
  59496. * For the full copyright and license information, please view the LICENSE
  59497. * file that was distributed with this source code.
  59498. */
  59499. if (!defined('JSON_PRETTY_PRINT')) {
  59500. define('JSON_PRETTY_PRINT', 128);
  59501. }
  59502. /**
  59503. * A TestListener that generates JSON messages.
  59504. *
  59505. * @package PHPUnit
  59506. * @subpackage Util_Log
  59507. * @author Sebastian Bergmann <sebastian@phpunit.de>
  59508. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  59509. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  59510. * @link http://www.phpunit.de/
  59511. * @since Class available since Release 3.0.0
  59512. */
  59513. class PHPUnit_Util_Log_JSON extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
  59514. {
  59515. /**
  59516. * @var string
  59517. */
  59518. protected $currentTestSuiteName = '';
  59519. /**
  59520. * @var string
  59521. */
  59522. protected $currentTestName = '';
  59523. /**
  59524. * @var boolean
  59525. * @access private
  59526. */
  59527. protected $currentTestPass = true;
  59528. /**
  59529. * An error occurred.
  59530. *
  59531. * @param PHPUnit_Framework_Test $test
  59532. * @param Exception $e
  59533. * @param float $time
  59534. */
  59535. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  59536. {
  59537. $this->writeCase(
  59538. 'error',
  59539. $time,
  59540. PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
  59541. $e->getMessage(),
  59542. $test
  59543. );
  59544. $this->currentTestPass = false;
  59545. }
  59546. /**
  59547. * A failure occurred.
  59548. *
  59549. * @param PHPUnit_Framework_Test $test
  59550. * @param PHPUnit_Framework_AssertionFailedError $e
  59551. * @param float $time
  59552. */
  59553. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  59554. {
  59555. $this->writeCase(
  59556. 'fail',
  59557. $time,
  59558. PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
  59559. $e->getMessage(),
  59560. $test
  59561. );
  59562. $this->currentTestPass = false;
  59563. }
  59564. /**
  59565. * Incomplete test.
  59566. *
  59567. * @param PHPUnit_Framework_Test $test
  59568. * @param Exception $e
  59569. * @param float $time
  59570. */
  59571. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59572. {
  59573. $this->writeCase(
  59574. 'error',
  59575. $time,
  59576. PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
  59577. 'Incomplete Test: ' . $e->getMessage(),
  59578. $test
  59579. );
  59580. $this->currentTestPass = false;
  59581. }
  59582. /**
  59583. * Risky test.
  59584. *
  59585. * @param PHPUnit_Framework_Test $test
  59586. * @param Exception $e
  59587. * @param float $time
  59588. * @since Method available since Release 4.0.0
  59589. */
  59590. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59591. {
  59592. $this->writeCase(
  59593. 'error',
  59594. $time,
  59595. PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
  59596. 'Risky Test: ' . $e->getMessage(),
  59597. $test
  59598. );
  59599. $this->currentTestPass = false;
  59600. }
  59601. /**
  59602. * Skipped test.
  59603. *
  59604. * @param PHPUnit_Framework_Test $test
  59605. * @param Exception $e
  59606. * @param float $time
  59607. */
  59608. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59609. {
  59610. $this->writeCase(
  59611. 'error',
  59612. $time,
  59613. PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
  59614. 'Skipped Test: ' . $e->getMessage(),
  59615. $test
  59616. );
  59617. $this->currentTestPass = false;
  59618. }
  59619. /**
  59620. * A testsuite started.
  59621. *
  59622. * @param PHPUnit_Framework_TestSuite $suite
  59623. */
  59624. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  59625. {
  59626. $this->currentTestSuiteName = $suite->getName();
  59627. $this->currentTestName = '';
  59628. $this->write(
  59629. array(
  59630. 'event' => 'suiteStart',
  59631. 'suite' => $this->currentTestSuiteName,
  59632. 'tests' => count($suite)
  59633. )
  59634. );
  59635. }
  59636. /**
  59637. * A testsuite ended.
  59638. *
  59639. * @param PHPUnit_Framework_TestSuite $suite
  59640. */
  59641. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  59642. {
  59643. $this->currentTestSuiteName = '';
  59644. $this->currentTestName = '';
  59645. }
  59646. /**
  59647. * A test started.
  59648. *
  59649. * @param PHPUnit_Framework_Test $test
  59650. */
  59651. public function startTest(PHPUnit_Framework_Test $test)
  59652. {
  59653. $this->currentTestName = PHPUnit_Util_Test::describe($test);
  59654. $this->currentTestPass = true;
  59655. $this->write(
  59656. array(
  59657. 'event' => 'testStart',
  59658. 'suite' => $this->currentTestSuiteName,
  59659. 'test' => $this->currentTestName
  59660. )
  59661. );
  59662. }
  59663. /**
  59664. * A test ended.
  59665. *
  59666. * @param PHPUnit_Framework_Test $test
  59667. * @param float $time
  59668. */
  59669. public function endTest(PHPUnit_Framework_Test $test, $time)
  59670. {
  59671. if ($this->currentTestPass) {
  59672. $this->writeCase('pass', $time, array(), '', $test);
  59673. }
  59674. }
  59675. /**
  59676. * @param string $status
  59677. * @param float $time
  59678. * @param array $trace
  59679. * @param string $message
  59680. * @param PHPUnit_Framework_TestCase|null $test
  59681. */
  59682. protected function writeCase($status, $time, array $trace = array(), $message = '', $test = null)
  59683. {
  59684. $output = '';
  59685. // take care of TestSuite producing error (e.g. by running into exception) as TestSuite doesn't have hasOutput
  59686. if ($test !== null && method_exists($test, 'hasOutput') && $test->hasOutput()) {
  59687. $output = $test->getActualOutput();
  59688. }
  59689. $this->write(
  59690. array(
  59691. 'event' => 'test',
  59692. 'suite' => $this->currentTestSuiteName,
  59693. 'test' => $this->currentTestName,
  59694. 'status' => $status,
  59695. 'time' => $time,
  59696. 'trace' => $trace,
  59697. 'message' => PHPUnit_Util_String::convertToUtf8($message),
  59698. 'output' => $output,
  59699. )
  59700. );
  59701. }
  59702. /**
  59703. * @param string $buffer
  59704. */
  59705. public function write($buffer)
  59706. {
  59707. array_walk_recursive($buffer, function (&$input) {
  59708. if (is_string($input)) {
  59709. $input = PHPUnit_Util_String::convertToUtf8($input);
  59710. }
  59711. });
  59712. parent::write(json_encode($buffer, JSON_PRETTY_PRINT));
  59713. }
  59714. }
  59715. <?php
  59716. /*
  59717. * This file is part of PHPUnit.
  59718. *
  59719. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59720. *
  59721. * For the full copyright and license information, please view the LICENSE
  59722. * file that was distributed with this source code.
  59723. */
  59724. /**
  59725. * A TestListener that generates a logfile of the
  59726. * test execution using the Test Anything Protocol (TAP).
  59727. *
  59728. * @package PHPUnit
  59729. * @subpackage Util_Log
  59730. * @author Sebastian Bergmann <sebastian@phpunit.de>
  59731. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  59732. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  59733. * @link http://www.phpunit.de/
  59734. * @since Class available since Release 3.0.0
  59735. */
  59736. class PHPUnit_Util_Log_TAP extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
  59737. {
  59738. /**
  59739. * @var integer
  59740. */
  59741. protected $testNumber = 0;
  59742. /**
  59743. * @var integer
  59744. */
  59745. protected $testSuiteLevel = 0;
  59746. /**
  59747. * @var boolean
  59748. */
  59749. protected $testSuccessful = true;
  59750. /**
  59751. * Constructor.
  59752. *
  59753. * @param mixed $out
  59754. * @throws PHPUnit_Framework_Exception
  59755. * @since Method available since Release 3.3.4
  59756. */
  59757. public function __construct($out = null)
  59758. {
  59759. parent::__construct($out);
  59760. $this->write("TAP version 13\n");
  59761. }
  59762. /**
  59763. * An error occurred.
  59764. *
  59765. * @param PHPUnit_Framework_Test $test
  59766. * @param Exception $e
  59767. * @param float $time
  59768. */
  59769. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  59770. {
  59771. $this->writeNotOk($test, 'Error');
  59772. }
  59773. /**
  59774. * A failure occurred.
  59775. *
  59776. * @param PHPUnit_Framework_Test $test
  59777. * @param PHPUnit_Framework_AssertionFailedError $e
  59778. * @param float $time
  59779. */
  59780. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  59781. {
  59782. $this->writeNotOk($test, 'Failure');
  59783. $message = explode(
  59784. "\n",
  59785. PHPUnit_Framework_TestFailure::exceptionToString($e)
  59786. );
  59787. $diagnostic = array(
  59788. 'message' => $message[0],
  59789. 'severity' => 'fail'
  59790. );
  59791. if ($e instanceof PHPUnit_Framework_ExpectationFailedException) {
  59792. $cf = $e->getComparisonFailure();
  59793. if ($cf !== null) {
  59794. $diagnostic['data'] = array(
  59795. 'got' => $cf->getActual(),
  59796. 'expected' => $cf->getExpected()
  59797. );
  59798. }
  59799. }
  59800. $yaml = new Symfony\Component\Yaml\Dumper;
  59801. $this->write(
  59802. sprintf(
  59803. " ---\n%s ...\n",
  59804. $yaml->dump($diagnostic, 2, 2)
  59805. )
  59806. );
  59807. }
  59808. /**
  59809. * Incomplete test.
  59810. *
  59811. * @param PHPUnit_Framework_Test $test
  59812. * @param Exception $e
  59813. * @param float $time
  59814. */
  59815. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59816. {
  59817. $this->writeNotOk($test, '', 'TODO Incomplete Test');
  59818. }
  59819. /**
  59820. * Risky test.
  59821. *
  59822. * @param PHPUnit_Framework_Test $test
  59823. * @param Exception $e
  59824. * @param float $time
  59825. * @since Method available since Release 4.0.0
  59826. */
  59827. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59828. {
  59829. $this->write(
  59830. sprintf(
  59831. "ok %d - # RISKY%s\n",
  59832. $this->testNumber,
  59833. $e->getMessage() != '' ? ' ' . $e->getMessage() : ''
  59834. )
  59835. );
  59836. $this->testSuccessful = false;
  59837. }
  59838. /**
  59839. * Skipped test.
  59840. *
  59841. * @param PHPUnit_Framework_Test $test
  59842. * @param Exception $e
  59843. * @param float $time
  59844. * @since Method available since Release 3.0.0
  59845. */
  59846. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59847. {
  59848. $this->write(
  59849. sprintf(
  59850. "ok %d - # SKIP%s\n",
  59851. $this->testNumber,
  59852. $e->getMessage() != '' ? ' ' . $e->getMessage() : ''
  59853. )
  59854. );
  59855. $this->testSuccessful = false;
  59856. }
  59857. /**
  59858. * A testsuite started.
  59859. *
  59860. * @param PHPUnit_Framework_TestSuite $suite
  59861. */
  59862. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  59863. {
  59864. $this->testSuiteLevel++;
  59865. }
  59866. /**
  59867. * A testsuite ended.
  59868. *
  59869. * @param PHPUnit_Framework_TestSuite $suite
  59870. */
  59871. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  59872. {
  59873. $this->testSuiteLevel--;
  59874. if ($this->testSuiteLevel == 0) {
  59875. $this->write(sprintf("1..%d\n", $this->testNumber));
  59876. }
  59877. }
  59878. /**
  59879. * A test started.
  59880. *
  59881. * @param PHPUnit_Framework_Test $test
  59882. */
  59883. public function startTest(PHPUnit_Framework_Test $test)
  59884. {
  59885. $this->testNumber++;
  59886. $this->testSuccessful = true;
  59887. }
  59888. /**
  59889. * A test ended.
  59890. *
  59891. * @param PHPUnit_Framework_Test $test
  59892. * @param float $time
  59893. */
  59894. public function endTest(PHPUnit_Framework_Test $test, $time)
  59895. {
  59896. if ($this->testSuccessful === true) {
  59897. $this->write(
  59898. sprintf(
  59899. "ok %d - %s\n",
  59900. $this->testNumber,
  59901. PHPUnit_Util_Test::describe($test)
  59902. )
  59903. );
  59904. }
  59905. }
  59906. /**
  59907. * @param PHPUnit_Framework_Test $test
  59908. * @param string $prefix
  59909. * @param string $directive
  59910. */
  59911. protected function writeNotOk(PHPUnit_Framework_Test $test, $prefix = '', $directive = '')
  59912. {
  59913. $this->write(
  59914. sprintf(
  59915. "not ok %d - %s%s%s\n",
  59916. $this->testNumber,
  59917. $prefix != '' ? $prefix . ': ' : '',
  59918. PHPUnit_Util_Test::describe($test),
  59919. $directive != '' ? ' # ' . $directive : ''
  59920. )
  59921. );
  59922. $this->testSuccessful = false;
  59923. }
  59924. }
  59925. <?php
  59926. /*
  59927. * This file is part of PHPUnit.
  59928. *
  59929. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59930. *
  59931. * For the full copyright and license information, please view the LICENSE
  59932. * file that was distributed with this source code.
  59933. */
  59934. /**
  59935. * A TestListener that generates a logfile of the test execution in XML markup.
  59936. *
  59937. * The XML markup used is the same as the one that is used by the JUnit Ant task.
  59938. *
  59939. * @package PHPUnit
  59940. * @subpackage Util_Log
  59941. * @author Sebastian Bergmann <sebastian@phpunit.de>
  59942. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  59943. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  59944. * @link http://www.phpunit.de/
  59945. * @since Class available since Release 2.1.0
  59946. */
  59947. class PHPUnit_Util_Log_JUnit extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
  59948. {
  59949. /**
  59950. * @var DOMDocument
  59951. */
  59952. protected $document;
  59953. /**
  59954. * @var DOMElement
  59955. */
  59956. protected $root;
  59957. /**
  59958. * @var boolean
  59959. */
  59960. protected $logIncompleteSkipped = false;
  59961. /**
  59962. * @var boolean
  59963. */
  59964. protected $writeDocument = true;
  59965. /**
  59966. * @var DOMElement[]
  59967. */
  59968. protected $testSuites = array();
  59969. /**
  59970. * @var integer[]
  59971. */
  59972. protected $testSuiteTests = array(0);
  59973. /**
  59974. * @var integer[]
  59975. */
  59976. protected $testSuiteAssertions = array(0);
  59977. /**
  59978. * @var integer[]
  59979. */
  59980. protected $testSuiteErrors = array(0);
  59981. /**
  59982. * @var integer[]
  59983. */
  59984. protected $testSuiteFailures = array(0);
  59985. /**
  59986. * @var integer[]
  59987. */
  59988. protected $testSuiteTimes = array(0);
  59989. /**
  59990. * @var integer
  59991. */
  59992. protected $testSuiteLevel = 0;
  59993. /**
  59994. * @var DOMElement
  59995. */
  59996. protected $currentTestCase = null;
  59997. /**
  59998. * @var boolean
  59999. */
  60000. protected $attachCurrentTestCase = true;
  60001. /**
  60002. * Constructor.
  60003. *
  60004. * @param mixed $out
  60005. * @param boolean $logIncompleteSkipped
  60006. */
  60007. public function __construct($out = null, $logIncompleteSkipped = false)
  60008. {
  60009. $this->document = new DOMDocument('1.0', 'UTF-8');
  60010. $this->document->formatOutput = true;
  60011. $this->root = $this->document->createElement('testsuites');
  60012. $this->document->appendChild($this->root);
  60013. parent::__construct($out);
  60014. $this->logIncompleteSkipped = $logIncompleteSkipped;
  60015. }
  60016. /**
  60017. * Flush buffer and close output.
  60018. *
  60019. */
  60020. public function flush()
  60021. {
  60022. if ($this->writeDocument === true) {
  60023. $this->write($this->getXML());
  60024. }
  60025. parent::flush();
  60026. }
  60027. /**
  60028. * An error occurred.
  60029. *
  60030. * @param PHPUnit_Framework_Test $test
  60031. * @param Exception $e
  60032. * @param float $time
  60033. */
  60034. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  60035. {
  60036. if ($this->currentTestCase !== null) {
  60037. if ($test instanceof PHPUnit_Framework_SelfDescribing) {
  60038. $buffer = $test->toString() . "\n";
  60039. } else {
  60040. $buffer = '';
  60041. }
  60042. $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) .
  60043. "\n" .
  60044. PHPUnit_Util_Filter::getFilteredStacktrace($e);
  60045. $error = $this->document->createElement(
  60046. 'error',
  60047. PHPUnit_Util_XML::prepareString($buffer)
  60048. );
  60049. $error->setAttribute('type', get_class($e));
  60050. $this->currentTestCase->appendChild($error);
  60051. $this->testSuiteErrors[$this->testSuiteLevel]++;
  60052. }
  60053. }
  60054. /**
  60055. * A failure occurred.
  60056. *
  60057. * @param PHPUnit_Framework_Test $test
  60058. * @param PHPUnit_Framework_AssertionFailedError $e
  60059. * @param float $time
  60060. */
  60061. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  60062. {
  60063. if ($this->currentTestCase !== null) {
  60064. if (!$test instanceof PHPUnit_Framework_Warning) {
  60065. if ($test instanceof PHPUnit_Framework_SelfDescribing) {
  60066. $buffer = $test->toString() . "\n";
  60067. } else {
  60068. $buffer = '';
  60069. }
  60070. $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) .
  60071. "\n" .
  60072. PHPUnit_Util_Filter::getFilteredStacktrace($e);
  60073. $failure = $this->document->createElement(
  60074. 'failure',
  60075. PHPUnit_Util_XML::prepareString($buffer)
  60076. );
  60077. $failure->setAttribute('type', get_class($e));
  60078. $this->currentTestCase->appendChild($failure);
  60079. $this->testSuiteFailures[$this->testSuiteLevel]++;
  60080. }
  60081. }
  60082. }
  60083. /**
  60084. * Incomplete test.
  60085. *
  60086. * @param PHPUnit_Framework_Test $test
  60087. * @param Exception $e
  60088. * @param float $time
  60089. */
  60090. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  60091. {
  60092. if ($this->logIncompleteSkipped && $this->currentTestCase !== null) {
  60093. $error = $this->document->createElement(
  60094. 'error',
  60095. PHPUnit_Util_XML::prepareString(
  60096. "Incomplete Test\n" .
  60097. PHPUnit_Util_Filter::getFilteredStacktrace($e)
  60098. )
  60099. );
  60100. $error->setAttribute('type', get_class($e));
  60101. $this->currentTestCase->appendChild($error);
  60102. $this->testSuiteErrors[$this->testSuiteLevel]++;
  60103. } else {
  60104. $this->attachCurrentTestCase = false;
  60105. }
  60106. }
  60107. /**
  60108. * Risky test.
  60109. *
  60110. * @param PHPUnit_Framework_Test $test
  60111. * @param Exception $e
  60112. * @param float $time
  60113. * @since Method available since Release 4.0.0
  60114. */
  60115. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  60116. {
  60117. if ($this->logIncompleteSkipped && $this->currentTestCase !== null) {
  60118. $error = $this->document->createElement(
  60119. 'error',
  60120. PHPUnit_Util_XML::prepareString(
  60121. "Risky Test\n" .
  60122. PHPUnit_Util_Filter::getFilteredStacktrace($e)
  60123. )
  60124. );
  60125. $error->setAttribute('type', get_class($e));
  60126. $this->currentTestCase->appendChild($error);
  60127. $this->testSuiteErrors[$this->testSuiteLevel]++;
  60128. } else {
  60129. $this->attachCurrentTestCase = false;
  60130. }
  60131. }
  60132. /**
  60133. * Skipped test.
  60134. *
  60135. * @param PHPUnit_Framework_Test $test
  60136. * @param Exception $e
  60137. * @param float $time
  60138. * @since Method available since Release 3.0.0
  60139. */
  60140. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  60141. {
  60142. if ($this->logIncompleteSkipped && $this->currentTestCase !== null) {
  60143. $error = $this->document->createElement(
  60144. 'error',
  60145. PHPUnit_Util_XML::prepareString(
  60146. "Skipped Test\n" .
  60147. PHPUnit_Util_Filter::getFilteredStacktrace($e)
  60148. )
  60149. );
  60150. $error->setAttribute('type', get_class($e));
  60151. $this->currentTestCase->appendChild($error);
  60152. $this->testSuiteErrors[$this->testSuiteLevel]++;
  60153. } else {
  60154. $this->attachCurrentTestCase = false;
  60155. }
  60156. }
  60157. /**
  60158. * A testsuite started.
  60159. *
  60160. * @param PHPUnit_Framework_TestSuite $suite
  60161. * @since Method available since Release 2.2.0
  60162. */
  60163. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  60164. {
  60165. $testSuite = $this->document->createElement('testsuite');
  60166. $testSuite->setAttribute('name', $suite->getName());
  60167. if (class_exists($suite->getName(), false)) {
  60168. try {
  60169. $class = new ReflectionClass($suite->getName());
  60170. $testSuite->setAttribute('file', $class->getFileName());
  60171. } catch (ReflectionException $e) {
  60172. }
  60173. }
  60174. if ($this->testSuiteLevel > 0) {
  60175. $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite);
  60176. } else {
  60177. $this->root->appendChild($testSuite);
  60178. }
  60179. $this->testSuiteLevel++;
  60180. $this->testSuites[$this->testSuiteLevel] = $testSuite;
  60181. $this->testSuiteTests[$this->testSuiteLevel] = 0;
  60182. $this->testSuiteAssertions[$this->testSuiteLevel] = 0;
  60183. $this->testSuiteErrors[$this->testSuiteLevel] = 0;
  60184. $this->testSuiteFailures[$this->testSuiteLevel] = 0;
  60185. $this->testSuiteTimes[$this->testSuiteLevel] = 0;
  60186. }
  60187. /**
  60188. * A testsuite ended.
  60189. *
  60190. * @param PHPUnit_Framework_TestSuite $suite
  60191. * @since Method available since Release 2.2.0
  60192. */
  60193. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  60194. {
  60195. $this->testSuites[$this->testSuiteLevel]->setAttribute(
  60196. 'tests',
  60197. $this->testSuiteTests[$this->testSuiteLevel]
  60198. );
  60199. $this->testSuites[$this->testSuiteLevel]->setAttribute(
  60200. 'assertions',
  60201. $this->testSuiteAssertions[$this->testSuiteLevel]
  60202. );
  60203. $this->testSuites[$this->testSuiteLevel]->setAttribute(
  60204. 'failures',
  60205. $this->testSuiteFailures[$this->testSuiteLevel]
  60206. );
  60207. $this->testSuites[$this->testSuiteLevel]->setAttribute(
  60208. 'errors',
  60209. $this->testSuiteErrors[$this->testSuiteLevel]
  60210. );
  60211. $this->testSuites[$this->testSuiteLevel]->setAttribute(
  60212. 'time',
  60213. sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel])
  60214. );
  60215. if ($this->testSuiteLevel > 1) {
  60216. $this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel];
  60217. $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel];
  60218. $this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel];
  60219. $this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel];
  60220. $this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel];
  60221. }
  60222. $this->testSuiteLevel--;
  60223. }
  60224. /**
  60225. * A test started.
  60226. *
  60227. * @param PHPUnit_Framework_Test $test
  60228. */
  60229. public function startTest(PHPUnit_Framework_Test $test)
  60230. {
  60231. if (!$test instanceof PHPUnit_Framework_Warning) {
  60232. $testCase = $this->document->createElement('testcase');
  60233. $testCase->setAttribute('name', $test->getName());
  60234. if ($test instanceof PHPUnit_Framework_TestCase) {
  60235. $class = new ReflectionClass($test);
  60236. $methodName = $test->getName();
  60237. if ($class->hasMethod($methodName)) {
  60238. $method = $class->getMethod($test->getName());
  60239. $testCase->setAttribute('class', $class->getName());
  60240. $testCase->setAttribute('file', $class->getFileName());
  60241. $testCase->setAttribute('line', $method->getStartLine());
  60242. }
  60243. }
  60244. $this->currentTestCase = $testCase;
  60245. }
  60246. }
  60247. /**
  60248. * A test ended.
  60249. *
  60250. * @param PHPUnit_Framework_Test $test
  60251. * @param float $time
  60252. */
  60253. public function endTest(PHPUnit_Framework_Test $test, $time)
  60254. {
  60255. if (!$test instanceof PHPUnit_Framework_Warning) {
  60256. if ($this->attachCurrentTestCase) {
  60257. if ($test instanceof PHPUnit_Framework_TestCase) {
  60258. $numAssertions = $test->getNumAssertions();
  60259. $this->testSuiteAssertions[$this->testSuiteLevel] += $numAssertions;
  60260. $this->currentTestCase->setAttribute(
  60261. 'assertions',
  60262. $numAssertions
  60263. );
  60264. }
  60265. $this->currentTestCase->setAttribute(
  60266. 'time',
  60267. sprintf('%F', $time)
  60268. );
  60269. $this->testSuites[$this->testSuiteLevel]->appendChild(
  60270. $this->currentTestCase
  60271. );
  60272. $this->testSuiteTests[$this->testSuiteLevel]++;
  60273. $this->testSuiteTimes[$this->testSuiteLevel] += $time;
  60274. if (method_exists($test, 'hasOutput') && $test->hasOutput()) {
  60275. $systemOut = $this->document->createElement('system-out');
  60276. $systemOut->appendChild(
  60277. $this->document->createTextNode($test->getActualOutput())
  60278. );
  60279. $this->currentTestCase->appendChild($systemOut);
  60280. }
  60281. }
  60282. }
  60283. $this->attachCurrentTestCase = true;
  60284. $this->currentTestCase = null;
  60285. }
  60286. /**
  60287. * Returns the XML as a string.
  60288. *
  60289. * @return string
  60290. * @since Method available since Release 2.2.0
  60291. */
  60292. public function getXML()
  60293. {
  60294. return $this->document->saveXML();
  60295. }
  60296. /**
  60297. * Enables or disables the writing of the document
  60298. * in flush().
  60299. *
  60300. * This is a "hack" needed for the integration of
  60301. * PHPUnit with Phing.
  60302. *
  60303. * @return string
  60304. * @since Method available since Release 2.2.0
  60305. */
  60306. public function setWriteDocument($flag)
  60307. {
  60308. if (is_bool($flag)) {
  60309. $this->writeDocument = $flag;
  60310. }
  60311. }
  60312. }
  60313. <?php
  60314. /*
  60315. * This file is part of PHPUnit.
  60316. *
  60317. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60318. *
  60319. * For the full copyright and license information, please view the LICENSE
  60320. * file that was distributed with this source code.
  60321. */
  60322. /**
  60323. * Utility class for blacklisting PHPUnit's own source code files.
  60324. *
  60325. * @package PHPUnit
  60326. * @subpackage Util
  60327. * @author Sebastian Bergmann <sebastian@phpunit.de>
  60328. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  60329. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  60330. * @link http://www.phpunit.de/
  60331. * @since Class available since Release 4.0.0
  60332. */
  60333. class PHPUnit_Util_Blacklist
  60334. {
  60335. /**
  60336. * @var array
  60337. */
  60338. public static $blacklistedClassNames = array(
  60339. 'File_Iterator' => 1,
  60340. 'PHP_CodeCoverage' => 1,
  60341. 'PHP_Invoker' => 1,
  60342. 'PHP_Timer' => 1,
  60343. 'PHP_Token' => 1,
  60344. 'PHPUnit_Framework_TestCase' => 2,
  60345. 'PHPUnit_Extensions_Database_TestCase' => 2,
  60346. 'PHPUnit_Framework_MockObject_Generator' => 2,
  60347. 'PHPUnit_Extensions_SeleniumTestCase' => 2,
  60348. 'PHPUnit_Extensions_Story_TestCase' => 2,
  60349. 'Text_Template' => 1,
  60350. 'Symfony\Component\Yaml\Yaml' => 1,
  60351. 'SebastianBergmann\Diff\Diff' => 1,
  60352. 'SebastianBergmann\Environment\Runtime' => 1,
  60353. 'SebastianBergmann\Comparator\Comparator' => 1,
  60354. 'SebastianBergmann\Exporter\Exporter' => 1,
  60355. 'SebastianBergmann\GlobalState\Snapshot' => 1,
  60356. 'SebastianBergmann\RecursionContext\Context' => 1,
  60357. 'SebastianBergmann\Version' => 1,
  60358. 'Composer\Autoload\ClassLoader' => 1,
  60359. 'Doctrine\Instantiator\Instantiator' => 1,
  60360. 'phpDocumentor\Reflection\DocBlock' => 1,
  60361. 'Prophecy\Prophet' => 1
  60362. );
  60363. /**
  60364. * @var array
  60365. */
  60366. private static $directories;
  60367. /**
  60368. * @return array
  60369. * @since Method available since Release 4.1.0
  60370. */
  60371. public function getBlacklistedDirectories()
  60372. {
  60373. $this->initialize();
  60374. return self::$directories;
  60375. }
  60376. /**
  60377. * @param string $file
  60378. * @return boolean
  60379. */
  60380. public function isBlacklisted($file)
  60381. {
  60382. if (defined('PHPUNIT_TESTSUITE')) {
  60383. return false;
  60384. }
  60385. $this->initialize();
  60386. foreach (self::$directories as $directory) {
  60387. if (strpos($file, $directory) === 0) {
  60388. return true;
  60389. }
  60390. }
  60391. return false;
  60392. }
  60393. private function initialize()
  60394. {
  60395. if (self::$directories === null) {
  60396. self::$directories = array();
  60397. foreach (self::$blacklistedClassNames as $className => $parent) {
  60398. if (!class_exists($className)) {
  60399. continue;
  60400. }
  60401. $reflector = new ReflectionClass($className);
  60402. $directory = $reflector->getFileName();
  60403. for ($i = 0; $i < $parent; $i++) {
  60404. $directory = dirname($directory);
  60405. }
  60406. self::$directories[] = $directory;
  60407. }
  60408. // Hide process isolation workaround on Windows.
  60409. // @see PHPUnit_Util_PHP::factory()
  60410. // @see PHPUnit_Util_PHP_Windows::process()
  60411. if (DIRECTORY_SEPARATOR === '\\') {
  60412. // tempnam() prefix is limited to first 3 chars.
  60413. // @see http://php.net/manual/en/function.tempnam.php
  60414. self::$directories[] = sys_get_temp_dir() . '\\PHP';
  60415. }
  60416. }
  60417. }
  60418. }
  60419. <?php
  60420. /*
  60421. * This file is part of PHPUnit.
  60422. *
  60423. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60424. *
  60425. * For the full copyright and license information, please view the LICENSE
  60426. * file that was distributed with this source code.
  60427. */
  60428. /**
  60429. * Iterator for test suites.
  60430. *
  60431. * @package PHPUnit
  60432. * @subpackage Util
  60433. * @author Sebastian Bergmann <sebastian@phpunit.de>
  60434. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  60435. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  60436. * @link http://www.phpunit.de/
  60437. * @since Class available since Release 3.1.0
  60438. */
  60439. class PHPUnit_Util_TestSuiteIterator implements RecursiveIterator
  60440. {
  60441. /**
  60442. * @var integer
  60443. */
  60444. protected $position;
  60445. /**
  60446. * @var PHPUnit_Framework_Test[]
  60447. */
  60448. protected $tests;
  60449. /**
  60450. * @param PHPUnit_Framework_TestSuite $testSuite
  60451. */
  60452. public function __construct(PHPUnit_Framework_TestSuite $testSuite)
  60453. {
  60454. $this->tests = $testSuite->tests();
  60455. }
  60456. /**
  60457. * Rewinds the Iterator to the first element.
  60458. *
  60459. */
  60460. public function rewind()
  60461. {
  60462. $this->position = 0;
  60463. }
  60464. /**
  60465. * Checks if there is a current element after calls to rewind() or next().
  60466. *
  60467. * @return boolean
  60468. */
  60469. public function valid()
  60470. {
  60471. return $this->position < count($this->tests);
  60472. }
  60473. /**
  60474. * Returns the key of the current element.
  60475. *
  60476. * @return integer
  60477. */
  60478. public function key()
  60479. {
  60480. return $this->position;
  60481. }
  60482. /**
  60483. * Returns the current element.
  60484. *
  60485. * @return PHPUnit_Framework_Test
  60486. */
  60487. public function current()
  60488. {
  60489. return $this->valid() ? $this->tests[$this->position] : null;
  60490. }
  60491. /**
  60492. * Moves forward to next element.
  60493. *
  60494. */
  60495. public function next()
  60496. {
  60497. $this->position++;
  60498. }
  60499. /**
  60500. * Returns the sub iterator for the current element.
  60501. *
  60502. * @return PHPUnit_Util_TestSuiteIterator
  60503. */
  60504. public function getChildren()
  60505. {
  60506. return new PHPUnit_Util_TestSuiteIterator(
  60507. $this->tests[$this->position]
  60508. );
  60509. }
  60510. /**
  60511. * Checks whether the current element has children.
  60512. *
  60513. * @return boolean
  60514. */
  60515. public function hasChildren()
  60516. {
  60517. return $this->tests[$this->position] instanceof PHPUnit_Framework_TestSuite;
  60518. }
  60519. }
  60520. <?php
  60521. /*
  60522. * This file is part of PHPUnit.
  60523. *
  60524. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60525. *
  60526. * For the full copyright and license information, please view the LICENSE
  60527. * file that was distributed with this source code.
  60528. */
  60529. /**
  60530. * Utility class for code filtering.
  60531. *
  60532. * @package PHPUnit
  60533. * @subpackage Util
  60534. * @author Sebastian Bergmann <sebastian@phpunit.de>
  60535. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  60536. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  60537. * @link http://www.phpunit.de/
  60538. * @since Class available since Release 2.0.0
  60539. */
  60540. class PHPUnit_Util_Filter
  60541. {
  60542. /**
  60543. * Filters stack frames from PHPUnit classes.
  60544. *
  60545. * @param Exception $e
  60546. * @param boolean $asString
  60547. * @return string
  60548. */
  60549. public static function getFilteredStacktrace(Exception $e, $asString = true)
  60550. {
  60551. $prefix = false;
  60552. $script = realpath($GLOBALS['_SERVER']['SCRIPT_NAME']);
  60553. if (defined('__PHPUNIT_PHAR_ROOT__')) {
  60554. $prefix = __PHPUNIT_PHAR_ROOT__;
  60555. }
  60556. if ($asString === true) {
  60557. $filteredStacktrace = '';
  60558. } else {
  60559. $filteredStacktrace = array();
  60560. }
  60561. if ($e instanceof PHPUnit_Framework_SyntheticError) {
  60562. $eTrace = $e->getSyntheticTrace();
  60563. $eFile = $e->getSyntheticFile();
  60564. $eLine = $e->getSyntheticLine();
  60565. } elseif ($e instanceof PHPUnit_Framework_Exception) {
  60566. $eTrace = $e->getSerializableTrace();
  60567. $eFile = $e->getFile();
  60568. $eLine = $e->getLine();
  60569. } else {
  60570. if ($e->getPrevious()) {
  60571. $e = $e->getPrevious();
  60572. }
  60573. $eTrace = $e->getTrace();
  60574. $eFile = $e->getFile();
  60575. $eLine = $e->getLine();
  60576. }
  60577. if (!self::frameExists($eTrace, $eFile, $eLine)) {
  60578. array_unshift(
  60579. $eTrace,
  60580. array('file' => $eFile, 'line' => $eLine)
  60581. );
  60582. }
  60583. $blacklist = new PHPUnit_Util_Blacklist;
  60584. foreach ($eTrace as $frame) {
  60585. if (isset($frame['file']) && is_file($frame['file']) &&
  60586. !$blacklist->isBlacklisted($frame['file']) &&
  60587. ($prefix === false || strpos($frame['file'], $prefix) !== 0) &&
  60588. $frame['file'] !== $script) {
  60589. if ($asString === true) {
  60590. $filteredStacktrace .= sprintf(
  60591. "%s:%s\n",
  60592. $frame['file'],
  60593. isset($frame['line']) ? $frame['line'] : '?'
  60594. );
  60595. } else {
  60596. $filteredStacktrace[] = $frame;
  60597. }
  60598. }
  60599. }
  60600. return $filteredStacktrace;
  60601. }
  60602. /**
  60603. * @param array $trace
  60604. * @param string $file
  60605. * @param int $line
  60606. * @return boolean
  60607. * @since Method available since Release 3.3.2
  60608. */
  60609. private static function frameExists(array $trace, $file, $line)
  60610. {
  60611. foreach ($trace as $frame) {
  60612. if (isset($frame['file']) && $frame['file'] == $file &&
  60613. isset($frame['line']) && $frame['line'] == $line) {
  60614. return true;
  60615. }
  60616. }
  60617. return false;
  60618. }
  60619. }
  60620. <?php
  60621. /*
  60622. * This file is part of PHPUnit.
  60623. *
  60624. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60625. *
  60626. * For the full copyright and license information, please view the LICENSE
  60627. * file that was distributed with this source code.
  60628. */
  60629. /**
  60630. * Prints TestDox documentation in HTML format.
  60631. *
  60632. * @package PHPUnit
  60633. * @subpackage Util_TestDox
  60634. * @author Sebastian Bergmann <sebastian@phpunit.de>
  60635. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  60636. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  60637. * @link http://www.phpunit.de/
  60638. * @since Class available since Release 2.1.0
  60639. */
  60640. class PHPUnit_Util_TestDox_ResultPrinter_HTML extends PHPUnit_Util_TestDox_ResultPrinter
  60641. {
  60642. /**
  60643. * @var boolean
  60644. */
  60645. protected $printsHTML = true;
  60646. /**
  60647. * Handler for 'start run' event.
  60648. *
  60649. */
  60650. protected function startRun()
  60651. {
  60652. $this->write('<html><body>');
  60653. }
  60654. /**
  60655. * Handler for 'start class' event.
  60656. *
  60657. * @param string $name
  60658. */
  60659. protected function startClass($name)
  60660. {
  60661. $this->write(
  60662. '<h2 id="' . $name . '">' . $this->currentTestClassPrettified .
  60663. '</h2><ul>'
  60664. );
  60665. }
  60666. /**
  60667. * Handler for 'on test' event.
  60668. *
  60669. * @param string $name
  60670. * @param boolean $success
  60671. */
  60672. protected function onTest($name, $success = true)
  60673. {
  60674. if (!$success) {
  60675. $strikeOpen = '<span style="text-decoration:line-through;">';
  60676. $strikeClose = '</span>';
  60677. } else {
  60678. $strikeOpen = '';
  60679. $strikeClose = '';
  60680. }
  60681. $this->write('<li>' . $strikeOpen . $name . $strikeClose . '</li>');
  60682. }
  60683. /**
  60684. * Handler for 'end class' event.
  60685. *
  60686. * @param string $name
  60687. */
  60688. protected function endClass($name)
  60689. {
  60690. $this->write('</ul>');
  60691. }
  60692. /**
  60693. * Handler for 'end run' event.
  60694. *
  60695. */
  60696. protected function endRun()
  60697. {
  60698. $this->write('</body></html>');
  60699. }
  60700. }
  60701. <?php
  60702. /*
  60703. * This file is part of PHPUnit.
  60704. *
  60705. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60706. *
  60707. * For the full copyright and license information, please view the LICENSE
  60708. * file that was distributed with this source code.
  60709. */
  60710. /**
  60711. * Prints TestDox documentation in text format.
  60712. *
  60713. * @package PHPUnit
  60714. * @subpackage Util_TestDox
  60715. * @author Sebastian Bergmann <sebastian@phpunit.de>
  60716. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  60717. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  60718. * @link http://www.phpunit.de/
  60719. * @since Class available since Release 2.1.0
  60720. */
  60721. class PHPUnit_Util_TestDox_ResultPrinter_Text extends PHPUnit_Util_TestDox_ResultPrinter
  60722. {
  60723. /**
  60724. * Handler for 'start class' event.
  60725. *
  60726. * @param string $name
  60727. */
  60728. protected function startClass($name)
  60729. {
  60730. $this->write($this->currentTestClassPrettified . "\n");
  60731. }
  60732. /**
  60733. * Handler for 'on test' event.
  60734. *
  60735. * @param string $name
  60736. * @param boolean $success
  60737. */
  60738. protected function onTest($name, $success = true)
  60739. {
  60740. if ($success) {
  60741. $this->write(' [x] ');
  60742. } else {
  60743. $this->write(' [ ] ');
  60744. }
  60745. $this->write($name . "\n");
  60746. }
  60747. /**
  60748. * Handler for 'end class' event.
  60749. *
  60750. * @param string $name
  60751. */
  60752. protected function endClass($name)
  60753. {
  60754. $this->write("\n");
  60755. }
  60756. }
  60757. <?php
  60758. /*
  60759. * This file is part of PHPUnit.
  60760. *
  60761. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60762. *
  60763. * For the full copyright and license information, please view the LICENSE
  60764. * file that was distributed with this source code.
  60765. */
  60766. /**
  60767. * Base class for printers of TestDox documentation.
  60768. *
  60769. * @package PHPUnit
  60770. * @subpackage Util_TestDox
  60771. * @author Sebastian Bergmann <sebastian@phpunit.de>
  60772. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  60773. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  60774. * @link http://www.phpunit.de/
  60775. * @since Class available since Release 2.1.0
  60776. */
  60777. abstract class PHPUnit_Util_TestDox_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
  60778. {
  60779. /**
  60780. * @var PHPUnit_Util_TestDox_NamePrettifier
  60781. */
  60782. protected $prettifier;
  60783. /**
  60784. * @var string
  60785. */
  60786. protected $testClass = '';
  60787. /**
  60788. * @var integer
  60789. */
  60790. protected $testStatus = false;
  60791. /**
  60792. * @var array
  60793. */
  60794. protected $tests = array();
  60795. /**
  60796. * @var integer
  60797. */
  60798. protected $successful = 0;
  60799. /**
  60800. * @var integer
  60801. */
  60802. protected $failed = 0;
  60803. /**
  60804. * @var integer
  60805. */
  60806. protected $risky = 0;
  60807. /**
  60808. * @var integer
  60809. */
  60810. protected $skipped = 0;
  60811. /**
  60812. * @var integer
  60813. */
  60814. protected $incomplete = 0;
  60815. /**
  60816. * @var string
  60817. */
  60818. protected $currentTestClassPrettified;
  60819. /**
  60820. * @var string
  60821. */
  60822. protected $currentTestMethodPrettified;
  60823. /**
  60824. * Constructor.
  60825. *
  60826. * @param resource $out
  60827. */
  60828. public function __construct($out = null)
  60829. {
  60830. parent::__construct($out);
  60831. $this->prettifier = new PHPUnit_Util_TestDox_NamePrettifier;
  60832. $this->startRun();
  60833. }
  60834. /**
  60835. * Flush buffer and close output.
  60836. *
  60837. */
  60838. public function flush()
  60839. {
  60840. $this->doEndClass();
  60841. $this->endRun();
  60842. parent::flush();
  60843. }
  60844. /**
  60845. * An error occurred.
  60846. *
  60847. * @param PHPUnit_Framework_Test $test
  60848. * @param Exception $e
  60849. * @param float $time
  60850. */
  60851. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  60852. {
  60853. if (!$this->isOfInterest($test)) {
  60854. return;
  60855. }
  60856. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
  60857. $this->failed++;
  60858. }
  60859. /**
  60860. * A failure occurred.
  60861. *
  60862. * @param PHPUnit_Framework_Test $test
  60863. * @param PHPUnit_Framework_AssertionFailedError $e
  60864. * @param float $time
  60865. */
  60866. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  60867. {
  60868. if (!$this->isOfInterest($test)) {
  60869. return;
  60870. }
  60871. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
  60872. $this->failed++;
  60873. }
  60874. /**
  60875. * Incomplete test.
  60876. *
  60877. * @param PHPUnit_Framework_Test $test
  60878. * @param Exception $e
  60879. * @param float $time
  60880. */
  60881. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  60882. {
  60883. if (!$this->isOfInterest($test)) {
  60884. return;
  60885. }
  60886. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE;
  60887. $this->incomplete++;
  60888. }
  60889. /**
  60890. * Risky test.
  60891. *
  60892. * @param PHPUnit_Framework_Test $test
  60893. * @param Exception $e
  60894. * @param float $time
  60895. * @since Method available since Release 4.0.0
  60896. */
  60897. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  60898. {
  60899. if (!$this->isOfInterest($test)) {
  60900. return;
  60901. }
  60902. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_RISKY;
  60903. $this->risky++;
  60904. }
  60905. /**
  60906. * Skipped test.
  60907. *
  60908. * @param PHPUnit_Framework_Test $test
  60909. * @param Exception $e
  60910. * @param float $time
  60911. * @since Method available since Release 3.0.0
  60912. */
  60913. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  60914. {
  60915. if (!$this->isOfInterest($test)) {
  60916. return;
  60917. }
  60918. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED;
  60919. $this->skipped++;
  60920. }
  60921. /**
  60922. * A testsuite started.
  60923. *
  60924. * @param PHPUnit_Framework_TestSuite $suite
  60925. * @since Method available since Release 2.2.0
  60926. */
  60927. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  60928. {
  60929. }
  60930. /**
  60931. * A testsuite ended.
  60932. *
  60933. * @param PHPUnit_Framework_TestSuite $suite
  60934. * @since Method available since Release 2.2.0
  60935. */
  60936. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  60937. {
  60938. }
  60939. /**
  60940. * A test started.
  60941. *
  60942. * @param PHPUnit_Framework_Test $test
  60943. */
  60944. public function startTest(PHPUnit_Framework_Test $test)
  60945. {
  60946. if (!$this->isOfInterest($test)) {
  60947. return;
  60948. }
  60949. $class = get_class($test);
  60950. if ($this->testClass != $class) {
  60951. if ($this->testClass != '') {
  60952. $this->doEndClass();
  60953. }
  60954. $this->currentTestClassPrettified = $this->prettifier->prettifyTestClass($class);
  60955. $this->startClass($class);
  60956. $this->testClass = $class;
  60957. $this->tests = array();
  60958. }
  60959. $prettified = false;
  60960. $annotations = $test->getAnnotations();
  60961. if (isset($annotations['method']['testdox'][0])) {
  60962. $this->currentTestMethodPrettified = $annotations['method']['testdox'][0];
  60963. $prettified = true;
  60964. }
  60965. if (!$prettified) {
  60966. $this->currentTestMethodPrettified = $this->prettifier->prettifyTestMethod($test->getName(false));
  60967. }
  60968. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED;
  60969. }
  60970. /**
  60971. * A test ended.
  60972. *
  60973. * @param PHPUnit_Framework_Test $test
  60974. * @param float $time
  60975. */
  60976. public function endTest(PHPUnit_Framework_Test $test, $time)
  60977. {
  60978. if (!$this->isOfInterest($test)) {
  60979. return;
  60980. }
  60981. if (!isset($this->tests[$this->currentTestMethodPrettified])) {
  60982. if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
  60983. $this->tests[$this->currentTestMethodPrettified]['success'] = 1;
  60984. $this->tests[$this->currentTestMethodPrettified]['failure'] = 0;
  60985. } else {
  60986. $this->tests[$this->currentTestMethodPrettified]['success'] = 0;
  60987. $this->tests[$this->currentTestMethodPrettified]['failure'] = 1;
  60988. }
  60989. } else {
  60990. if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
  60991. $this->tests[$this->currentTestMethodPrettified]['success']++;
  60992. } else {
  60993. $this->tests[$this->currentTestMethodPrettified]['failure']++;
  60994. }
  60995. }
  60996. $this->currentTestClassPrettified = null;
  60997. $this->currentTestMethodPrettified = null;
  60998. }
  60999. /**
  61000. * @since Method available since Release 2.3.0
  61001. */
  61002. protected function doEndClass()
  61003. {
  61004. foreach ($this->tests as $name => $data) {
  61005. $this->onTest($name, $data['failure'] == 0);
  61006. }
  61007. $this->endClass($this->testClass);
  61008. }
  61009. /**
  61010. * Handler for 'start run' event.
  61011. *
  61012. */
  61013. protected function startRun()
  61014. {
  61015. }
  61016. /**
  61017. * Handler for 'start class' event.
  61018. *
  61019. * @param string $name
  61020. */
  61021. protected function startClass($name)
  61022. {
  61023. }
  61024. /**
  61025. * Handler for 'on test' event.
  61026. *
  61027. * @param string $name
  61028. * @param boolean $success
  61029. */
  61030. protected function onTest($name, $success = true)
  61031. {
  61032. }
  61033. /**
  61034. * Handler for 'end class' event.
  61035. *
  61036. * @param string $name
  61037. */
  61038. protected function endClass($name)
  61039. {
  61040. }
  61041. /**
  61042. * Handler for 'end run' event.
  61043. *
  61044. */
  61045. protected function endRun()
  61046. {
  61047. }
  61048. private function isOfInterest(PHPUnit_Framework_Test $test)
  61049. {
  61050. return $test instanceof PHPUnit_Framework_TestCase && get_class($test) != 'PHPUnit_Framework_Warning';
  61051. }
  61052. }
  61053. <?php
  61054. /*
  61055. * This file is part of PHPUnit.
  61056. *
  61057. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61058. *
  61059. * For the full copyright and license information, please view the LICENSE
  61060. * file that was distributed with this source code.
  61061. */
  61062. /**
  61063. * Prettifies class and method names for use in TestDox documentation.
  61064. *
  61065. * @package PHPUnit
  61066. * @subpackage Util_TestDox
  61067. * @author Sebastian Bergmann <sebastian@phpunit.de>
  61068. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  61069. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  61070. * @link http://www.phpunit.de/
  61071. * @since Class available since Release 2.1.0
  61072. */
  61073. class PHPUnit_Util_TestDox_NamePrettifier
  61074. {
  61075. /**
  61076. * @var string
  61077. */
  61078. protected $prefix = 'Test';
  61079. /**
  61080. * @var string
  61081. */
  61082. protected $suffix = 'Test';
  61083. /**
  61084. * @var array
  61085. */
  61086. protected $strings = array();
  61087. /**
  61088. * Prettifies the name of a test class.
  61089. *
  61090. * @param string $name
  61091. * @return string
  61092. */
  61093. public function prettifyTestClass($name)
  61094. {
  61095. $title = $name;
  61096. if ($this->suffix !== null &&
  61097. $this->suffix == substr($name, -1 * strlen($this->suffix))) {
  61098. $title = substr($title, 0, strripos($title, $this->suffix));
  61099. }
  61100. if ($this->prefix !== null &&
  61101. $this->prefix == substr($name, 0, strlen($this->prefix))) {
  61102. $title = substr($title, strlen($this->prefix));
  61103. }
  61104. if (substr($title, 0, 1) == '\\') {
  61105. $title = substr($title, 1);
  61106. }
  61107. return $title;
  61108. }
  61109. /**
  61110. * Prettifies the name of a test method.
  61111. *
  61112. * @param string $name
  61113. * @return string
  61114. */
  61115. public function prettifyTestMethod($name)
  61116. {
  61117. $buffer = '';
  61118. if (!is_string($name) || strlen($name) == 0) {
  61119. return $buffer;
  61120. }
  61121. $string = preg_replace('#\d+$#', '', $name, -1, $count);
  61122. if (in_array($string, $this->strings)) {
  61123. $name = $string;
  61124. } elseif ($count == 0) {
  61125. $this->strings[] = $string;
  61126. }
  61127. if (strpos($name, '_') !== false) {
  61128. return str_replace('_', ' ', $name);
  61129. }
  61130. $max = strlen($name);
  61131. if (substr($name, 0, 4) == 'test') {
  61132. $offset = 4;
  61133. } else {
  61134. $offset = 0;
  61135. $name[0] = strtoupper($name[0]);
  61136. }
  61137. $wasNumeric = false;
  61138. for ($i = $offset; $i < $max; $i++) {
  61139. if ($i > $offset &&
  61140. ord($name[$i]) >= 65 &&
  61141. ord($name[$i]) <= 90) {
  61142. $buffer .= ' ' . strtolower($name[$i]);
  61143. } else {
  61144. $isNumeric = is_numeric($name[$i]);
  61145. if (!$wasNumeric && $isNumeric) {
  61146. $buffer .= ' ';
  61147. $wasNumeric = true;
  61148. }
  61149. if ($wasNumeric && !$isNumeric) {
  61150. $wasNumeric = false;
  61151. }
  61152. $buffer .= $name[$i];
  61153. }
  61154. }
  61155. return $buffer;
  61156. }
  61157. /**
  61158. * Sets the prefix of test names.
  61159. *
  61160. * @param string $prefix
  61161. */
  61162. public function setPrefix($prefix)
  61163. {
  61164. $this->prefix = $prefix;
  61165. }
  61166. /**
  61167. * Sets the suffix of test names.
  61168. *
  61169. * @param string $suffix
  61170. */
  61171. public function setSuffix($suffix)
  61172. {
  61173. $this->suffix = $suffix;
  61174. }
  61175. }
  61176. <?php
  61177. /*
  61178. * This file is part of PHPUnit.
  61179. *
  61180. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61181. *
  61182. * For the full copyright and license information, please view the LICENSE
  61183. * file that was distributed with this source code.
  61184. */
  61185. /**
  61186. * Error handler that converts PHP errors and warnings to exceptions.
  61187. *
  61188. * @package PHPUnit
  61189. * @subpackage Util
  61190. * @author Márcio Almada <marcio3w@gmail.com>
  61191. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  61192. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  61193. * @link http://www.phpunit.de/
  61194. * @since Class available since Release 4.2.0
  61195. */
  61196. class PHPUnit_Util_Regex
  61197. {
  61198. public static function pregMatchSafe($pattern, $subject, $matches = null, $flags = 0, $offset = 0)
  61199. {
  61200. $handler_terminator = PHPUnit_Util_ErrorHandler::handleErrorOnce(E_WARNING);
  61201. $match = preg_match($pattern, $subject, $matches, $flags, $offset);
  61202. $handler_terminator(); // cleaning
  61203. return $match;
  61204. }
  61205. }
  61206. <?php
  61207. /*
  61208. * This file is part of PHPUnit.
  61209. *
  61210. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61211. *
  61212. * For the full copyright and license information, please view the LICENSE
  61213. * file that was distributed with this source code.
  61214. */
  61215. /**
  61216. * Utility class for textual type (and value) representation.
  61217. *
  61218. * @package PHPUnit
  61219. * @subpackage Util
  61220. * @author Sebastian Bergmann <sebastian@phpunit.de>
  61221. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  61222. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  61223. * @link http://www.phpunit.de/
  61224. * @since Class available since Release 3.0.0
  61225. */
  61226. class PHPUnit_Util_Type
  61227. {
  61228. public static function isType($type)
  61229. {
  61230. return in_array(
  61231. $type,
  61232. array(
  61233. 'numeric',
  61234. 'integer',
  61235. 'int',
  61236. 'float',
  61237. 'string',
  61238. 'boolean',
  61239. 'bool',
  61240. 'null',
  61241. 'array',
  61242. 'object',
  61243. 'resource',
  61244. 'scalar'
  61245. )
  61246. );
  61247. }
  61248. }
  61249. <?php
  61250. /*
  61251. * This file is part of PHPUnit.
  61252. *
  61253. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61254. *
  61255. * For the full copyright and license information, please view the LICENSE
  61256. * file that was distributed with this source code.
  61257. */
  61258. use SebastianBergmann\Environment\Runtime;
  61259. /**
  61260. * Default utility for PHP sub-processes.
  61261. *
  61262. * @package PHPUnit
  61263. * @subpackage Util
  61264. * @author Sebastian Bergmann <sebastian@phpunit.de>
  61265. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  61266. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  61267. * @link http://www.phpunit.de/
  61268. * @since Class available since Release 3.5.12
  61269. */
  61270. class PHPUnit_Util_PHP_Default extends PHPUnit_Util_PHP
  61271. {
  61272. /**
  61273. * Runs a single job (PHP code) using a separate PHP process.
  61274. *
  61275. * @param string $job
  61276. * @param array $settings
  61277. * @return array
  61278. * @throws PHPUnit_Framework_Exception
  61279. */
  61280. public function runJob($job, array $settings = array())
  61281. {
  61282. $runtime = new Runtime;
  61283. $process = proc_open(
  61284. $runtime->getBinary() . $this->settingsToParameters($settings),
  61285. array(
  61286. 0 => array('pipe', 'r'),
  61287. 1 => array('pipe', 'w'),
  61288. 2 => array('pipe', 'w')
  61289. ),
  61290. $pipes
  61291. );
  61292. if (!is_resource($process)) {
  61293. throw new PHPUnit_Framework_Exception(
  61294. 'Unable to spawn worker process'
  61295. );
  61296. }
  61297. $this->process($pipes[0], $job);
  61298. fclose($pipes[0]);
  61299. $stdout = stream_get_contents($pipes[1]);
  61300. fclose($pipes[1]);
  61301. $stderr = stream_get_contents($pipes[2]);
  61302. fclose($pipes[2]);
  61303. proc_close($process);
  61304. $this->cleanup();
  61305. return array('stdout' => $stdout, 'stderr' => $stderr);
  61306. }
  61307. /**
  61308. * @param resource $pipe
  61309. * @param string $job
  61310. * @throws PHPUnit_Framework_Exception
  61311. * @since Method available since Release 3.5.12
  61312. */
  61313. protected function process($pipe, $job)
  61314. {
  61315. fwrite($pipe, $job);
  61316. }
  61317. /**
  61318. * @since Method available since Release 3.5.12
  61319. */
  61320. protected function cleanup()
  61321. {
  61322. }
  61323. }
  61324. <?php
  61325. if (!defined('STDOUT')) {
  61326. // php://stdout does not obey output buffering. Any output would break
  61327. // unserialization of child process results in the parent process.
  61328. define('STDOUT', fopen('php://temp', 'w+b'));
  61329. define('STDERR', fopen('php://stderr', 'wb'));
  61330. }
  61331. {iniSettings}
  61332. ini_set('display_errors', 'stderr');
  61333. set_include_path('{include_path}');
  61334. $composerAutoload = {composerAutoload};
  61335. $phar = {phar};
  61336. ob_start();
  61337. if ($composerAutoload) {
  61338. require_once $composerAutoload;
  61339. define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
  61340. } else if ($phar) {
  61341. require $phar;
  61342. }
  61343. function __phpunit_run_isolated_test()
  61344. {
  61345. if (!class_exists('{className}')) {
  61346. require_once '{filename}';
  61347. }
  61348. $result = new PHPUnit_Framework_TestResult;
  61349. if ({collectCodeCoverageInformation}) {
  61350. $result->setCodeCoverage(new PHP_CodeCoverage);
  61351. }
  61352. $result->beStrictAboutTestsThatDoNotTestAnything({isStrictAboutTestsThatDoNotTestAnything});
  61353. $result->beStrictAboutOutputDuringTests({isStrictAboutOutputDuringTests});
  61354. $result->beStrictAboutTestSize({isStrictAboutTestSize});
  61355. $result->beStrictAboutTodoAnnotatedTests({isStrictAboutTodoAnnotatedTests});
  61356. $test = new {className}('{methodName}', unserialize('{data}'), '{dataName}');
  61357. $test->setDependencyInput(unserialize('{dependencyInput}'));
  61358. $test->setInIsolation(TRUE);
  61359. ob_end_clean();
  61360. $test->run($result);
  61361. $output = '';
  61362. if (!$test->hasExpectationOnOutput()) {
  61363. $output = $test->getActualOutput();
  61364. }
  61365. rewind(STDOUT);
  61366. if ($stdout = stream_get_contents(STDOUT)) {
  61367. $output = $stdout . $output;
  61368. }
  61369. print serialize(
  61370. array(
  61371. 'testResult' => $test->getResult(),
  61372. 'numAssertions' => $test->getNumAssertions(),
  61373. 'result' => $result,
  61374. 'output' => $output
  61375. )
  61376. );
  61377. }
  61378. {constants}
  61379. {included_files}
  61380. {globals}
  61381. if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
  61382. require_once $GLOBALS['__PHPUNIT_BOOTSTRAP'];
  61383. unset($GLOBALS['__PHPUNIT_BOOTSTRAP']);
  61384. }
  61385. __phpunit_run_isolated_test();
  61386. <?php
  61387. /*
  61388. * This file is part of PHPUnit.
  61389. *
  61390. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61391. *
  61392. * For the full copyright and license information, please view the LICENSE
  61393. * file that was distributed with this source code.
  61394. */
  61395. use SebastianBergmann\Environment\Runtime;
  61396. /**
  61397. * Windows utility for PHP sub-processes.
  61398. *
  61399. * @package PHPUnit
  61400. * @subpackage Util
  61401. * @author Sebastian Bergmann <sebastian@phpunit.de>
  61402. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  61403. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  61404. * @link http://www.phpunit.de/
  61405. * @since Class available since Release 3.5.12
  61406. */
  61407. class PHPUnit_Util_PHP_Windows extends PHPUnit_Util_PHP_Default
  61408. {
  61409. /**
  61410. * @var string
  61411. */
  61412. private $tempFile;
  61413. /**
  61414. * {@inheritdoc}
  61415. *
  61416. * Reading from STDOUT or STDERR hangs forever on Windows if the output is
  61417. * too large.
  61418. *
  61419. * @see https://bugs.php.net/bug.php?id=51800
  61420. */
  61421. public function runJob($job, array $settings = array())
  61422. {
  61423. $runtime = new Runtime;
  61424. if (false === $stdout_handle = tmpfile()) {
  61425. throw new PHPUnit_Framework_Exception(
  61426. 'A temporary file could not be created; verify that your TEMP environment variable is writable'
  61427. );
  61428. }
  61429. $process = proc_open(
  61430. $runtime->getBinary() . $this->settingsToParameters($settings),
  61431. array(
  61432. 0 => array('pipe', 'r'),
  61433. 1 => $stdout_handle,
  61434. 2 => array('pipe', 'w')
  61435. ),
  61436. $pipes
  61437. );
  61438. if (!is_resource($process)) {
  61439. throw new PHPUnit_Framework_Exception(
  61440. 'Unable to spawn worker process'
  61441. );
  61442. }
  61443. $this->process($pipes[0], $job);
  61444. fclose($pipes[0]);
  61445. $stderr = stream_get_contents($pipes[2]);
  61446. fclose($pipes[2]);
  61447. proc_close($process);
  61448. rewind($stdout_handle);
  61449. $stdout = stream_get_contents($stdout_handle);
  61450. fclose($stdout_handle);
  61451. $this->cleanup();
  61452. return array('stdout' => $stdout, 'stderr' => $stderr);
  61453. }
  61454. /**
  61455. * @param resource $pipe
  61456. * @param string $job
  61457. * @throws PHPUnit_Framework_Exception
  61458. * @since Method available since Release 3.5.12
  61459. */
  61460. protected function process($pipe, $job)
  61461. {
  61462. if (!($this->tempFile = tempnam(sys_get_temp_dir(), 'PHPUnit')) ||
  61463. file_put_contents($this->tempFile, $job) === false) {
  61464. throw new PHPUnit_Framework_Exception(
  61465. 'Unable to write temporary file'
  61466. );
  61467. }
  61468. fwrite(
  61469. $pipe,
  61470. "<?php require_once " . var_export($this->tempFile, true) . "; ?>"
  61471. );
  61472. }
  61473. /**
  61474. * @since Method available since Release 3.5.12
  61475. */
  61476. protected function cleanup()
  61477. {
  61478. unlink($this->tempFile);
  61479. }
  61480. }
  61481. <?php
  61482. /*
  61483. * This file is part of PHPUnit.
  61484. *
  61485. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61486. *
  61487. * For the full copyright and license information, please view the LICENSE
  61488. * file that was distributed with this source code.
  61489. */
  61490. /**
  61491. * Utility methods to load PHP sourcefiles.
  61492. *
  61493. * @package PHPUnit
  61494. * @subpackage Util
  61495. * @author Sebastian Bergmann <sebastian@phpunit.de>
  61496. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  61497. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  61498. * @link http://www.phpunit.de/
  61499. * @since Class available since Release 2.3.0
  61500. */
  61501. class PHPUnit_Util_Fileloader
  61502. {
  61503. /**
  61504. * Checks if a PHP sourcefile is readable.
  61505. * The sourcefile is loaded through the load() method.
  61506. *
  61507. * @param string $filename
  61508. * @return string
  61509. * @throws PHPUnit_Framework_Exception
  61510. */
  61511. public static function checkAndLoad($filename)
  61512. {
  61513. $includePathFilename = stream_resolve_include_path($filename);
  61514. if (!$includePathFilename || !is_readable($includePathFilename)) {
  61515. throw new PHPUnit_Framework_Exception(
  61516. sprintf('Cannot open file "%s".' . "\n", $filename)
  61517. );
  61518. }
  61519. self::load($includePathFilename);
  61520. return $includePathFilename;
  61521. }
  61522. /**
  61523. * Loads a PHP sourcefile.
  61524. *
  61525. * @param string $filename
  61526. * @return mixed
  61527. * @since Method available since Release 3.0.0
  61528. */
  61529. public static function load($filename)
  61530. {
  61531. $oldVariableNames = array_keys(get_defined_vars());
  61532. include_once $filename;
  61533. $newVariables = get_defined_vars();
  61534. $newVariableNames = array_diff(
  61535. array_keys($newVariables),
  61536. $oldVariableNames
  61537. );
  61538. foreach ($newVariableNames as $variableName) {
  61539. if ($variableName != 'oldVariableNames') {
  61540. $GLOBALS[$variableName] = $newVariables[$variableName];
  61541. }
  61542. }
  61543. return $filename;
  61544. }
  61545. }
  61546. <?php
  61547. /*
  61548. * This file is part of PHPUnit.
  61549. *
  61550. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61551. *
  61552. * For the full copyright and license information, please view the LICENSE
  61553. * file that was distributed with this source code.
  61554. */
  61555. /**
  61556. * XML helpers.
  61557. *
  61558. * @package PHPUnit
  61559. * @subpackage Util
  61560. * @author Sebastian Bergmann <sebastian@phpunit.de>
  61561. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  61562. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  61563. * @link http://www.phpunit.de/
  61564. * @since Class available since Release 3.2.0
  61565. */
  61566. class PHPUnit_Util_XML
  61567. {
  61568. /**
  61569. * Escapes a string for the use in XML documents
  61570. * Any Unicode character is allowed, excluding the surrogate blocks, FFFE,
  61571. * and FFFF (not even as character reference).
  61572. * See http://www.w3.org/TR/xml/#charsets
  61573. *
  61574. * @param string $string
  61575. * @return string
  61576. * @author Kore Nordmann <mail@kore-nordmann.de>
  61577. * @since Method available since Release 3.4.6
  61578. */
  61579. public static function prepareString($string)
  61580. {
  61581. return preg_replace(
  61582. '/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/',
  61583. '',
  61584. htmlspecialchars(
  61585. PHPUnit_Util_String::convertToUtf8($string),
  61586. ENT_QUOTES,
  61587. 'UTF-8'
  61588. )
  61589. );
  61590. }
  61591. /**
  61592. * Loads an XML (or HTML) file into a DOMDocument object.
  61593. *
  61594. * @param string $filename
  61595. * @param boolean $isHtml
  61596. * @param boolean $xinclude
  61597. * @param boolean $strict
  61598. * @return DOMDocument
  61599. * @since Method available since Release 3.3.0
  61600. */
  61601. public static function loadFile($filename, $isHtml = false, $xinclude = false, $strict = false)
  61602. {
  61603. $reporting = error_reporting(0);
  61604. $contents = file_get_contents($filename);
  61605. error_reporting($reporting);
  61606. if ($contents === false) {
  61607. throw new PHPUnit_Framework_Exception(
  61608. sprintf(
  61609. 'Could not read "%s".',
  61610. $filename
  61611. )
  61612. );
  61613. }
  61614. return self::load($contents, $isHtml, $filename, $xinclude, $strict);
  61615. }
  61616. /**
  61617. * Load an $actual document into a DOMDocument. This is called
  61618. * from the selector assertions.
  61619. *
  61620. * If $actual is already a DOMDocument, it is returned with
  61621. * no changes. Otherwise, $actual is loaded into a new DOMDocument
  61622. * as either HTML or XML, depending on the value of $isHtml. If $isHtml is
  61623. * false and $xinclude is true, xinclude is performed on the loaded
  61624. * DOMDocument.
  61625. *
  61626. * Note: prior to PHPUnit 3.3.0, this method loaded a file and
  61627. * not a string as it currently does. To load a file into a
  61628. * DOMDocument, use loadFile() instead.
  61629. *
  61630. * @param string|DOMDocument $actual
  61631. * @param boolean $isHtml
  61632. * @param string $filename
  61633. * @param boolean $xinclude
  61634. * @param boolean $strict
  61635. * @return DOMDocument
  61636. * @since Method available since Release 3.3.0
  61637. * @author Mike Naberezny <mike@maintainable.com>
  61638. * @author Derek DeVries <derek@maintainable.com>
  61639. * @author Tobias Schlitt <toby@php.net>
  61640. */
  61641. public static function load($actual, $isHtml = false, $filename = '', $xinclude = false, $strict = false)
  61642. {
  61643. if ($actual instanceof DOMDocument) {
  61644. return $actual;
  61645. }
  61646. // Required for XInclude on Windows.
  61647. if ($xinclude) {
  61648. $cwd = getcwd();
  61649. @chdir(dirname($filename));
  61650. }
  61651. $document = new DOMDocument;
  61652. $internal = libxml_use_internal_errors(true);
  61653. $message = '';
  61654. $reporting = error_reporting(0);
  61655. if ('' !== $filename) {
  61656. // Necessary for xinclude
  61657. $document->documentURI = $filename;
  61658. }
  61659. if ($isHtml) {
  61660. $loaded = $document->loadHTML($actual);
  61661. } else {
  61662. $loaded = $document->loadXML($actual);
  61663. }
  61664. if (!$isHtml && $xinclude) {
  61665. $document->xinclude();
  61666. }
  61667. foreach (libxml_get_errors() as $error) {
  61668. $message .= "\n" . $error->message;
  61669. }
  61670. libxml_use_internal_errors($internal);
  61671. error_reporting($reporting);
  61672. if ($xinclude) {
  61673. @chdir($cwd);
  61674. }
  61675. if ($loaded === false || ($strict && $message !== '')) {
  61676. if ($filename !== '') {
  61677. throw new PHPUnit_Framework_Exception(
  61678. sprintf(
  61679. 'Could not load "%s".%s',
  61680. $filename,
  61681. $message != '' ? "\n" . $message : ''
  61682. )
  61683. );
  61684. } else {
  61685. throw new PHPUnit_Framework_Exception($message);
  61686. }
  61687. }
  61688. return $document;
  61689. }
  61690. /**
  61691. *
  61692. *
  61693. * @param DOMNode $node
  61694. * @return string
  61695. * @since Method available since Release 3.4.0
  61696. */
  61697. public static function nodeToText(DOMNode $node)
  61698. {
  61699. if ($node->childNodes->length == 1) {
  61700. return $node->nodeValue;
  61701. }
  61702. $result = '';
  61703. foreach ($node->childNodes as $childNode) {
  61704. $result .= $node->ownerDocument->saveXML($childNode);
  61705. }
  61706. return $result;
  61707. }
  61708. /**
  61709. *
  61710. *
  61711. * @param DOMNode $node
  61712. * @since Method available since Release 3.3.0
  61713. * @author Mattis Stordalen Flister <mattis@xait.no>
  61714. */
  61715. public static function removeCharacterDataNodes(DOMNode $node)
  61716. {
  61717. if ($node->hasChildNodes()) {
  61718. for ($i = $node->childNodes->length - 1; $i >= 0; $i--) {
  61719. if (($child = $node->childNodes->item($i)) instanceof DOMCharacterData) {
  61720. $node->removeChild($child);
  61721. }
  61722. }
  61723. }
  61724. }
  61725. /**
  61726. * "Convert" a DOMElement object into a PHP variable.
  61727. *
  61728. * @param DOMElement $element
  61729. * @return mixed
  61730. * @since Method available since Release 3.4.0
  61731. */
  61732. public static function xmlToVariable(DOMElement $element)
  61733. {
  61734. $variable = null;
  61735. switch ($element->tagName) {
  61736. case 'array': {
  61737. $variable = array();
  61738. foreach ($element->getElementsByTagName('element') as $element) {
  61739. $value = self::xmlToVariable($element->childNodes->item(1));
  61740. if ($element->hasAttribute('key')) {
  61741. $variable[(string) $element->getAttribute('key')] = $value;
  61742. } else {
  61743. $variable[] = $value;
  61744. }
  61745. }
  61746. }
  61747. break;
  61748. case 'object': {
  61749. $className = $element->getAttribute('class');
  61750. if ($element->hasChildNodes()) {
  61751. $arguments = $element->childNodes->item(1)->childNodes;
  61752. $constructorArgs = array();
  61753. foreach ($arguments as $argument) {
  61754. if ($argument instanceof DOMElement) {
  61755. $constructorArgs[] = self::xmlToVariable($argument);
  61756. }
  61757. }
  61758. $class = new ReflectionClass($className);
  61759. $variable = $class->newInstanceArgs($constructorArgs);
  61760. } else {
  61761. $variable = new $className;
  61762. }
  61763. }
  61764. break;
  61765. case 'boolean': {
  61766. $variable = $element->nodeValue == 'true' ? true : false;
  61767. }
  61768. break;
  61769. case 'integer':
  61770. case 'double':
  61771. case 'string': {
  61772. $variable = $element->nodeValue;
  61773. settype($variable, $element->tagName);
  61774. }
  61775. break;
  61776. }
  61777. return $variable;
  61778. }
  61779. /**
  61780. * Validate list of keys in the associative array.
  61781. *
  61782. * @param array $hash
  61783. * @param array $validKeys
  61784. * @return array
  61785. * @throws PHPUnit_Framework_Exception
  61786. * @since Method available since Release 3.3.0
  61787. * @author Mike Naberezny <mike@maintainable.com>
  61788. * @author Derek DeVries <derek@maintainable.com>
  61789. */
  61790. public static function assertValidKeys(array $hash, array $validKeys)
  61791. {
  61792. $valids = array();
  61793. // Normalize validation keys so that we can use both indexed and
  61794. // associative arrays.
  61795. foreach ($validKeys as $key => $val) {
  61796. is_int($key) ? $valids[$val] = null : $valids[$key] = $val;
  61797. }
  61798. $validKeys = array_keys($valids);
  61799. // Check for invalid keys.
  61800. foreach ($hash as $key => $value) {
  61801. if (!in_array($key, $validKeys)) {
  61802. $unknown[] = $key;
  61803. }
  61804. }
  61805. if (!empty($unknown)) {
  61806. throw new PHPUnit_Framework_Exception(
  61807. 'Unknown key(s): ' . implode(', ', $unknown)
  61808. );
  61809. }
  61810. // Add default values for any valid keys that are empty.
  61811. foreach ($valids as $key => $value) {
  61812. if (!isset($hash[$key])) {
  61813. $hash[$key] = $value;
  61814. }
  61815. }
  61816. return $hash;
  61817. }
  61818. /**
  61819. * Parse a CSS selector into an associative array suitable for
  61820. * use with findNodes().
  61821. *
  61822. * @param string $selector
  61823. * @param mixed $content
  61824. * @return array
  61825. * @since Method available since Release 3.3.0
  61826. * @author Mike Naberezny <mike@maintainable.com>
  61827. * @author Derek DeVries <derek@maintainable.com>
  61828. */
  61829. public static function convertSelectToTag($selector, $content = true)
  61830. {
  61831. $selector = trim(preg_replace("/\s+/", " ", $selector));
  61832. // substitute spaces within attribute value
  61833. while (preg_match('/\[[^\]]+"[^"]+\s[^"]+"\]/', $selector)) {
  61834. $selector = preg_replace(
  61835. '/(\[[^\]]+"[^"]+)\s([^"]+"\])/',
  61836. "$1__SPACE__$2",
  61837. $selector
  61838. );
  61839. }
  61840. if (strstr($selector, ' ')) {
  61841. $elements = explode(' ', $selector);
  61842. } else {
  61843. $elements = array($selector);
  61844. }
  61845. $previousTag = array();
  61846. foreach (array_reverse($elements) as $element) {
  61847. $element = str_replace('__SPACE__', ' ', $element);
  61848. // child selector
  61849. if ($element == '>') {
  61850. $previousTag = array('child' => $previousTag['descendant']);
  61851. continue;
  61852. }
  61853. // adjacent-sibling selector
  61854. if ($element == '+') {
  61855. $previousTag = array('adjacent-sibling' => $previousTag['descendant']);
  61856. continue;
  61857. }
  61858. $tag = array();
  61859. // match element tag
  61860. preg_match("/^([^\.#\[]*)/", $element, $eltMatches);
  61861. if (!empty($eltMatches[1])) {
  61862. $tag['tag'] = $eltMatches[1];
  61863. }
  61864. // match attributes (\[[^\]]*\]*), ids (#[^\.#\[]*),
  61865. // and classes (\.[^\.#\[]*))
  61866. preg_match_all(
  61867. "/(\[[^\]]*\]*|#[^\.#\[]*|\.[^\.#\[]*)/",
  61868. $element,
  61869. $matches
  61870. );
  61871. if (!empty($matches[1])) {
  61872. $classes = array();
  61873. $attrs = array();
  61874. foreach ($matches[1] as $match) {
  61875. // id matched
  61876. if (substr($match, 0, 1) == '#') {
  61877. $tag['id'] = substr($match, 1);
  61878. } // class matched
  61879. elseif (substr($match, 0, 1) == '.') {
  61880. $classes[] = substr($match, 1);
  61881. } // attribute matched
  61882. elseif (substr($match, 0, 1) == '[' &&
  61883. substr($match, -1, 1) == ']') {
  61884. $attribute = substr($match, 1, strlen($match) - 2);
  61885. $attribute = str_replace('"', '', $attribute);
  61886. // match single word
  61887. if (strstr($attribute, '~=')) {
  61888. list($key, $value) = explode('~=', $attribute);
  61889. $value = "regexp:/.*\b$value\b.*/";
  61890. } // match substring
  61891. elseif (strstr($attribute, '*=')) {
  61892. list($key, $value) = explode('*=', $attribute);
  61893. $value = "regexp:/.*$value.*/";
  61894. } // exact match
  61895. else {
  61896. list($key, $value) = explode('=', $attribute);
  61897. }
  61898. $attrs[$key] = $value;
  61899. }
  61900. }
  61901. if ($classes) {
  61902. $tag['class'] = implode(' ', $classes);
  61903. }
  61904. if ($attrs) {
  61905. $tag['attributes'] = $attrs;
  61906. }
  61907. }
  61908. // tag content
  61909. if (is_string($content)) {
  61910. $tag['content'] = $content;
  61911. }
  61912. // determine previous child/descendants
  61913. if (!empty($previousTag['descendant'])) {
  61914. $tag['descendant'] = $previousTag['descendant'];
  61915. } elseif (!empty($previousTag['child'])) {
  61916. $tag['child'] = $previousTag['child'];
  61917. } elseif (!empty($previousTag['adjacent-sibling'])) {
  61918. $tag['adjacent-sibling'] = $previousTag['adjacent-sibling'];
  61919. unset($tag['content']);
  61920. }
  61921. $previousTag = array('descendant' => $tag);
  61922. }
  61923. return $tag;
  61924. }
  61925. /**
  61926. * Parse an $actual document and return an array of DOMNodes
  61927. * matching the CSS $selector. If an error occurs, it will
  61928. * return false.
  61929. *
  61930. * To only return nodes containing a certain content, give
  61931. * the $content to match as a string. Otherwise, setting
  61932. * $content to true will return all nodes matching $selector.
  61933. *
  61934. * The $actual document may be a DOMDocument or a string
  61935. * containing XML or HTML, identified by $isHtml.
  61936. *
  61937. * @param array $selector
  61938. * @param string $content
  61939. * @param mixed $actual
  61940. * @param boolean $isHtml
  61941. * @return boolean|array
  61942. * @since Method available since Release 3.3.0
  61943. * @author Mike Naberezny <mike@maintainable.com>
  61944. * @author Derek DeVries <derek@maintainable.com>
  61945. * @author Tobias Schlitt <toby@php.net>
  61946. */
  61947. public static function cssSelect($selector, $content, $actual, $isHtml = true)
  61948. {
  61949. $matcher = self::convertSelectToTag($selector, $content);
  61950. $dom = self::load($actual, $isHtml);
  61951. $tags = self::findNodes($dom, $matcher, $isHtml);
  61952. return $tags;
  61953. }
  61954. /**
  61955. * Parse out the options from the tag using DOM object tree.
  61956. *
  61957. * @param DOMDocument $dom
  61958. * @param array $options
  61959. * @param boolean $isHtml
  61960. * @return array
  61961. * @since Method available since Release 3.3.0
  61962. * @author Mike Naberezny <mike@maintainable.com>
  61963. * @author Derek DeVries <derek@maintainable.com>
  61964. * @author Tobias Schlitt <toby@php.net>
  61965. */
  61966. public static function findNodes(DOMDocument $dom, array $options, $isHtml = true)
  61967. {
  61968. $valid = array(
  61969. 'id', 'class', 'tag', 'content', 'attributes', 'parent',
  61970. 'child', 'ancestor', 'descendant', 'children', 'adjacent-sibling'
  61971. );
  61972. $filtered = array();
  61973. $options = self::assertValidKeys($options, $valid);
  61974. // find the element by id
  61975. if ($options['id']) {
  61976. $options['attributes']['id'] = $options['id'];
  61977. }
  61978. if ($options['class']) {
  61979. $options['attributes']['class'] = $options['class'];
  61980. }
  61981. // find the element by a tag type
  61982. if ($options['tag']) {
  61983. if ($isHtml) {
  61984. $elements = self::getElementsByCaseInsensitiveTagName(
  61985. $dom,
  61986. $options['tag']
  61987. );
  61988. } else {
  61989. $elements = $dom->getElementsByTagName($options['tag']);
  61990. }
  61991. foreach ($elements as $element) {
  61992. $nodes[] = $element;
  61993. }
  61994. if (empty($nodes)) {
  61995. return false;
  61996. }
  61997. } // no tag selected, get them all
  61998. else {
  61999. $tags = array(
  62000. 'a', 'abbr', 'acronym', 'address', 'area', 'b', 'base', 'bdo',
  62001. 'big', 'blockquote', 'body', 'br', 'button', 'caption', 'cite',
  62002. 'code', 'col', 'colgroup', 'dd', 'del', 'div', 'dfn', 'dl',
  62003. 'dt', 'em', 'fieldset', 'form', 'frame', 'frameset', 'h1', 'h2',
  62004. 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'i', 'iframe',
  62005. 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'link',
  62006. 'map', 'meta', 'noframes', 'noscript', 'object', 'ol', 'optgroup',
  62007. 'option', 'p', 'param', 'pre', 'q', 'samp', 'script', 'select',
  62008. 'small', 'span', 'strong', 'style', 'sub', 'sup', 'table',
  62009. 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title',
  62010. 'tr', 'tt', 'ul', 'var',
  62011. // HTML5
  62012. 'article', 'aside', 'audio', 'bdi', 'canvas', 'command',
  62013. 'datalist', 'details', 'dialog', 'embed', 'figure', 'figcaption',
  62014. 'footer', 'header', 'hgroup', 'keygen', 'mark', 'meter', 'nav',
  62015. 'output', 'progress', 'ruby', 'rt', 'rp', 'track', 'section',
  62016. 'source', 'summary', 'time', 'video', 'wbr'
  62017. );
  62018. foreach ($tags as $tag) {
  62019. if ($isHtml) {
  62020. $elements = self::getElementsByCaseInsensitiveTagName(
  62021. $dom,
  62022. $tag
  62023. );
  62024. } else {
  62025. $elements = $dom->getElementsByTagName($tag);
  62026. }
  62027. foreach ($elements as $element) {
  62028. $nodes[] = $element;
  62029. }
  62030. }
  62031. if (empty($nodes)) {
  62032. return false;
  62033. }
  62034. }
  62035. // filter by attributes
  62036. if ($options['attributes']) {
  62037. foreach ($nodes as $node) {
  62038. $invalid = false;
  62039. foreach ($options['attributes'] as $name => $value) {
  62040. // match by regexp if like "regexp:/foo/i"
  62041. if (preg_match('/^regexp\s*:\s*(.*)/i', $value, $matches)) {
  62042. if (!preg_match($matches[1], $node->getAttribute($name))) {
  62043. $invalid = true;
  62044. }
  62045. } // class can match only a part
  62046. elseif ($name == 'class') {
  62047. // split to individual classes
  62048. $findClasses = explode(
  62049. ' ',
  62050. preg_replace("/\s+/", " ", $value)
  62051. );
  62052. $allClasses = explode(
  62053. ' ',
  62054. preg_replace("/\s+/", " ", $node->getAttribute($name))
  62055. );
  62056. // make sure each class given is in the actual node
  62057. foreach ($findClasses as $findClass) {
  62058. if (!in_array($findClass, $allClasses)) {
  62059. $invalid = true;
  62060. }
  62061. }
  62062. } // match by exact string
  62063. else {
  62064. if ($node->getAttribute($name) != $value) {
  62065. $invalid = true;
  62066. }
  62067. }
  62068. }
  62069. // if every attribute given matched
  62070. if (!$invalid) {
  62071. $filtered[] = $node;
  62072. }
  62073. }
  62074. $nodes = $filtered;
  62075. $filtered = array();
  62076. if (empty($nodes)) {
  62077. return false;
  62078. }
  62079. }
  62080. // filter by content
  62081. if ($options['content'] !== null) {
  62082. foreach ($nodes as $node) {
  62083. $invalid = false;
  62084. // match by regexp if like "regexp:/foo/i"
  62085. if (preg_match('/^regexp\s*:\s*(.*)/i', $options['content'], $matches)) {
  62086. if (!preg_match($matches[1], self::getNodeText($node))) {
  62087. $invalid = true;
  62088. }
  62089. } // match empty string
  62090. elseif ($options['content'] === '') {
  62091. if (self::getNodeText($node) !== '') {
  62092. $invalid = true;
  62093. }
  62094. } // match by exact string
  62095. elseif (strstr(self::getNodeText($node), $options['content']) === false) {
  62096. $invalid = true;
  62097. }
  62098. if (!$invalid) {
  62099. $filtered[] = $node;
  62100. }
  62101. }
  62102. $nodes = $filtered;
  62103. $filtered = array();
  62104. if (empty($nodes)) {
  62105. return false;
  62106. }
  62107. }
  62108. // filter by parent node
  62109. if ($options['parent']) {
  62110. $parentNodes = self::findNodes($dom, $options['parent'], $isHtml);
  62111. $parentNode = isset($parentNodes[0]) ? $parentNodes[0] : null;
  62112. foreach ($nodes as $node) {
  62113. if ($parentNode !== $node->parentNode) {
  62114. continue;
  62115. }
  62116. $filtered[] = $node;
  62117. }
  62118. $nodes = $filtered;
  62119. $filtered = array();
  62120. if (empty($nodes)) {
  62121. return false;
  62122. }
  62123. }
  62124. // filter by child node
  62125. if ($options['child']) {
  62126. $childNodes = self::findNodes($dom, $options['child'], $isHtml);
  62127. $childNodes = !empty($childNodes) ? $childNodes : array();
  62128. foreach ($nodes as $node) {
  62129. foreach ($node->childNodes as $child) {
  62130. foreach ($childNodes as $childNode) {
  62131. if ($childNode === $child) {
  62132. $filtered[] = $node;
  62133. }
  62134. }
  62135. }
  62136. }
  62137. $nodes = $filtered;
  62138. $filtered = array();
  62139. if (empty($nodes)) {
  62140. return false;
  62141. }
  62142. }
  62143. // filter by adjacent-sibling
  62144. if ($options['adjacent-sibling']) {
  62145. $adjacentSiblingNodes = self::findNodes($dom, $options['adjacent-sibling'], $isHtml);
  62146. $adjacentSiblingNodes = !empty($adjacentSiblingNodes) ? $adjacentSiblingNodes : array();
  62147. foreach ($nodes as $node) {
  62148. $sibling = $node;
  62149. while ($sibling = $sibling->nextSibling) {
  62150. if ($sibling->nodeType !== XML_ELEMENT_NODE) {
  62151. continue;
  62152. }
  62153. foreach ($adjacentSiblingNodes as $adjacentSiblingNode) {
  62154. if ($sibling === $adjacentSiblingNode) {
  62155. $filtered[] = $node;
  62156. break;
  62157. }
  62158. }
  62159. break;
  62160. }
  62161. }
  62162. $nodes = $filtered;
  62163. $filtered = array();
  62164. if (empty($nodes)) {
  62165. return false;
  62166. }
  62167. }
  62168. // filter by ancestor
  62169. if ($options['ancestor']) {
  62170. $ancestorNodes = self::findNodes($dom, $options['ancestor'], $isHtml);
  62171. $ancestorNode = isset($ancestorNodes[0]) ? $ancestorNodes[0] : null;
  62172. foreach ($nodes as $node) {
  62173. $parent = $node->parentNode;
  62174. while ($parent && $parent->nodeType != XML_HTML_DOCUMENT_NODE) {
  62175. if ($parent === $ancestorNode) {
  62176. $filtered[] = $node;
  62177. }
  62178. $parent = $parent->parentNode;
  62179. }
  62180. }
  62181. $nodes = $filtered;
  62182. $filtered = array();
  62183. if (empty($nodes)) {
  62184. return false;
  62185. }
  62186. }
  62187. // filter by descendant
  62188. if ($options['descendant']) {
  62189. $descendantNodes = self::findNodes($dom, $options['descendant'], $isHtml);
  62190. $descendantNodes = !empty($descendantNodes) ? $descendantNodes : array();
  62191. foreach ($nodes as $node) {
  62192. foreach (self::getDescendants($node) as $descendant) {
  62193. foreach ($descendantNodes as $descendantNode) {
  62194. if ($descendantNode === $descendant) {
  62195. $filtered[] = $node;
  62196. }
  62197. }
  62198. }
  62199. }
  62200. $nodes = $filtered;
  62201. $filtered = array();
  62202. if (empty($nodes)) {
  62203. return false;
  62204. }
  62205. }
  62206. // filter by children
  62207. if ($options['children']) {
  62208. $validChild = array('count', 'greater_than', 'less_than', 'only');
  62209. $childOptions = self::assertValidKeys(
  62210. $options['children'],
  62211. $validChild
  62212. );
  62213. foreach ($nodes as $node) {
  62214. $childNodes = $node->childNodes;
  62215. foreach ($childNodes as $childNode) {
  62216. if ($childNode->nodeType !== XML_CDATA_SECTION_NODE &&
  62217. $childNode->nodeType !== XML_TEXT_NODE) {
  62218. $children[] = $childNode;
  62219. }
  62220. }
  62221. // we must have children to pass this filter
  62222. if (!empty($children)) {
  62223. // exact count of children
  62224. if ($childOptions['count'] !== null) {
  62225. if (count($children) !== $childOptions['count']) {
  62226. break;
  62227. }
  62228. } // range count of children
  62229. elseif ($childOptions['less_than'] !== null &&
  62230. $childOptions['greater_than'] !== null) {
  62231. if (count($children) >= $childOptions['less_than'] ||
  62232. count($children) <= $childOptions['greater_than']) {
  62233. break;
  62234. }
  62235. } // less than a given count
  62236. elseif ($childOptions['less_than'] !== null) {
  62237. if (count($children) >= $childOptions['less_than']) {
  62238. break;
  62239. }
  62240. } // more than a given count
  62241. elseif ($childOptions['greater_than'] !== null) {
  62242. if (count($children) <= $childOptions['greater_than']) {
  62243. break;
  62244. }
  62245. }
  62246. // match each child against a specific tag
  62247. if ($childOptions['only']) {
  62248. $onlyNodes = self::findNodes(
  62249. $dom,
  62250. $childOptions['only'],
  62251. $isHtml
  62252. );
  62253. // try to match each child to one of the 'only' nodes
  62254. foreach ($children as $child) {
  62255. $matched = false;
  62256. foreach ($onlyNodes as $onlyNode) {
  62257. if ($onlyNode === $child) {
  62258. $matched = true;
  62259. }
  62260. }
  62261. if (!$matched) {
  62262. break 2;
  62263. }
  62264. }
  62265. }
  62266. $filtered[] = $node;
  62267. }
  62268. }
  62269. $nodes = $filtered;
  62270. if (empty($nodes)) {
  62271. return;
  62272. }
  62273. }
  62274. // return the first node that matches all criteria
  62275. return !empty($nodes) ? $nodes : array();
  62276. }
  62277. /**
  62278. * Recursively get flat array of all descendants of this node.
  62279. *
  62280. * @param DOMNode $node
  62281. * @return array
  62282. * @since Method available since Release 3.3.0
  62283. * @author Mike Naberezny <mike@maintainable.com>
  62284. * @author Derek DeVries <derek@maintainable.com>
  62285. */
  62286. protected static function getDescendants(DOMNode $node)
  62287. {
  62288. $allChildren = array();
  62289. $childNodes = $node->childNodes ? $node->childNodes : array();
  62290. foreach ($childNodes as $child) {
  62291. if ($child->nodeType === XML_CDATA_SECTION_NODE ||
  62292. $child->nodeType === XML_TEXT_NODE) {
  62293. continue;
  62294. }
  62295. $children = self::getDescendants($child);
  62296. $allChildren = array_merge($allChildren, $children, array($child));
  62297. }
  62298. return isset($allChildren) ? $allChildren : array();
  62299. }
  62300. /**
  62301. * Gets elements by case insensitive tagname.
  62302. *
  62303. * @param DOMDocument $dom
  62304. * @param string $tag
  62305. * @return DOMNodeList
  62306. * @since Method available since Release 3.4.0
  62307. */
  62308. protected static function getElementsByCaseInsensitiveTagName(DOMDocument $dom, $tag)
  62309. {
  62310. $elements = $dom->getElementsByTagName(strtolower($tag));
  62311. if ($elements->length == 0) {
  62312. $elements = $dom->getElementsByTagName(strtoupper($tag));
  62313. }
  62314. return $elements;
  62315. }
  62316. /**
  62317. * Get the text value of this node's child text node.
  62318. *
  62319. * @param DOMNode $node
  62320. * @return string
  62321. * @since Method available since Release 3.3.0
  62322. * @author Mike Naberezny <mike@maintainable.com>
  62323. * @author Derek DeVries <derek@maintainable.com>
  62324. */
  62325. protected static function getNodeText(DOMNode $node)
  62326. {
  62327. if (!$node->childNodes instanceof DOMNodeList) {
  62328. return '';
  62329. }
  62330. $result = '';
  62331. foreach ($node->childNodes as $childNode) {
  62332. if ($childNode->nodeType === XML_TEXT_NODE ||
  62333. $childNode->nodeType === XML_CDATA_SECTION_NODE) {
  62334. $result .= trim($childNode->data) . ' ';
  62335. } else {
  62336. $result .= self::getNodeText($childNode);
  62337. }
  62338. }
  62339. return str_replace(' ', ' ', $result);
  62340. }
  62341. }
  62342. <?php
  62343. /*
  62344. * This file is part of PHPUnit.
  62345. *
  62346. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62347. *
  62348. * For the full copyright and license information, please view the LICENSE
  62349. * file that was distributed with this source code.
  62350. */
  62351. /**
  62352. * Utility methods for PHP sub-processes.
  62353. *
  62354. * @package PHPUnit
  62355. * @subpackage Util
  62356. * @author Sebastian Bergmann <sebastian@phpunit.de>
  62357. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  62358. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  62359. * @link http://www.phpunit.de/
  62360. * @since Class available since Release 3.4.0
  62361. */
  62362. abstract class PHPUnit_Util_PHP
  62363. {
  62364. /**
  62365. * @return PHPUnit_Util_PHP
  62366. * @since Method available since Release 3.5.12
  62367. */
  62368. public static function factory()
  62369. {
  62370. if (DIRECTORY_SEPARATOR == '\\') {
  62371. return new PHPUnit_Util_PHP_Windows;
  62372. }
  62373. return new PHPUnit_Util_PHP_Default;
  62374. }
  62375. /**
  62376. * Runs a single test in a separate PHP process.
  62377. *
  62378. * @param string $job
  62379. * @param PHPUnit_Framework_Test $test
  62380. * @param PHPUnit_Framework_TestResult $result
  62381. * @throws PHPUnit_Framework_Exception
  62382. */
  62383. public function runTestJob($job, PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result)
  62384. {
  62385. $result->startTest($test);
  62386. $_result = $this->runJob($job);
  62387. $this->processChildResult(
  62388. $test,
  62389. $result,
  62390. $_result['stdout'],
  62391. $_result['stderr']
  62392. );
  62393. }
  62394. /**
  62395. * Runs a single job (PHP code) using a separate PHP process.
  62396. *
  62397. * @param string $job
  62398. * @param array $settings
  62399. * @return array
  62400. * @throws PHPUnit_Framework_Exception
  62401. */
  62402. abstract public function runJob($job, array $settings = array());
  62403. /**
  62404. * @param array $settings
  62405. * @return string
  62406. * @since Method available since Release 4.0.0
  62407. */
  62408. protected function settingsToParameters(array $settings)
  62409. {
  62410. $buffer = '';
  62411. foreach ($settings as $setting) {
  62412. $buffer .= ' -d ' . $setting;
  62413. }
  62414. return $buffer;
  62415. }
  62416. /**
  62417. * Processes the TestResult object from an isolated process.
  62418. *
  62419. * @param PHPUnit_Framework_Test $test
  62420. * @param PHPUnit_Framework_TestResult $result
  62421. * @param string $stdout
  62422. * @param string $stderr
  62423. * @since Method available since Release 3.5.0
  62424. */
  62425. private function processChildResult(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result, $stdout, $stderr)
  62426. {
  62427. $time = 0;
  62428. if (!empty($stderr)) {
  62429. $result->addError(
  62430. $test,
  62431. new PHPUnit_Framework_Exception(trim($stderr)),
  62432. $time
  62433. );
  62434. } else {
  62435. set_error_handler(function ($errno, $errstr, $errfile, $errline) {
  62436. throw new ErrorException($errstr, $errno, $errno, $errfile, $errline);
  62437. });
  62438. try {
  62439. if (strpos($stdout, "#!/usr/bin/env php\n") === 0) {
  62440. $stdout = substr($stdout, 19);
  62441. }
  62442. $childResult = unserialize(str_replace("#!/usr/bin/env php\n", '', $stdout));
  62443. restore_error_handler();
  62444. } catch (ErrorException $e) {
  62445. restore_error_handler();
  62446. $childResult = false;
  62447. $result->addError(
  62448. $test,
  62449. new PHPUnit_Framework_Exception(trim($stdout), 0, $e),
  62450. $time
  62451. );
  62452. }
  62453. if ($childResult !== false) {
  62454. if (!empty($childResult['output'])) {
  62455. $output = $childResult['output'];
  62456. }
  62457. $test->setResult($childResult['testResult']);
  62458. $test->addToAssertionCount($childResult['numAssertions']);
  62459. $childResult = $childResult['result'];
  62460. if ($result->getCollectCodeCoverageInformation()) {
  62461. $result->getCodeCoverage()->merge(
  62462. $childResult->getCodeCoverage()
  62463. );
  62464. }
  62465. $time = $childResult->time();
  62466. $notImplemented = $childResult->notImplemented();
  62467. $risky = $childResult->risky();
  62468. $skipped = $childResult->skipped();
  62469. $errors = $childResult->errors();
  62470. $failures = $childResult->failures();
  62471. if (!empty($notImplemented)) {
  62472. $result->addError(
  62473. $test,
  62474. $this->getException($notImplemented[0]),
  62475. $time
  62476. );
  62477. } elseif (!empty($risky)) {
  62478. $result->addError(
  62479. $test,
  62480. $this->getException($risky[0]),
  62481. $time
  62482. );
  62483. } elseif (!empty($skipped)) {
  62484. $result->addError(
  62485. $test,
  62486. $this->getException($skipped[0]),
  62487. $time
  62488. );
  62489. } elseif (!empty($errors)) {
  62490. $result->addError(
  62491. $test,
  62492. $this->getException($errors[0]),
  62493. $time
  62494. );
  62495. } elseif (!empty($failures)) {
  62496. $result->addFailure(
  62497. $test,
  62498. $this->getException($failures[0]),
  62499. $time
  62500. );
  62501. }
  62502. }
  62503. }
  62504. $result->endTest($test, $time);
  62505. if (!empty($output)) {
  62506. print $output;
  62507. }
  62508. }
  62509. /**
  62510. * Gets the thrown exception from a PHPUnit_Framework_TestFailure.
  62511. *
  62512. * @param PHPUnit_Framework_TestFailure $error
  62513. * @return Exception
  62514. * @since Method available since Release 3.6.0
  62515. * @see https://github.com/sebastianbergmann/phpunit/issues/74
  62516. */
  62517. private function getException(PHPUnit_Framework_TestFailure $error)
  62518. {
  62519. $exception = $error->thrownException();
  62520. if ($exception instanceof __PHP_Incomplete_Class) {
  62521. $exceptionArray = array();
  62522. foreach ((array) $exception as $key => $value) {
  62523. $key = substr($key, strrpos($key, "\0") + 1);
  62524. $exceptionArray[$key] = $value;
  62525. }
  62526. $exception = new PHPUnit_Framework_SyntheticError(
  62527. sprintf(
  62528. '%s: %s',
  62529. $exceptionArray['_PHP_Incomplete_Class_Name'],
  62530. $exceptionArray['message']
  62531. ),
  62532. $exceptionArray['code'],
  62533. $exceptionArray['file'],
  62534. $exceptionArray['line'],
  62535. $exceptionArray['trace']
  62536. );
  62537. }
  62538. return $exception;
  62539. }
  62540. }
  62541. <?php
  62542. /*
  62543. * This file is part of PHPUnit.
  62544. *
  62545. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62546. *
  62547. * For the full copyright and license information, please view the LICENSE
  62548. * file that was distributed with this source code.
  62549. */
  62550. /**
  62551. * @package PHPUnit
  62552. * @subpackage Runner
  62553. * @author Sebastian Bergmann <sebastian@phpunit.de>
  62554. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  62555. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  62556. * @link http://www.phpunit.de/
  62557. * @since Class available since Release 4.0.0
  62558. */
  62559. class PHPUnit_Runner_Exception extends RuntimeException implements PHPUnit_Exception
  62560. {
  62561. }
  62562. <?php
  62563. /*
  62564. * This file is part of PHPUnit.
  62565. *
  62566. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62567. *
  62568. * For the full copyright and license information, please view the LICENSE
  62569. * file that was distributed with this source code.
  62570. */
  62571. /**
  62572. * @package PHPUnit
  62573. * @subpackage Runner
  62574. * @author Sebastian Bergmann <sebastian@phpunit.de>
  62575. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  62576. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  62577. * @link http://www.phpunit.de/
  62578. * @since Class available since Release 4.0.0
  62579. */
  62580. class PHPUnit_Runner_Filter_Test extends RecursiveFilterIterator
  62581. {
  62582. /**
  62583. * @var string
  62584. */
  62585. protected $filter = null;
  62586. /**
  62587. * @var integer
  62588. */
  62589. protected $filterMin;
  62590. /**
  62591. * @var integer
  62592. */
  62593. protected $filterMax;
  62594. /**
  62595. * @param RecursiveIterator $iterator
  62596. * @param string $filter
  62597. */
  62598. public function __construct(RecursiveIterator $iterator, $filter)
  62599. {
  62600. parent::__construct($iterator);
  62601. $this->setFilter($filter);
  62602. }
  62603. /**
  62604. * @param string $filter
  62605. */
  62606. protected function setFilter($filter)
  62607. {
  62608. if (PHPUnit_Util_Regex::pregMatchSafe($filter, '') === false) {
  62609. // Handles:
  62610. // * testAssertEqualsSucceeds#4
  62611. // * testAssertEqualsSucceeds#4-8
  62612. if (preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) {
  62613. if (isset($matches[3]) && $matches[2] < $matches[3]) {
  62614. $filter = sprintf(
  62615. '%s.*with data set #(\d+)$',
  62616. $matches[1]
  62617. );
  62618. $this->filterMin = $matches[2];
  62619. $this->filterMax = $matches[3];
  62620. } else {
  62621. $filter = sprintf(
  62622. '%s.*with data set #%s$',
  62623. $matches[1],
  62624. $matches[2]
  62625. );
  62626. }
  62627. } // Handles:
  62628. // * testDetermineJsonError@JSON_ERROR_NONE
  62629. // * testDetermineJsonError@JSON.*
  62630. elseif (preg_match('/^(.*?)@(.+)$/', $filter, $matches)) {
  62631. $filter = sprintf(
  62632. '%s.*with data set "%s"$',
  62633. $matches[1],
  62634. $matches[2]
  62635. );
  62636. }
  62637. // Escape delimiters in regular expression. Do NOT use preg_quote,
  62638. // to keep magic characters.
  62639. $filter = sprintf('/%s/', str_replace(
  62640. '/',
  62641. '\\/',
  62642. $filter
  62643. ));
  62644. }
  62645. $this->filter = $filter;
  62646. }
  62647. /**
  62648. * @return boolean
  62649. */
  62650. public function accept()
  62651. {
  62652. $test = $this->getInnerIterator()->current();
  62653. if ($test instanceof PHPUnit_Framework_TestSuite) {
  62654. return true;
  62655. }
  62656. $tmp = PHPUnit_Util_Test::describe($test, false);
  62657. if ($tmp[0] != '') {
  62658. $name = implode('::', $tmp);
  62659. } else {
  62660. $name = $tmp[1];
  62661. }
  62662. $accepted = preg_match($this->filter, $name, $matches);
  62663. if ($accepted && isset($this->filterMax)) {
  62664. $set = end($matches);
  62665. $accepted = $set >= $this->filterMin && $set <= $this->filterMax;
  62666. }
  62667. return $accepted;
  62668. }
  62669. }
  62670. <?php
  62671. /*
  62672. * This file is part of PHPUnit.
  62673. *
  62674. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62675. *
  62676. * For the full copyright and license information, please view the LICENSE
  62677. * file that was distributed with this source code.
  62678. */
  62679. /**
  62680. * @package PHPUnit
  62681. * @subpackage Runner
  62682. * @author Sebastian Bergmann <sebastian@phpunit.de>
  62683. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  62684. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  62685. * @link http://www.phpunit.de/
  62686. * @since Class available since Release 4.0.0
  62687. */
  62688. class PHPUnit_Runner_Filter_Group_Exclude extends PHPUnit_Runner_Filter_GroupFilterIterator
  62689. {
  62690. protected function doAccept($hash)
  62691. {
  62692. return !in_array($hash, $this->groupTests);
  62693. }
  62694. }
  62695. <?php
  62696. /*
  62697. * This file is part of PHPUnit.
  62698. *
  62699. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62700. *
  62701. * For the full copyright and license information, please view the LICENSE
  62702. * file that was distributed with this source code.
  62703. */
  62704. /**
  62705. * @package PHPUnit
  62706. * @subpackage Runner
  62707. * @author Sebastian Bergmann <sebastian@phpunit.de>
  62708. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  62709. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  62710. * @link http://www.phpunit.de/
  62711. * @since Class available since Release 4.0.0
  62712. */
  62713. class PHPUnit_Runner_Filter_Group_Include extends PHPUnit_Runner_Filter_GroupFilterIterator
  62714. {
  62715. protected function doAccept($hash)
  62716. {
  62717. return in_array($hash, $this->groupTests);
  62718. }
  62719. }
  62720. <?php
  62721. /*
  62722. * This file is part of PHPUnit.
  62723. *
  62724. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62725. *
  62726. * For the full copyright and license information, please view the LICENSE
  62727. * file that was distributed with this source code.
  62728. */
  62729. /**
  62730. * @package PHPUnit
  62731. * @subpackage Runner
  62732. * @author Sebastian Bergmann <sebastian@phpunit.de>
  62733. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  62734. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  62735. * @link http://www.phpunit.de/
  62736. * @since Class available since Release 4.0.0
  62737. */
  62738. class PHPUnit_Runner_Filter_Factory
  62739. {
  62740. /**
  62741. * @var array
  62742. */
  62743. private $filters = array();
  62744. /**
  62745. * @param ReflectionClass $filter
  62746. * @param mixed $args
  62747. */
  62748. public function addFilter(ReflectionClass $filter, $args)
  62749. {
  62750. if (!$filter->isSubclassOf('RecursiveFilterIterator')) {
  62751. throw new InvalidArgumentException(
  62752. sprintf(
  62753. 'Class "%s" does not extend RecursiveFilterIterator',
  62754. $filter->name
  62755. )
  62756. );
  62757. }
  62758. $this->filters[] = array($filter, $args);
  62759. }
  62760. /**
  62761. * @return FilterIterator
  62762. */
  62763. public function factory(Iterator $iterator, PHPUnit_Framework_TestSuite $suite)
  62764. {
  62765. foreach ($this->filters as $filter) {
  62766. list($class, $args) = $filter;
  62767. $iterator = $class->newInstance($iterator, $args, $suite);
  62768. }
  62769. return $iterator;
  62770. }
  62771. }
  62772. <?php
  62773. /*
  62774. * This file is part of PHPUnit.
  62775. *
  62776. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62777. *
  62778. * For the full copyright and license information, please view the LICENSE
  62779. * file that was distributed with this source code.
  62780. */
  62781. /**
  62782. * @package PHPUnit
  62783. * @subpackage Runner
  62784. * @author Sebastian Bergmann <sebastian@phpunit.de>
  62785. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  62786. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  62787. * @link http://www.phpunit.de/
  62788. * @since Class available since Release 4.0.0
  62789. */
  62790. abstract class PHPUnit_Runner_Filter_GroupFilterIterator extends RecursiveFilterIterator
  62791. {
  62792. /**
  62793. * @var array
  62794. */
  62795. protected $groupTests = array();
  62796. /**
  62797. * @param RecursiveIterator $iterator
  62798. * @param array $groups
  62799. * @param PHPUnit_Framework_TestSuite $suite
  62800. */
  62801. public function __construct(RecursiveIterator $iterator, array $groups, PHPUnit_Framework_TestSuite $suite)
  62802. {
  62803. parent::__construct($iterator);
  62804. foreach ($suite->getGroupDetails() as $group => $tests) {
  62805. if (in_array($group, $groups)) {
  62806. $testHashes = array_map(
  62807. function ($test) {
  62808. return spl_object_hash($test);
  62809. },
  62810. $tests
  62811. );
  62812. $this->groupTests = array_merge($this->groupTests, $testHashes);
  62813. }
  62814. }
  62815. }
  62816. /**
  62817. * @return boolean
  62818. */
  62819. public function accept()
  62820. {
  62821. $test = $this->getInnerIterator()->current();
  62822. if ($test instanceof PHPUnit_Framework_TestSuite) {
  62823. return true;
  62824. }
  62825. return $this->doAccept(spl_object_hash($test));
  62826. }
  62827. abstract protected function doAccept($hash);
  62828. }
  62829. <?php
  62830. /*
  62831. * This file is part of PHPUnit.
  62832. *
  62833. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62834. *
  62835. * For the full copyright and license information, please view the LICENSE
  62836. * file that was distributed with this source code.
  62837. */
  62838. /**
  62839. * An interface to define how a test suite should be loaded.
  62840. *
  62841. * @package PHPUnit
  62842. * @subpackage Runner
  62843. * @author Sebastian Bergmann <sebastian@phpunit.de>
  62844. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  62845. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  62846. * @link http://www.phpunit.de/
  62847. * @since Interface available since Release 2.0.0
  62848. */
  62849. interface PHPUnit_Runner_TestSuiteLoader
  62850. {
  62851. /**
  62852. * @param string $suiteClassName
  62853. * @param string $suiteClassFile
  62854. * @return ReflectionClass
  62855. */
  62856. public function load($suiteClassName, $suiteClassFile = '');
  62857. /**
  62858. * @param ReflectionClass $aClass
  62859. * @return ReflectionClass
  62860. */
  62861. public function reload(ReflectionClass $aClass);
  62862. }
  62863. <?php
  62864. /*
  62865. * This file is part of PHPUnit.
  62866. *
  62867. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62868. *
  62869. * For the full copyright and license information, please view the LICENSE
  62870. * file that was distributed with this source code.
  62871. */
  62872. /**
  62873. * Base class for all test runners.
  62874. *
  62875. * @package PHPUnit
  62876. * @subpackage Runner
  62877. * @author Sebastian Bergmann <sebastian@phpunit.de>
  62878. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  62879. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  62880. * @link http://www.phpunit.de/
  62881. * @since Class available since Release 2.0.0
  62882. */
  62883. abstract class PHPUnit_Runner_BaseTestRunner
  62884. {
  62885. const STATUS_PASSED = 0;
  62886. const STATUS_SKIPPED = 1;
  62887. const STATUS_INCOMPLETE = 2;
  62888. const STATUS_FAILURE = 3;
  62889. const STATUS_ERROR = 4;
  62890. const STATUS_RISKY = 5;
  62891. const SUITE_METHODNAME = 'suite';
  62892. /**
  62893. * Returns the loader to be used.
  62894. *
  62895. * @return PHPUnit_Runner_TestSuiteLoader
  62896. */
  62897. public function getLoader()
  62898. {
  62899. return new PHPUnit_Runner_StandardTestSuiteLoader;
  62900. }
  62901. /**
  62902. * Returns the Test corresponding to the given suite.
  62903. * This is a template method, subclasses override
  62904. * the runFailed() and clearStatus() methods.
  62905. *
  62906. * @param string $suiteClassName
  62907. * @param string $suiteClassFile
  62908. * @param mixed $suffixes
  62909. * @return PHPUnit_Framework_Test
  62910. */
  62911. public function getTest($suiteClassName, $suiteClassFile = '', $suffixes = '')
  62912. {
  62913. if (is_dir($suiteClassName) &&
  62914. !is_file($suiteClassName . '.php') && empty($suiteClassFile)) {
  62915. $facade = new File_Iterator_Facade;
  62916. $files = $facade->getFilesAsArray(
  62917. $suiteClassName,
  62918. $suffixes
  62919. );
  62920. $suite = new PHPUnit_Framework_TestSuite($suiteClassName);
  62921. $suite->addTestFiles($files);
  62922. return $suite;
  62923. }
  62924. try {
  62925. $testClass = $this->loadSuiteClass(
  62926. $suiteClassName,
  62927. $suiteClassFile
  62928. );
  62929. } catch (PHPUnit_Framework_Exception $e) {
  62930. $this->runFailed($e->getMessage());
  62931. return;
  62932. }
  62933. try {
  62934. $suiteMethod = $testClass->getMethod(self::SUITE_METHODNAME);
  62935. if (!$suiteMethod->isStatic()) {
  62936. $this->runFailed(
  62937. 'suite() method must be static.'
  62938. );
  62939. return;
  62940. }
  62941. try {
  62942. $test = $suiteMethod->invoke(null, $testClass->getName());
  62943. } catch (ReflectionException $e) {
  62944. $this->runFailed(
  62945. sprintf(
  62946. "Failed to invoke suite() method.\n%s",
  62947. $e->getMessage()
  62948. )
  62949. );
  62950. return;
  62951. }
  62952. } catch (ReflectionException $e) {
  62953. try {
  62954. $test = new PHPUnit_Framework_TestSuite($testClass);
  62955. } catch (PHPUnit_Framework_Exception $e) {
  62956. $test = new PHPUnit_Framework_TestSuite;
  62957. $test->setName($suiteClassName);
  62958. }
  62959. }
  62960. $this->clearStatus();
  62961. return $test;
  62962. }
  62963. /**
  62964. * Returns the loaded ReflectionClass for a suite name.
  62965. *
  62966. * @param string $suiteClassName
  62967. * @param string $suiteClassFile
  62968. * @return ReflectionClass
  62969. */
  62970. protected function loadSuiteClass($suiteClassName, $suiteClassFile = '')
  62971. {
  62972. $loader = $this->getLoader();
  62973. return $loader->load($suiteClassName, $suiteClassFile);
  62974. }
  62975. /**
  62976. * Clears the status message.
  62977. *
  62978. */
  62979. protected function clearStatus()
  62980. {
  62981. }
  62982. /**
  62983. * Override to define how to handle a failed loading of
  62984. * a test suite.
  62985. *
  62986. * @param string $message
  62987. */
  62988. abstract protected function runFailed($message);
  62989. }
  62990. <?php
  62991. /*
  62992. * This file is part of PHPUnit.
  62993. *
  62994. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62995. *
  62996. * For the full copyright and license information, please view the LICENSE
  62997. * file that was distributed with this source code.
  62998. */
  62999. /**
  63000. * The standard test suite loader.
  63001. *
  63002. * @package PHPUnit
  63003. * @subpackage Runner
  63004. * @author Sebastian Bergmann <sebastian@phpunit.de>
  63005. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  63006. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  63007. * @link http://www.phpunit.de/
  63008. * @since Class available since Release 2.0.0
  63009. */
  63010. class PHPUnit_Runner_StandardTestSuiteLoader implements PHPUnit_Runner_TestSuiteLoader
  63011. {
  63012. /**
  63013. * @param string $suiteClassName
  63014. * @param string $suiteClassFile
  63015. * @return ReflectionClass
  63016. * @throws PHPUnit_Framework_Exception
  63017. */
  63018. public function load($suiteClassName, $suiteClassFile = '')
  63019. {
  63020. $suiteClassName = str_replace('.php', '', $suiteClassName);
  63021. if (empty($suiteClassFile)) {
  63022. $suiteClassFile = PHPUnit_Util_Filesystem::classNameToFilename(
  63023. $suiteClassName
  63024. );
  63025. }
  63026. if (!class_exists($suiteClassName, false)) {
  63027. $loadedClasses = get_declared_classes();
  63028. $filename = PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile);
  63029. $loadedClasses = array_values(
  63030. array_diff(get_declared_classes(), $loadedClasses)
  63031. );
  63032. }
  63033. if (!class_exists($suiteClassName, false) && !empty($loadedClasses)) {
  63034. $offset = 0 - strlen($suiteClassName);
  63035. foreach ($loadedClasses as $loadedClass) {
  63036. $class = new ReflectionClass($loadedClass);
  63037. if (substr($loadedClass, $offset) === $suiteClassName &&
  63038. $class->getFileName() == $filename) {
  63039. $suiteClassName = $loadedClass;
  63040. break;
  63041. }
  63042. }
  63043. }
  63044. if (!class_exists($suiteClassName, false) && !empty($loadedClasses)) {
  63045. $testCaseClass = 'PHPUnit_Framework_TestCase';
  63046. foreach ($loadedClasses as $loadedClass) {
  63047. $class = new ReflectionClass($loadedClass);
  63048. $classFile = $class->getFileName();
  63049. if ($class->isSubclassOf($testCaseClass) &&
  63050. !$class->isAbstract()) {
  63051. $suiteClassName = $loadedClass;
  63052. $testCaseClass = $loadedClass;
  63053. if ($classFile == realpath($suiteClassFile)) {
  63054. break;
  63055. }
  63056. }
  63057. if ($class->hasMethod('suite')) {
  63058. $method = $class->getMethod('suite');
  63059. if (!$method->isAbstract() &&
  63060. $method->isPublic() &&
  63061. $method->isStatic()) {
  63062. $suiteClassName = $loadedClass;
  63063. if ($classFile == realpath($suiteClassFile)) {
  63064. break;
  63065. }
  63066. }
  63067. }
  63068. }
  63069. }
  63070. if (class_exists($suiteClassName, false)) {
  63071. $class = new ReflectionClass($suiteClassName);
  63072. if ($class->getFileName() == realpath($suiteClassFile)) {
  63073. return $class;
  63074. }
  63075. }
  63076. throw new PHPUnit_Framework_Exception(
  63077. sprintf(
  63078. "Class '%s' could not be found in '%s'.",
  63079. $suiteClassName,
  63080. $suiteClassFile
  63081. )
  63082. );
  63083. }
  63084. /**
  63085. * @param ReflectionClass $aClass
  63086. * @return ReflectionClass
  63087. */
  63088. public function reload(ReflectionClass $aClass)
  63089. {
  63090. return $aClass;
  63091. }
  63092. }
  63093. <?php
  63094. /*
  63095. * This file is part of PHPUnit.
  63096. *
  63097. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63098. *
  63099. * For the full copyright and license information, please view the LICENSE
  63100. * file that was distributed with this source code.
  63101. */
  63102. /**
  63103. * This class defines the current version of PHPUnit.
  63104. *
  63105. * @package PHPUnit
  63106. * @subpackage Runner
  63107. * @author Sebastian Bergmann <sebastian@phpunit.de>
  63108. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  63109. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  63110. * @link http://www.phpunit.de/
  63111. * @since Class available since Release 2.0.0
  63112. */
  63113. class PHPUnit_Runner_Version
  63114. {
  63115. private static $pharVersion = "4.7.0";
  63116. private static $version;
  63117. /**
  63118. * Returns the current version of PHPUnit.
  63119. *
  63120. * @return string
  63121. */
  63122. public static function id()
  63123. {
  63124. if (self::$pharVersion !== null) {
  63125. return self::$pharVersion;
  63126. }
  63127. if (self::$version === null) {
  63128. $version = new SebastianBergmann\Version('4.7.0', dirname(dirname(__DIR__)));
  63129. self::$version = $version->getVersion();
  63130. }
  63131. return self::$version;
  63132. }
  63133. /**
  63134. * @return string
  63135. */
  63136. public static function getVersionString()
  63137. {
  63138. return 'PHPUnit ' . self::id() . ' by Sebastian Bergmann and contributors.';
  63139. }
  63140. /**
  63141. * @return string
  63142. * @since Method available since Release 4.0.0
  63143. */
  63144. public static function getReleaseChannel()
  63145. {
  63146. if (strpos(self::$pharVersion, 'alpha') !== false) {
  63147. return '-alpha';
  63148. }
  63149. if (strpos(self::$pharVersion, 'beta') !== false) {
  63150. return '-beta';
  63151. }
  63152. return '';
  63153. }
  63154. }
  63155. Environment
  63156. Copyright (c) 2014-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  63157. All rights reserved.
  63158. Redistribution and use in source and binary forms, with or without
  63159. modification, are permitted provided that the following conditions
  63160. are met:
  63161. * Redistributions of source code must retain the above copyright
  63162. notice, this list of conditions and the following disclaimer.
  63163. * Redistributions in binary form must reproduce the above copyright
  63164. notice, this list of conditions and the following disclaimer in
  63165. the documentation and/or other materials provided with the
  63166. distribution.
  63167. * Neither the name of Sebastian Bergmann nor the names of his
  63168. contributors may be used to endorse or promote products derived
  63169. from this software without specific prior written permission.
  63170. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  63171. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  63172. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  63173. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  63174. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  63175. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  63176. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  63177. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  63178. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  63179. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  63180. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  63181. POSSIBILITY OF SUCH DAMAGE.
  63182. <?php
  63183. /*
  63184. * This file is part of the Environment package.
  63185. *
  63186. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63187. *
  63188. * For the full copyright and license information, please view the LICENSE
  63189. * file that was distributed with this source code.
  63190. */
  63191. namespace SebastianBergmann\Environment;
  63192. /**
  63193. * Utility class for HHVM/PHP environment handling.
  63194. *
  63195. * @package Environment
  63196. * @author Sebastian Bergmann <sebastian@phpunit.de>
  63197. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  63198. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  63199. * @link http://www.github.com/sebastianbergmann/environment
  63200. */
  63201. class Runtime
  63202. {
  63203. /**
  63204. * @var string
  63205. */
  63206. private static $binary;
  63207. /**
  63208. * Returns true when the runtime used is HHVM or
  63209. * the runtime used is PHP + Xdebug.
  63210. *
  63211. * @return boolean
  63212. */
  63213. public function canCollectCodeCoverage()
  63214. {
  63215. return $this->isHHVM() || $this->hasXdebug();
  63216. }
  63217. /**
  63218. * Returns the path to the binary of the current runtime.
  63219. * Appends ' --php' to the path when the runtime is HHVM.
  63220. *
  63221. * @return string
  63222. */
  63223. public function getBinary()
  63224. {
  63225. // HHVM
  63226. if (self::$binary === null && $this->isHHVM()) {
  63227. if ((self::$binary = getenv('PHP_BINARY')) === false) {
  63228. self::$binary = PHP_BINARY;
  63229. }
  63230. self::$binary = escapeshellarg(self::$binary) . ' --php';
  63231. }
  63232. // PHP >= 5.4.0
  63233. if (self::$binary === null && defined('PHP_BINARY')) {
  63234. self::$binary = escapeshellarg(PHP_BINARY);
  63235. }
  63236. // PHP < 5.4.0
  63237. if (self::$binary === null) {
  63238. if (PHP_SAPI == 'cli' && isset($_SERVER['_'])) {
  63239. if (strpos($_SERVER['_'], 'phpunit') !== false) {
  63240. $file = file($_SERVER['_']);
  63241. if (strpos($file[0], ' ') !== false) {
  63242. $tmp = explode(' ', $file[0]);
  63243. self::$binary = escapeshellarg(trim($tmp[1]));
  63244. } else {
  63245. self::$binary = escapeshellarg(ltrim(trim($file[0]), '#!'));
  63246. }
  63247. } elseif (strpos(basename($_SERVER['_']), 'php') !== false) {
  63248. self::$binary = escapeshellarg($_SERVER['_']);
  63249. }
  63250. }
  63251. }
  63252. if (self::$binary === null) {
  63253. $possibleBinaryLocations = array(
  63254. PHP_BINDIR . '/php',
  63255. PHP_BINDIR . '/php-cli.exe',
  63256. PHP_BINDIR . '/php.exe'
  63257. );
  63258. foreach ($possibleBinaryLocations as $binary) {
  63259. if (is_readable($binary)) {
  63260. self::$binary = escapeshellarg($binary);
  63261. break;
  63262. }
  63263. }
  63264. }
  63265. if (self::$binary === null) {
  63266. self::$binary = 'php';
  63267. }
  63268. return self::$binary;
  63269. }
  63270. /**
  63271. * @return string
  63272. */
  63273. public function getNameWithVersion()
  63274. {
  63275. return $this->getName() . ' ' . $this->getVersion();
  63276. }
  63277. /**
  63278. * @return string
  63279. */
  63280. public function getName()
  63281. {
  63282. if ($this->isHHVM()) {
  63283. return 'HHVM';
  63284. } else {
  63285. return 'PHP';
  63286. }
  63287. }
  63288. /**
  63289. * @return string
  63290. */
  63291. public function getVendorUrl()
  63292. {
  63293. if ($this->isHHVM()) {
  63294. return 'http://hhvm.com/';
  63295. } else {
  63296. return 'http://php.net/';
  63297. }
  63298. }
  63299. /**
  63300. * @return string
  63301. */
  63302. public function getVersion()
  63303. {
  63304. if ($this->isHHVM()) {
  63305. return HHVM_VERSION;
  63306. } else {
  63307. return PHP_VERSION;
  63308. }
  63309. }
  63310. /**
  63311. * Returns true when the runtime used is PHP and Xdebug is loaded.
  63312. *
  63313. * @return boolean
  63314. */
  63315. public function hasXdebug()
  63316. {
  63317. return $this->isPHP() && extension_loaded('xdebug');
  63318. }
  63319. /**
  63320. * Returns true when the runtime used is HHVM.
  63321. *
  63322. * @return boolean
  63323. */
  63324. public function isHHVM()
  63325. {
  63326. return defined('HHVM_VERSION');
  63327. }
  63328. /**
  63329. * Returns true when the runtime used is PHP.
  63330. *
  63331. * @return boolean
  63332. */
  63333. public function isPHP()
  63334. {
  63335. return !$this->isHHVM();
  63336. }
  63337. }
  63338. <?php
  63339. /*
  63340. * This file is part of the Environment package.
  63341. *
  63342. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  63343. *
  63344. * For the full copyright and license information, please view the LICENSE
  63345. * file that was distributed with this source code.
  63346. */
  63347. namespace SebastianBergmann\Environment;
  63348. /**
  63349. * @package Environment
  63350. * @author Sebastian Bergmann <sebastian@phpunit.de>
  63351. * @copyright 2014 Sebastian Bergmann <sebastian@phpunit.de>
  63352. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  63353. * @link http://www.github.com/sebastianbergmann/environment
  63354. */
  63355. class Console
  63356. {
  63357. const STDIN = 0;
  63358. const STDOUT = 1;
  63359. const STDERR = 2;
  63360. /**
  63361. * Returns true if STDOUT supports colorization.
  63362. *
  63363. * This code has been copied and adapted from
  63364. * Symfony\Component\Console\Output\OutputStream.
  63365. *
  63366. * @return boolean
  63367. */
  63368. public function hasColorSupport()
  63369. {
  63370. if (DIRECTORY_SEPARATOR == '\\') {
  63371. return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
  63372. }
  63373. if (!defined('STDOUT')) {
  63374. return false;
  63375. }
  63376. return $this->isInteractive(STDOUT);
  63377. }
  63378. /**
  63379. * Returns the number of columns of the terminal.
  63380. *
  63381. * @return integer
  63382. */
  63383. public function getNumberOfColumns()
  63384. {
  63385. // Windows terminals have a fixed size of 80
  63386. // but one column is used for the cursor.
  63387. if (DIRECTORY_SEPARATOR == '\\') {
  63388. return 79;
  63389. }
  63390. if (!$this->isInteractive(self::STDIN)) {
  63391. return 80;
  63392. }
  63393. if (preg_match('#\d+ (\d+)#', shell_exec('stty size'), $match) === 1) {
  63394. return (int) $match[1];
  63395. }
  63396. if (preg_match('#columns = (\d+);#', shell_exec('stty'), $match) === 1) {
  63397. return (int) $match[1];
  63398. }
  63399. return 80;
  63400. }
  63401. /**
  63402. * Returns if the file descriptor is an interactive terminal or not.
  63403. *
  63404. * @param int|resource $fileDescriptor
  63405. *
  63406. * @return boolean
  63407. */
  63408. public function isInteractive($fileDescriptor = self::STDOUT)
  63409. {
  63410. return function_exists('posix_isatty') && @posix_isatty($fileDescriptor);
  63411. }
  63412. }
  63413. The MIT License (MIT)
  63414. Copyright (c) 2010 Mike van Riel
  63415. Permission is hereby granted, free of charge, to any person obtaining a copy
  63416. of this software and associated documentation files (the "Software"), to deal
  63417. in the Software without restriction, including without limitation the rights
  63418. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  63419. copies of the Software, and to permit persons to whom the Software is
  63420. furnished to do so, subject to the following conditions:
  63421. The above copyright notice and this permission notice shall be included in
  63422. all copies or substantial portions of the Software.
  63423. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  63424. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  63425. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  63426. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  63427. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  63428. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  63429. THE SOFTWARE.
  63430. <?php
  63431. /**
  63432. * phpDocumentor
  63433. *
  63434. * PHP Version 5.3
  63435. *
  63436. * @author Mike van Riel <mike.vanriel@naenius.com>
  63437. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63438. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63439. * @link http://phpdoc.org
  63440. */
  63441. namespace phpDocumentor\Reflection;
  63442. use phpDocumentor\Reflection\DocBlock\Tag;
  63443. use phpDocumentor\Reflection\DocBlock\Context;
  63444. use phpDocumentor\Reflection\DocBlock\Location;
  63445. /**
  63446. * Parses the DocBlock for any structure.
  63447. *
  63448. * @author Mike van Riel <mike.vanriel@naenius.com>
  63449. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63450. * @link http://phpdoc.org
  63451. */
  63452. class DocBlock implements \Reflector
  63453. {
  63454. /** @var string The opening line for this docblock. */
  63455. protected $short_description = '';
  63456. /**
  63457. * @var DocBlock\Description The actual
  63458. * description for this docblock.
  63459. */
  63460. protected $long_description = null;
  63461. /**
  63462. * @var Tag[] An array containing all
  63463. * the tags in this docblock; except inline.
  63464. */
  63465. protected $tags = array();
  63466. /** @var Context Information about the context of this DocBlock. */
  63467. protected $context = null;
  63468. /** @var Location Information about the location of this DocBlock. */
  63469. protected $location = null;
  63470. /** @var bool Is this DocBlock (the start of) a template? */
  63471. protected $isTemplateStart = false;
  63472. /** @var bool Does this DocBlock signify the end of a DocBlock template? */
  63473. protected $isTemplateEnd = false;
  63474. /**
  63475. * Parses the given docblock and populates the member fields.
  63476. *
  63477. * The constructor may also receive namespace information such as the
  63478. * current namespace and aliases. This information is used by some tags
  63479. * (e.g. @return, @param, etc.) to turn a relative Type into a FQCN.
  63480. *
  63481. * @param \Reflector|string $docblock A docblock comment (including
  63482. * asterisks) or reflector supporting the getDocComment method.
  63483. * @param Context $context The context in which the DocBlock
  63484. * occurs.
  63485. * @param Location $location The location within the file that this
  63486. * DocBlock occurs in.
  63487. *
  63488. * @throws \InvalidArgumentException if the given argument does not have the
  63489. * getDocComment method.
  63490. */
  63491. public function __construct(
  63492. $docblock,
  63493. Context $context = null,
  63494. Location $location = null
  63495. ) {
  63496. if (is_object($docblock)) {
  63497. if (!method_exists($docblock, 'getDocComment')) {
  63498. throw new \InvalidArgumentException(
  63499. 'Invalid object passed; the given reflector must support '
  63500. . 'the getDocComment method'
  63501. );
  63502. }
  63503. $docblock = $docblock->getDocComment();
  63504. }
  63505. $docblock = $this->cleanInput($docblock);
  63506. list($templateMarker, $short, $long, $tags) = $this->splitDocBlock($docblock);
  63507. $this->isTemplateStart = $templateMarker === '#@+';
  63508. $this->isTemplateEnd = $templateMarker === '#@-';
  63509. $this->short_description = $short;
  63510. $this->long_description = new DocBlock\Description($long, $this);
  63511. $this->parseTags($tags);
  63512. $this->context = $context;
  63513. $this->location = $location;
  63514. }
  63515. /**
  63516. * Strips the asterisks from the DocBlock comment.
  63517. *
  63518. * @param string $comment String containing the comment text.
  63519. *
  63520. * @return string
  63521. */
  63522. protected function cleanInput($comment)
  63523. {
  63524. $comment = trim(
  63525. preg_replace(
  63526. '#[ \t]*(?:\/\*\*|\*\/|\*)?[ \t]{0,1}(.*)?#u',
  63527. '$1',
  63528. $comment
  63529. )
  63530. );
  63531. // reg ex above is not able to remove */ from a single line docblock
  63532. if (substr($comment, -2) == '*/') {
  63533. $comment = trim(substr($comment, 0, -2));
  63534. }
  63535. // normalize strings
  63536. $comment = str_replace(array("\r\n", "\r"), "\n", $comment);
  63537. return $comment;
  63538. }
  63539. /**
  63540. * Splits the DocBlock into a template marker, summary, description and block of tags.
  63541. *
  63542. * @param string $comment Comment to split into the sub-parts.
  63543. *
  63544. * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split.
  63545. * @author Mike van Riel <me@mikevanriel.com> for extending the regex with template marker support.
  63546. *
  63547. * @return string[] containing the template marker (if any), summary, description and a string containing the tags.
  63548. */
  63549. protected function splitDocBlock($comment)
  63550. {
  63551. // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This
  63552. // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the
  63553. // performance impact of running a regular expression
  63554. if (strpos($comment, '@') === 0) {
  63555. return array('', '', '', $comment);
  63556. }
  63557. // clears all extra horizontal whitespace from the line endings to prevent parsing issues
  63558. $comment = preg_replace('/\h*$/Sum', '', $comment);
  63559. /*
  63560. * Splits the docblock into a template marker, short description, long description and tags section
  63561. *
  63562. * - The template marker is empty, #@+ or #@- if the DocBlock starts with either of those (a newline may
  63563. * occur after it and will be stripped).
  63564. * - The short description is started from the first character until a dot is encountered followed by a
  63565. * newline OR two consecutive newlines (horizontal whitespace is taken into account to consider spacing
  63566. * errors). This is optional.
  63567. * - The long description, any character until a new line is encountered followed by an @ and word
  63568. * characters (a tag). This is optional.
  63569. * - Tags; the remaining characters
  63570. *
  63571. * Big thanks to RichardJ for contributing this Regular Expression
  63572. */
  63573. preg_match(
  63574. '/
  63575. \A
  63576. # 1. Extract the template marker
  63577. (?:(\#\@\+|\#\@\-)\n?)?
  63578. # 2. Extract the summary
  63579. (?:
  63580. (?! @\pL ) # The summary may not start with an @
  63581. (
  63582. [^\n.]+
  63583. (?:
  63584. (?! \. \n | \n{2} ) # End summary upon a dot followed by newline or two newlines
  63585. [\n.] (?! [ \t]* @\pL ) # End summary when an @ is found as first character on a new line
  63586. [^\n.]+ # Include anything else
  63587. )*
  63588. \.?
  63589. )?
  63590. )
  63591. # 3. Extract the description
  63592. (?:
  63593. \s* # Some form of whitespace _must_ precede a description because a summary must be there
  63594. (?! @\pL ) # The description may not start with an @
  63595. (
  63596. [^\n]+
  63597. (?: \n+
  63598. (?! [ \t]* @\pL ) # End description when an @ is found as first character on a new line
  63599. [^\n]+ # Include anything else
  63600. )*
  63601. )
  63602. )?
  63603. # 4. Extract the tags (anything that follows)
  63604. (\s+ [\s\S]*)? # everything that follows
  63605. /ux',
  63606. $comment,
  63607. $matches
  63608. );
  63609. array_shift($matches);
  63610. while (count($matches) < 4) {
  63611. $matches[] = '';
  63612. }
  63613. return $matches;
  63614. }
  63615. /**
  63616. * Creates the tag objects.
  63617. *
  63618. * @param string $tags Tag block to parse.
  63619. *
  63620. * @return void
  63621. */
  63622. protected function parseTags($tags)
  63623. {
  63624. $result = array();
  63625. $tags = trim($tags);
  63626. if ('' !== $tags) {
  63627. if ('@' !== $tags[0]) {
  63628. throw new \LogicException(
  63629. 'A tag block started with text instead of an actual tag,'
  63630. . ' this makes the tag block invalid: ' . $tags
  63631. );
  63632. }
  63633. foreach (explode("\n", $tags) as $tag_line) {
  63634. if (isset($tag_line[0]) && ($tag_line[0] === '@')) {
  63635. $result[] = $tag_line;
  63636. } else {
  63637. $result[count($result) - 1] .= "\n" . $tag_line;
  63638. }
  63639. }
  63640. // create proper Tag objects
  63641. foreach ($result as $key => $tag_line) {
  63642. $result[$key] = Tag::createInstance(trim($tag_line), $this);
  63643. }
  63644. }
  63645. $this->tags = $result;
  63646. }
  63647. /**
  63648. * Gets the text portion of the doc block.
  63649. *
  63650. * Gets the text portion (short and long description combined) of the doc
  63651. * block.
  63652. *
  63653. * @return string The text portion of the doc block.
  63654. */
  63655. public function getText()
  63656. {
  63657. $short = $this->getShortDescription();
  63658. $long = $this->getLongDescription()->getContents();
  63659. if ($long) {
  63660. return "{$short}\n\n{$long}";
  63661. } else {
  63662. return $short;
  63663. }
  63664. }
  63665. /**
  63666. * Set the text portion of the doc block.
  63667. *
  63668. * Sets the text portion (short and long description combined) of the doc
  63669. * block.
  63670. *
  63671. * @param string $docblock The new text portion of the doc block.
  63672. *
  63673. * @return $this This doc block.
  63674. */
  63675. public function setText($comment)
  63676. {
  63677. list(,$short, $long) = $this->splitDocBlock($comment);
  63678. $this->short_description = $short;
  63679. $this->long_description = new DocBlock\Description($long, $this);
  63680. return $this;
  63681. }
  63682. /**
  63683. * Returns the opening line or also known as short description.
  63684. *
  63685. * @return string
  63686. */
  63687. public function getShortDescription()
  63688. {
  63689. return $this->short_description;
  63690. }
  63691. /**
  63692. * Returns the full description or also known as long description.
  63693. *
  63694. * @return DocBlock\Description
  63695. */
  63696. public function getLongDescription()
  63697. {
  63698. return $this->long_description;
  63699. }
  63700. /**
  63701. * Returns whether this DocBlock is the start of a Template section.
  63702. *
  63703. * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker
  63704. * (`#@+`) that is appended directly after the opening `/**` of a DocBlock.
  63705. *
  63706. * An example of such an opening is:
  63707. *
  63708. * ```
  63709. * /**#@+
  63710. * * My DocBlock
  63711. * * /
  63712. * ```
  63713. *
  63714. * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all
  63715. * elements that follow until another DocBlock is found that contains the closing marker (`#@-`).
  63716. *
  63717. * @see self::isTemplateEnd() for the check whether a closing marker was provided.
  63718. *
  63719. * @return boolean
  63720. */
  63721. public function isTemplateStart()
  63722. {
  63723. return $this->isTemplateStart;
  63724. }
  63725. /**
  63726. * Returns whether this DocBlock is the end of a Template section.
  63727. *
  63728. * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality.
  63729. *
  63730. * @return boolean
  63731. */
  63732. public function isTemplateEnd()
  63733. {
  63734. return $this->isTemplateEnd;
  63735. }
  63736. /**
  63737. * Returns the current context.
  63738. *
  63739. * @return Context
  63740. */
  63741. public function getContext()
  63742. {
  63743. return $this->context;
  63744. }
  63745. /**
  63746. * Returns the current location.
  63747. *
  63748. * @return Location
  63749. */
  63750. public function getLocation()
  63751. {
  63752. return $this->location;
  63753. }
  63754. /**
  63755. * Returns the tags for this DocBlock.
  63756. *
  63757. * @return Tag[]
  63758. */
  63759. public function getTags()
  63760. {
  63761. return $this->tags;
  63762. }
  63763. /**
  63764. * Returns an array of tags matching the given name. If no tags are found
  63765. * an empty array is returned.
  63766. *
  63767. * @param string $name String to search by.
  63768. *
  63769. * @return Tag[]
  63770. */
  63771. public function getTagsByName($name)
  63772. {
  63773. $result = array();
  63774. /** @var Tag $tag */
  63775. foreach ($this->getTags() as $tag) {
  63776. if ($tag->getName() != $name) {
  63777. continue;
  63778. }
  63779. $result[] = $tag;
  63780. }
  63781. return $result;
  63782. }
  63783. /**
  63784. * Checks if a tag of a certain type is present in this DocBlock.
  63785. *
  63786. * @param string $name Tag name to check for.
  63787. *
  63788. * @return bool
  63789. */
  63790. public function hasTag($name)
  63791. {
  63792. /** @var Tag $tag */
  63793. foreach ($this->getTags() as $tag) {
  63794. if ($tag->getName() == $name) {
  63795. return true;
  63796. }
  63797. }
  63798. return false;
  63799. }
  63800. /**
  63801. * Appends a tag at the end of the list of tags.
  63802. *
  63803. * @param Tag $tag The tag to add.
  63804. *
  63805. * @return Tag The newly added tag.
  63806. *
  63807. * @throws \LogicException When the tag belongs to a different DocBlock.
  63808. */
  63809. public function appendTag(Tag $tag)
  63810. {
  63811. if (null === $tag->getDocBlock()) {
  63812. $tag->setDocBlock($this);
  63813. }
  63814. if ($tag->getDocBlock() === $this) {
  63815. $this->tags[] = $tag;
  63816. } else {
  63817. throw new \LogicException(
  63818. 'This tag belongs to a different DocBlock object.'
  63819. );
  63820. }
  63821. return $tag;
  63822. }
  63823. /**
  63824. * Builds a string representation of this object.
  63825. *
  63826. * @todo determine the exact format as used by PHP Reflection and
  63827. * implement it.
  63828. *
  63829. * @return string
  63830. * @codeCoverageIgnore Not yet implemented
  63831. */
  63832. public static function export()
  63833. {
  63834. throw new \Exception('Not yet implemented');
  63835. }
  63836. /**
  63837. * Returns the exported information (we should use the export static method
  63838. * BUT this throws an exception at this point).
  63839. *
  63840. * @return string
  63841. * @codeCoverageIgnore Not yet implemented
  63842. */
  63843. public function __toString()
  63844. {
  63845. return 'Not yet implemented';
  63846. }
  63847. }
  63848. <?php
  63849. /**
  63850. * phpDocumentor
  63851. *
  63852. * PHP Version 5.3
  63853. *
  63854. * @author Vasil Rangelov <boen.robot@gmail.com>
  63855. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63856. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63857. * @link http://phpdoc.org
  63858. */
  63859. namespace phpDocumentor\Reflection\DocBlock;
  63860. /**
  63861. * The location a DocBlock occurs within a file.
  63862. *
  63863. * @author Vasil Rangelov <boen.robot@gmail.com>
  63864. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63865. * @link http://phpdoc.org
  63866. */
  63867. class Location
  63868. {
  63869. /** @var int Line where the DocBlock text starts. */
  63870. protected $lineNumber = 0;
  63871. /** @var int Column where the DocBlock text starts. */
  63872. protected $columnNumber = 0;
  63873. public function __construct(
  63874. $lineNumber = 0,
  63875. $columnNumber = 0
  63876. ) {
  63877. $this->setLineNumber($lineNumber)->setColumnNumber($columnNumber);
  63878. }
  63879. /**
  63880. * @return int Line where the DocBlock text starts.
  63881. */
  63882. public function getLineNumber()
  63883. {
  63884. return $this->lineNumber;
  63885. }
  63886. /**
  63887. *
  63888. * @param type $lineNumber
  63889. * @return $this
  63890. */
  63891. public function setLineNumber($lineNumber)
  63892. {
  63893. $this->lineNumber = (int)$lineNumber;
  63894. return $this;
  63895. }
  63896. /**
  63897. * @return int Column where the DocBlock text starts.
  63898. */
  63899. public function getColumnNumber()
  63900. {
  63901. return $this->columnNumber;
  63902. }
  63903. /**
  63904. *
  63905. * @param int $columnNumber
  63906. * @return $this
  63907. */
  63908. public function setColumnNumber($columnNumber)
  63909. {
  63910. $this->columnNumber = (int)$columnNumber;
  63911. return $this;
  63912. }
  63913. }
  63914. <?php
  63915. /**
  63916. * phpDocumentor
  63917. *
  63918. * PHP Version 5.3
  63919. *
  63920. * @author Vasil Rangelov <boen.robot@gmail.com>
  63921. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63922. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63923. * @link http://phpdoc.org
  63924. */
  63925. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63926. use phpDocumentor\Reflection\DocBlock\Tag\VersionTag;
  63927. /**
  63928. * Reflection class for a @since tag in a Docblock.
  63929. *
  63930. * @author Vasil Rangelov <boen.robot@gmail.com>
  63931. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63932. * @link http://phpdoc.org
  63933. */
  63934. class SinceTag extends VersionTag
  63935. {
  63936. }
  63937. <?php
  63938. /**
  63939. * phpDocumentor
  63940. *
  63941. * PHP Version 5.3
  63942. *
  63943. * @author Mike van Riel <mike.vanriel@naenius.com>
  63944. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63945. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63946. * @link http://phpdoc.org
  63947. */
  63948. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63949. use phpDocumentor\Reflection\DocBlock\Tag;
  63950. /**
  63951. * Reflection class for a @see tag in a Docblock.
  63952. *
  63953. * @author Mike van Riel <mike.vanriel@naenius.com>
  63954. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63955. * @link http://phpdoc.org
  63956. */
  63957. class SeeTag extends Tag
  63958. {
  63959. /** @var string */
  63960. protected $refers = null;
  63961. /**
  63962. * {@inheritdoc}
  63963. */
  63964. public function getContent()
  63965. {
  63966. if (null === $this->content) {
  63967. $this->content = "{$this->refers} {$this->description}";
  63968. }
  63969. return $this->content;
  63970. }
  63971. /**
  63972. * {@inheritdoc}
  63973. */
  63974. public function setContent($content)
  63975. {
  63976. parent::setContent($content);
  63977. $parts = preg_split('/\s+/Su', $this->description, 2);
  63978. // any output is considered a type
  63979. $this->refers = $parts[0];
  63980. $this->setDescription(isset($parts[1]) ? $parts[1] : '');
  63981. $this->content = $content;
  63982. return $this;
  63983. }
  63984. /**
  63985. * Gets the structural element this tag refers to.
  63986. *
  63987. * @return string
  63988. */
  63989. public function getReference()
  63990. {
  63991. return $this->refers;
  63992. }
  63993. /**
  63994. * Sets the structural element this tag refers to.
  63995. *
  63996. * @param string $refers The new type this tag refers to.
  63997. *
  63998. * @return $this
  63999. */
  64000. public function setReference($refers)
  64001. {
  64002. $this->refers = $refers;
  64003. $this->content = null;
  64004. return $this;
  64005. }
  64006. }
  64007. <?php
  64008. /**
  64009. * phpDocumentor
  64010. *
  64011. * PHP Version 5.3
  64012. *
  64013. * @author Vasil Rangelov <boen.robot@gmail.com>
  64014. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64015. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64016. * @link http://phpdoc.org
  64017. */
  64018. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64019. use phpDocumentor\Reflection\DocBlock\Tag;
  64020. /**
  64021. * Reflection class for a @version tag in a Docblock.
  64022. *
  64023. * @author Vasil Rangelov <boen.robot@gmail.com>
  64024. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64025. * @link http://phpdoc.org
  64026. */
  64027. class VersionTag extends Tag
  64028. {
  64029. /**
  64030. * PCRE regular expression matching a version vector.
  64031. * Assumes the "x" modifier.
  64032. */
  64033. const REGEX_VECTOR = '(?:
  64034. # Normal release vectors.
  64035. \d\S*
  64036. |
  64037. # VCS version vectors. Per PHPCS, they are expected to
  64038. # follow the form of the VCS name, followed by ":", followed
  64039. # by the version vector itself.
  64040. # By convention, popular VCSes like CVS, SVN and GIT use "$"
  64041. # around the actual version vector.
  64042. [^\s\:]+\:\s*\$[^\$]+\$
  64043. )';
  64044. /** @var string The version vector. */
  64045. protected $version = '';
  64046. public function getContent()
  64047. {
  64048. if (null === $this->content) {
  64049. $this->content = "{$this->version} {$this->description}";
  64050. }
  64051. return $this->content;
  64052. }
  64053. /**
  64054. * {@inheritdoc}
  64055. */
  64056. public function setContent($content)
  64057. {
  64058. parent::setContent($content);
  64059. if (preg_match(
  64060. '/^
  64061. # The version vector
  64062. (' . self::REGEX_VECTOR . ')
  64063. \s*
  64064. # The description
  64065. (.+)?
  64066. $/sux',
  64067. $this->description,
  64068. $matches
  64069. )) {
  64070. $this->version = $matches[1];
  64071. $this->setDescription(isset($matches[2]) ? $matches[2] : '');
  64072. $this->content = $content;
  64073. }
  64074. return $this;
  64075. }
  64076. /**
  64077. * Gets the version section of the tag.
  64078. *
  64079. * @return string The version section of the tag.
  64080. */
  64081. public function getVersion()
  64082. {
  64083. return $this->version;
  64084. }
  64085. /**
  64086. * Sets the version section of the tag.
  64087. *
  64088. * @param string $version The new version section of the tag.
  64089. * An invalid value will set an empty string.
  64090. *
  64091. * @return $this
  64092. */
  64093. public function setVersion($version)
  64094. {
  64095. $this->version
  64096. = preg_match('/^' . self::REGEX_VECTOR . '$/ux', $version)
  64097. ? $version
  64098. : '';
  64099. $this->content = null;
  64100. return $this;
  64101. }
  64102. }
  64103. <?php
  64104. /**
  64105. * phpDocumentor
  64106. *
  64107. * PHP Version 5.3
  64108. *
  64109. * @author Mike van Riel <mike.vanriel@naenius.com>
  64110. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64111. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64112. * @link http://phpdoc.org
  64113. */
  64114. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64115. /**
  64116. * Reflection class for a @property tag in a Docblock.
  64117. *
  64118. * @author Mike van Riel <mike.vanriel@naenius.com>
  64119. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64120. * @link http://phpdoc.org
  64121. */
  64122. class PropertyTag extends ParamTag
  64123. {
  64124. }
  64125. <?php
  64126. /**
  64127. * phpDocumentor
  64128. *
  64129. * PHP Version 5.3
  64130. *
  64131. * @author Mike van Riel <mike.vanriel@naenius.com>
  64132. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64133. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64134. * @link http://phpdoc.org
  64135. */
  64136. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64137. use phpDocumentor\Reflection\DocBlock\Tag;
  64138. use phpDocumentor\Reflection\DocBlock\Type\Collection;
  64139. /**
  64140. * Reflection class for a @return tag in a Docblock.
  64141. *
  64142. * @author Mike van Riel <mike.vanriel@naenius.com>
  64143. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64144. * @link http://phpdoc.org
  64145. */
  64146. class ReturnTag extends Tag
  64147. {
  64148. /** @var string The raw type component. */
  64149. protected $type = '';
  64150. /** @var Collection The parsed type component. */
  64151. protected $types = null;
  64152. /**
  64153. * {@inheritdoc}
  64154. */
  64155. public function getContent()
  64156. {
  64157. if (null === $this->content) {
  64158. $this->content = "{$this->type} {$this->description}";
  64159. }
  64160. return $this->content;
  64161. }
  64162. /**
  64163. * {@inheritdoc}
  64164. */
  64165. public function setContent($content)
  64166. {
  64167. parent::setContent($content);
  64168. $parts = preg_split('/\s+/Su', $this->description, 2);
  64169. // any output is considered a type
  64170. $this->type = $parts[0];
  64171. $this->types = null;
  64172. $this->setDescription(isset($parts[1]) ? $parts[1] : '');
  64173. $this->content = $content;
  64174. return $this;
  64175. }
  64176. /**
  64177. * Returns the unique types of the variable.
  64178. *
  64179. * @return string[]
  64180. */
  64181. public function getTypes()
  64182. {
  64183. return $this->getTypesCollection()->getArrayCopy();
  64184. }
  64185. /**
  64186. * Returns the type section of the variable.
  64187. *
  64188. * @return string
  64189. */
  64190. public function getType()
  64191. {
  64192. return (string) $this->getTypesCollection();
  64193. }
  64194. /**
  64195. * Returns the type collection.
  64196. *
  64197. * @return void
  64198. */
  64199. protected function getTypesCollection()
  64200. {
  64201. if (null === $this->types) {
  64202. $this->types = new Collection(
  64203. array($this->type),
  64204. $this->docblock ? $this->docblock->getContext() : null
  64205. );
  64206. }
  64207. return $this->types;
  64208. }
  64209. }
  64210. <?php
  64211. /**
  64212. * phpDocumentor
  64213. *
  64214. * PHP Version 5.3
  64215. *
  64216. * @author Vasil Rangelov <boen.robot@gmail.com>
  64217. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64218. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64219. * @link http://phpdoc.org
  64220. */
  64221. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64222. use phpDocumentor\Reflection\DocBlock\Tag\VersionTag;
  64223. /**
  64224. * Reflection class for a @deprecated tag in a Docblock.
  64225. *
  64226. * @author Vasil Rangelov <boen.robot@gmail.com>
  64227. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64228. * @link http://phpdoc.org
  64229. */
  64230. class DeprecatedTag extends VersionTag
  64231. {
  64232. }
  64233. <?php
  64234. /**
  64235. * phpDocumentor
  64236. *
  64237. * PHP Version 5.3
  64238. *
  64239. * @author Mike van Riel <mike.vanriel@naenius.com>
  64240. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64241. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64242. * @link http://phpdoc.org
  64243. */
  64244. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64245. /**
  64246. * Reflection class for a @throws tag in a Docblock.
  64247. *
  64248. * @author Mike van Riel <mike.vanriel@naenius.com>
  64249. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64250. * @link http://phpdoc.org
  64251. */
  64252. class ThrowsTag extends ReturnTag
  64253. {
  64254. }
  64255. <?php
  64256. /**
  64257. * phpDocumentor
  64258. *
  64259. * PHP Version 5.3
  64260. *
  64261. * @author Mike van Riel <mike.vanriel@naenius.com>
  64262. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64263. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64264. * @link http://phpdoc.org
  64265. */
  64266. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64267. /**
  64268. * Reflection class for a @covers tag in a Docblock.
  64269. *
  64270. * @author Mike van Riel <mike.vanriel@naenius.com>
  64271. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64272. * @link http://phpdoc.org
  64273. */
  64274. class CoversTag extends SeeTag
  64275. {
  64276. }
  64277. <?php
  64278. /**
  64279. * phpDocumentor
  64280. *
  64281. * PHP Version 5.3
  64282. *
  64283. * @author Vasil Rangelov <boen.robot@gmail.com>
  64284. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64285. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64286. * @link http://phpdoc.org
  64287. */
  64288. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64289. use phpDocumentor\Reflection\DocBlock\Tag;
  64290. /**
  64291. * Reflection class for a @source tag in a Docblock.
  64292. *
  64293. * @author Vasil Rangelov <boen.robot@gmail.com>
  64294. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64295. * @link http://phpdoc.org
  64296. */
  64297. class SourceTag extends Tag
  64298. {
  64299. /**
  64300. * @var int The starting line, relative to the structural element's
  64301. * location.
  64302. */
  64303. protected $startingLine = 1;
  64304. /**
  64305. * @var int|null The number of lines, relative to the starting line. NULL
  64306. * means "to the end".
  64307. */
  64308. protected $lineCount = null;
  64309. /**
  64310. * {@inheritdoc}
  64311. */
  64312. public function getContent()
  64313. {
  64314. if (null === $this->content) {
  64315. $this->content
  64316. = "{$this->startingLine} {$this->lineCount} {$this->description}";
  64317. }
  64318. return $this->content;
  64319. }
  64320. /**
  64321. * {@inheritdoc}
  64322. */
  64323. public function setContent($content)
  64324. {
  64325. parent::setContent($content);
  64326. if (preg_match(
  64327. '/^
  64328. # Starting line
  64329. ([1-9]\d*)
  64330. \s*
  64331. # Number of lines
  64332. (?:
  64333. ((?1))
  64334. \s+
  64335. )?
  64336. # Description
  64337. (.*)
  64338. $/sux',
  64339. $this->description,
  64340. $matches
  64341. )) {
  64342. $this->startingLine = (int)$matches[1];
  64343. if (isset($matches[2]) && '' !== $matches[2]) {
  64344. $this->lineCount = (int)$matches[2];
  64345. }
  64346. $this->setDescription($matches[3]);
  64347. $this->content = $content;
  64348. }
  64349. return $this;
  64350. }
  64351. /**
  64352. * Gets the starting line.
  64353. *
  64354. * @return int The starting line, relative to the structural element's
  64355. * location.
  64356. */
  64357. public function getStartingLine()
  64358. {
  64359. return $this->startingLine;
  64360. }
  64361. /**
  64362. * Sets the starting line.
  64363. *
  64364. * @param int $startingLine The new starting line, relative to the
  64365. * structural element's location.
  64366. *
  64367. * @return $this
  64368. */
  64369. public function setStartingLine($startingLine)
  64370. {
  64371. $this->startingLine = $startingLine;
  64372. $this->content = null;
  64373. return $this;
  64374. }
  64375. /**
  64376. * Returns the number of lines.
  64377. *
  64378. * @return int|null The number of lines, relative to the starting line. NULL
  64379. * means "to the end".
  64380. */
  64381. public function getLineCount()
  64382. {
  64383. return $this->lineCount;
  64384. }
  64385. /**
  64386. * Sets the number of lines.
  64387. *
  64388. * @param int|null $lineCount The new number of lines, relative to the
  64389. * starting line. NULL means "to the end".
  64390. *
  64391. * @return $this
  64392. */
  64393. public function setLineCount($lineCount)
  64394. {
  64395. $this->lineCount = $lineCount;
  64396. $this->content = null;
  64397. return $this;
  64398. }
  64399. }
  64400. <?php
  64401. /**
  64402. * phpDocumentor
  64403. *
  64404. * PHP Version 5.3
  64405. *
  64406. * @author Mike van Riel <mike.vanriel@naenius.com>
  64407. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64408. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64409. * @link http://phpdoc.org
  64410. */
  64411. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64412. /**
  64413. * Reflection class for a @uses tag in a Docblock.
  64414. *
  64415. * @author Mike van Riel <mike.vanriel@naenius.com>
  64416. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64417. * @link http://phpdoc.org
  64418. */
  64419. class UsesTag extends SeeTag
  64420. {
  64421. }
  64422. <?php
  64423. /**
  64424. * phpDocumentor
  64425. *
  64426. * PHP Version 5.3
  64427. *
  64428. * @author Mike van Riel <mike.vanriel@naenius.com>
  64429. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64430. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64431. * @link http://phpdoc.org
  64432. */
  64433. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64434. use phpDocumentor\Reflection\DocBlock\Tag;
  64435. /**
  64436. * Reflection class for a @method in a Docblock.
  64437. *
  64438. * @author Mike van Riel <mike.vanriel@naenius.com>
  64439. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64440. * @link http://phpdoc.org
  64441. */
  64442. class MethodTag extends ReturnTag
  64443. {
  64444. /** @var string */
  64445. protected $method_name = '';
  64446. /** @var string */
  64447. protected $arguments = '';
  64448. /** @var bool */
  64449. protected $isStatic = false;
  64450. /**
  64451. * {@inheritdoc}
  64452. */
  64453. public function getContent()
  64454. {
  64455. if (null === $this->content) {
  64456. $this->content = '';
  64457. if ($this->isStatic) {
  64458. $this->content .= 'static ';
  64459. }
  64460. $this->content .= $this->type .
  64461. " {$this->method_name}({$this->arguments}) " .
  64462. $this->description;
  64463. }
  64464. return $this->content;
  64465. }
  64466. /**
  64467. * {@inheritdoc}
  64468. */
  64469. public function setContent($content)
  64470. {
  64471. Tag::setContent($content);
  64472. // 1. none or more whitespace
  64473. // 2. optionally the keyword "static" followed by whitespace
  64474. // 3. optionally a word with underscores followed by whitespace : as
  64475. // type for the return value
  64476. // 4. then optionally a word with underscores followed by () and
  64477. // whitespace : as method name as used by phpDocumentor
  64478. // 5. then a word with underscores, followed by ( and any character
  64479. // until a ) and whitespace : as method name with signature
  64480. // 6. any remaining text : as description
  64481. if (preg_match(
  64482. '/^
  64483. # Static keyword
  64484. # Declates a static method ONLY if type is also present
  64485. (?:
  64486. (static)
  64487. \s+
  64488. )?
  64489. # Return type
  64490. (?:
  64491. ([\w\|_\\\\]+)
  64492. \s+
  64493. )?
  64494. # Legacy method name (not captured)
  64495. (?:
  64496. [\w_]+\(\)\s+
  64497. )?
  64498. # Method name
  64499. ([\w\|_\\\\]+)
  64500. # Arguments
  64501. \(([^\)]*)\)
  64502. \s*
  64503. # Description
  64504. (.*)
  64505. $/sux',
  64506. $this->description,
  64507. $matches
  64508. )) {
  64509. list(
  64510. ,
  64511. $static,
  64512. $this->type,
  64513. $this->method_name,
  64514. $this->arguments,
  64515. $this->description
  64516. ) = $matches;
  64517. if ($static) {
  64518. if (!$this->type) {
  64519. $this->type = 'static';
  64520. } else {
  64521. $this->isStatic = true;
  64522. }
  64523. } else {
  64524. if (!$this->type) {
  64525. $this->type = 'void';
  64526. }
  64527. }
  64528. $this->parsedDescription = null;
  64529. }
  64530. return $this;
  64531. }
  64532. /**
  64533. * Sets the name of this method.
  64534. *
  64535. * @param string $method_name The name of the method.
  64536. *
  64537. * @return $this
  64538. */
  64539. public function setMethodName($method_name)
  64540. {
  64541. $this->method_name = $method_name;
  64542. $this->content = null;
  64543. return $this;
  64544. }
  64545. /**
  64546. * Retrieves the method name.
  64547. *
  64548. * @return string
  64549. */
  64550. public function getMethodName()
  64551. {
  64552. return $this->method_name;
  64553. }
  64554. /**
  64555. * Sets the arguments for this method.
  64556. *
  64557. * @param string $arguments A comma-separated arguments line.
  64558. *
  64559. * @return void
  64560. */
  64561. public function setArguments($arguments)
  64562. {
  64563. $this->arguments = $arguments;
  64564. $this->content = null;
  64565. return $this;
  64566. }
  64567. /**
  64568. * Returns an array containing each argument as array of type and name.
  64569. *
  64570. * Please note that the argument sub-array may only contain 1 element if no
  64571. * type was specified.
  64572. *
  64573. * @return string[]
  64574. */
  64575. public function getArguments()
  64576. {
  64577. if (empty($this->arguments)) {
  64578. return array();
  64579. }
  64580. $arguments = explode(',', $this->arguments);
  64581. foreach ($arguments as $key => $value) {
  64582. $arguments[$key] = explode(' ', trim($value));
  64583. }
  64584. return $arguments;
  64585. }
  64586. /**
  64587. * Checks whether the method tag describes a static method or not.
  64588. *
  64589. * @return bool TRUE if the method declaration is for a static method, FALSE
  64590. * otherwise.
  64591. */
  64592. public function isStatic()
  64593. {
  64594. return $this->isStatic;
  64595. }
  64596. /**
  64597. * Sets a new value for whether the method is static or not.
  64598. *
  64599. * @param bool $isStatic The new value to set.
  64600. *
  64601. * @return $this
  64602. */
  64603. public function setIsStatic($isStatic)
  64604. {
  64605. $this->isStatic = $isStatic;
  64606. $this->content = null;
  64607. return $this;
  64608. }
  64609. }
  64610. <?php
  64611. /**
  64612. * phpDocumentor
  64613. *
  64614. * PHP Version 5.3
  64615. *
  64616. * @author Mike van Riel <mike.vanriel@naenius.com>
  64617. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64618. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64619. * @link http://phpdoc.org
  64620. */
  64621. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64622. /**
  64623. * Reflection class for a @property-read tag in a Docblock.
  64624. *
  64625. * @author Mike van Riel <mike.vanriel@naenius.com>
  64626. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64627. * @link http://phpdoc.org
  64628. */
  64629. class PropertyReadTag extends PropertyTag
  64630. {
  64631. }
  64632. <?php
  64633. /**
  64634. * phpDocumentor
  64635. *
  64636. * PHP Version 5.3
  64637. *
  64638. * @author Vasil Rangelov <boen.robot@gmail.com>
  64639. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64640. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64641. * @link http://phpdoc.org
  64642. */
  64643. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64644. use phpDocumentor\Reflection\DocBlock\Tag;
  64645. /**
  64646. * Reflection class for an @author tag in a Docblock.
  64647. *
  64648. * @author Mike van Riel <mike.vanriel@naenius.com>
  64649. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64650. * @link http://phpdoc.org
  64651. */
  64652. class AuthorTag extends Tag
  64653. {
  64654. /**
  64655. * PCRE regular expression matching any valid value for the name component.
  64656. */
  64657. const REGEX_AUTHOR_NAME = '[^\<]*';
  64658. /**
  64659. * PCRE regular expression matching any valid value for the email component.
  64660. */
  64661. const REGEX_AUTHOR_EMAIL = '[^\>]*';
  64662. /** @var string The name of the author */
  64663. protected $authorName = '';
  64664. /** @var string The email of the author */
  64665. protected $authorEmail = '';
  64666. public function getContent()
  64667. {
  64668. if (null === $this->content) {
  64669. $this->content = $this->authorName;
  64670. if ('' != $this->authorEmail) {
  64671. $this->content .= "<{$this->authorEmail}>";
  64672. }
  64673. }
  64674. return $this->content;
  64675. }
  64676. /**
  64677. * {@inheritdoc}
  64678. */
  64679. public function setContent($content)
  64680. {
  64681. parent::setContent($content);
  64682. if (preg_match(
  64683. '/^(' . self::REGEX_AUTHOR_NAME .
  64684. ')(\<(' . self::REGEX_AUTHOR_EMAIL .
  64685. ')\>)?$/u',
  64686. $this->description,
  64687. $matches
  64688. )) {
  64689. $this->authorName = trim($matches[1]);
  64690. if (isset($matches[3])) {
  64691. $this->authorEmail = trim($matches[3]);
  64692. }
  64693. }
  64694. return $this;
  64695. }
  64696. /**
  64697. * Gets the author's name.
  64698. *
  64699. * @return string The author's name.
  64700. */
  64701. public function getAuthorName()
  64702. {
  64703. return $this->authorName;
  64704. }
  64705. /**
  64706. * Sets the author's name.
  64707. *
  64708. * @param string $authorName The new author name.
  64709. * An invalid value will set an empty string.
  64710. *
  64711. * @return $this
  64712. */
  64713. public function setAuthorName($authorName)
  64714. {
  64715. $this->content = null;
  64716. $this->authorName
  64717. = preg_match('/^' . self::REGEX_AUTHOR_NAME . '$/u', $authorName)
  64718. ? $authorName : '';
  64719. return $this;
  64720. }
  64721. /**
  64722. * Gets the author's email.
  64723. *
  64724. * @return string The author's email.
  64725. */
  64726. public function getAuthorEmail()
  64727. {
  64728. return $this->authorEmail;
  64729. }
  64730. /**
  64731. * Sets the author's email.
  64732. *
  64733. * @param string $authorEmail The new author email.
  64734. * An invalid value will set an empty string.
  64735. *
  64736. * @return $this
  64737. */
  64738. public function setAuthorEmail($authorEmail)
  64739. {
  64740. $this->authorEmail
  64741. = preg_match('/^' . self::REGEX_AUTHOR_EMAIL . '$/u', $authorEmail)
  64742. ? $authorEmail : '';
  64743. $this->content = null;
  64744. return $this;
  64745. }
  64746. }
  64747. <?php
  64748. /**
  64749. * phpDocumentor
  64750. *
  64751. * PHP Version 5.3
  64752. *
  64753. * @author Mike van Riel <mike.vanriel@naenius.com>
  64754. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64755. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64756. * @link http://phpdoc.org
  64757. */
  64758. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64759. /**
  64760. * Reflection class for a @var tag in a Docblock.
  64761. *
  64762. * @author Mike van Riel <mike.vanriel@naenius.com>
  64763. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64764. * @link http://phpdoc.org
  64765. */
  64766. class VarTag extends ParamTag
  64767. {
  64768. }
  64769. <?php
  64770. /**
  64771. * phpDocumentor
  64772. *
  64773. * PHP Version 5.3
  64774. *
  64775. * @author Ben Selby <benmatselby@gmail.com>
  64776. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64777. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64778. * @link http://phpdoc.org
  64779. */
  64780. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64781. use phpDocumentor\Reflection\DocBlock\Tag;
  64782. /**
  64783. * Reflection class for a @link tag in a Docblock.
  64784. *
  64785. * @author Ben Selby <benmatselby@gmail.com>
  64786. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64787. * @link http://phpdoc.org
  64788. */
  64789. class LinkTag extends Tag
  64790. {
  64791. /** @var string */
  64792. protected $link = '';
  64793. /**
  64794. * {@inheritdoc}
  64795. */
  64796. public function getContent()
  64797. {
  64798. if (null === $this->content) {
  64799. $this->content = "{$this->link} {$this->description}";
  64800. }
  64801. return $this->content;
  64802. }
  64803. /**
  64804. * {@inheritdoc}
  64805. */
  64806. public function setContent($content)
  64807. {
  64808. parent::setContent($content);
  64809. $parts = preg_split('/\s+/Su', $this->description, 2);
  64810. $this->link = $parts[0];
  64811. $this->setDescription(isset($parts[1]) ? $parts[1] : $parts[0]);
  64812. $this->content = $content;
  64813. return $this;
  64814. }
  64815. /**
  64816. * Gets the link
  64817. *
  64818. * @return string
  64819. */
  64820. public function getLink()
  64821. {
  64822. return $this->link;
  64823. }
  64824. /**
  64825. * Sets the link
  64826. *
  64827. * @param string $link The link
  64828. *
  64829. * @return $this
  64830. */
  64831. public function setLink($link)
  64832. {
  64833. $this->link = $link;
  64834. $this->content = null;
  64835. return $this;
  64836. }
  64837. }
  64838. <?php
  64839. /**
  64840. * phpDocumentor
  64841. *
  64842. * PHP Version 5.3
  64843. *
  64844. * @author Vasil Rangelov <boen.robot@gmail.com>
  64845. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64846. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64847. * @link http://phpdoc.org
  64848. */
  64849. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64850. use phpDocumentor\Reflection\DocBlock\Tag;
  64851. /**
  64852. * Reflection class for a @example tag in a Docblock.
  64853. *
  64854. * @author Vasil Rangelov <boen.robot@gmail.com>
  64855. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64856. * @link http://phpdoc.org
  64857. */
  64858. class ExampleTag extends SourceTag
  64859. {
  64860. /**
  64861. * @var string Path to a file to use as an example.
  64862. * May also be an absolute URI.
  64863. */
  64864. protected $filePath = '';
  64865. /**
  64866. * @var bool Whether the file path component represents an URI.
  64867. * This determines how the file portion appears at {@link getContent()}.
  64868. */
  64869. protected $isURI = false;
  64870. /**
  64871. * {@inheritdoc}
  64872. */
  64873. public function getContent()
  64874. {
  64875. if (null === $this->content) {
  64876. $filePath = '';
  64877. if ($this->isURI) {
  64878. if (false === strpos($this->filePath, ':')) {
  64879. $filePath = str_replace(
  64880. '%2F',
  64881. '/',
  64882. rawurlencode($this->filePath)
  64883. );
  64884. } else {
  64885. $filePath = $this->filePath;
  64886. }
  64887. } else {
  64888. $filePath = '"' . $this->filePath . '"';
  64889. }
  64890. $this->content = $filePath . ' ' . parent::getContent();
  64891. }
  64892. return $this->content;
  64893. }
  64894. /**
  64895. * {@inheritdoc}
  64896. */
  64897. public function setContent($content)
  64898. {
  64899. Tag::setContent($content);
  64900. if (preg_match(
  64901. '/^
  64902. # File component
  64903. (?:
  64904. # File path in quotes
  64905. \"([^\"]+)\"
  64906. |
  64907. # File URI
  64908. (\S+)
  64909. )
  64910. # Remaining content (parsed by SourceTag)
  64911. (?:\s+(.*))?
  64912. $/sux',
  64913. $this->description,
  64914. $matches
  64915. )) {
  64916. if ('' !== $matches[1]) {
  64917. $this->setFilePath($matches[1]);
  64918. } else {
  64919. $this->setFileURI($matches[2]);
  64920. }
  64921. if (isset($matches[3])) {
  64922. parent::setContent($matches[3]);
  64923. } else {
  64924. $this->setDescription('');
  64925. }
  64926. $this->content = $content;
  64927. }
  64928. return $this;
  64929. }
  64930. /**
  64931. * Returns the file path.
  64932. *
  64933. * @return string Path to a file to use as an example.
  64934. * May also be an absolute URI.
  64935. */
  64936. public function getFilePath()
  64937. {
  64938. return $this->filePath;
  64939. }
  64940. /**
  64941. * Sets the file path.
  64942. *
  64943. * @param string $filePath The new file path to use for the example.
  64944. *
  64945. * @return $this
  64946. */
  64947. public function setFilePath($filePath)
  64948. {
  64949. $this->isURI = false;
  64950. $this->filePath = trim($filePath);
  64951. $this->content = null;
  64952. return $this;
  64953. }
  64954. /**
  64955. * Sets the file path as an URI.
  64956. *
  64957. * This function is equivalent to {@link setFilePath()}, except that it
  64958. * convers an URI to a file path before that.
  64959. *
  64960. * There is no getFileURI(), as {@link getFilePath()} is compatible.
  64961. *
  64962. * @param type $uri The new file URI to use as an example.
  64963. */
  64964. public function setFileURI($uri)
  64965. {
  64966. $this->isURI = true;
  64967. if (false === strpos($uri, ':')) {
  64968. //Relative URL
  64969. $this->filePath = rawurldecode(
  64970. str_replace(array('/', '\\'), '%2F', $uri)
  64971. );
  64972. } else {
  64973. //Absolute URL or URI.
  64974. $this->filePath = $uri;
  64975. }
  64976. $this->content = null;
  64977. return $this;
  64978. }
  64979. }
  64980. <?php
  64981. /**
  64982. * phpDocumentor
  64983. *
  64984. * PHP Version 5.3
  64985. *
  64986. * @author Mike van Riel <mike.vanriel@naenius.com>
  64987. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64988. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64989. * @link http://phpdoc.org
  64990. */
  64991. namespace phpDocumentor\Reflection\DocBlock\Tag;
  64992. use phpDocumentor\Reflection\DocBlock\Tag;
  64993. /**
  64994. * Reflection class for a @param tag in a Docblock.
  64995. *
  64996. * @author Mike van Riel <mike.vanriel@naenius.com>
  64997. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64998. * @link http://phpdoc.org
  64999. */
  65000. class ParamTag extends ReturnTag
  65001. {
  65002. /** @var string */
  65003. protected $variableName = '';
  65004. /** @var bool determines whether this is a variadic argument */
  65005. protected $isVariadic = false;
  65006. /**
  65007. * {@inheritdoc}
  65008. */
  65009. public function getContent()
  65010. {
  65011. if (null === $this->content) {
  65012. $this->content
  65013. = "{$this->type} {$this->variableName} {$this->description}";
  65014. }
  65015. return $this->content;
  65016. }
  65017. /**
  65018. * {@inheritdoc}
  65019. */
  65020. public function setContent($content)
  65021. {
  65022. Tag::setContent($content);
  65023. $parts = preg_split(
  65024. '/(\s+)/Su',
  65025. $this->description,
  65026. 3,
  65027. PREG_SPLIT_DELIM_CAPTURE
  65028. );
  65029. // if the first item that is encountered is not a variable; it is a type
  65030. if (isset($parts[0])
  65031. && (strlen($parts[0]) > 0)
  65032. && ($parts[0][0] !== '$')
  65033. ) {
  65034. $this->type = array_shift($parts);
  65035. array_shift($parts);
  65036. }
  65037. // if the next item starts with a $ or ...$ it must be the variable name
  65038. if (isset($parts[0])
  65039. && (strlen($parts[0]) > 0)
  65040. && ($parts[0][0] == '$' || substr($parts[0], 0, 4) === '...$')
  65041. ) {
  65042. $this->variableName = array_shift($parts);
  65043. array_shift($parts);
  65044. if (substr($this->variableName, 0, 3) === '...') {
  65045. $this->isVariadic = true;
  65046. $this->variableName = substr($this->variableName, 3);
  65047. }
  65048. }
  65049. $this->setDescription(implode('', $parts));
  65050. $this->content = $content;
  65051. return $this;
  65052. }
  65053. /**
  65054. * Returns the variable's name.
  65055. *
  65056. * @return string
  65057. */
  65058. public function getVariableName()
  65059. {
  65060. return $this->variableName;
  65061. }
  65062. /**
  65063. * Sets the variable's name.
  65064. *
  65065. * @param string $name The new name for this variable.
  65066. *
  65067. * @return $this
  65068. */
  65069. public function setVariableName($name)
  65070. {
  65071. $this->variableName = $name;
  65072. $this->content = null;
  65073. return $this;
  65074. }
  65075. /**
  65076. * Returns whether this tag is variadic.
  65077. *
  65078. * @return boolean
  65079. */
  65080. public function isVariadic()
  65081. {
  65082. return $this->isVariadic;
  65083. }
  65084. }
  65085. <?php
  65086. /**
  65087. * phpDocumentor
  65088. *
  65089. * PHP Version 5.3
  65090. *
  65091. * @author Mike van Riel <mike.vanriel@naenius.com>
  65092. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  65093. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65094. * @link http://phpdoc.org
  65095. */
  65096. namespace phpDocumentor\Reflection\DocBlock\Tag;
  65097. /**
  65098. * Reflection class for a @property-write tag in a Docblock.
  65099. *
  65100. * @author Mike van Riel <mike.vanriel@naenius.com>
  65101. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65102. * @link http://phpdoc.org
  65103. */
  65104. class PropertyWriteTag extends PropertyTag
  65105. {
  65106. }
  65107. <?php
  65108. /**
  65109. * phpDocumentor
  65110. *
  65111. * PHP Version 5.3
  65112. *
  65113. * @author Barry vd. Heuvel <barryvdh@gmail.com>
  65114. * @copyright 2013 Mike van Riel / Naenius (http://www.naenius.com)
  65115. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65116. * @link http://phpdoc.org
  65117. */
  65118. namespace phpDocumentor\Reflection\DocBlock;
  65119. use phpDocumentor\Reflection\DocBlock;
  65120. /**
  65121. * Serializes a DocBlock instance.
  65122. *
  65123. * @author Barry vd. Heuvel <barryvdh@gmail.com>
  65124. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65125. * @link http://phpdoc.org
  65126. */
  65127. class Serializer
  65128. {
  65129. /** @var string The string to indent the comment with. */
  65130. protected $indentString = ' ';
  65131. /** @var int The number of times the indent string is repeated. */
  65132. protected $indent = 0;
  65133. /** @var bool Whether to indent the first line. */
  65134. protected $isFirstLineIndented = true;
  65135. /** @var int|null The max length of a line. */
  65136. protected $lineLength = null;
  65137. /**
  65138. * Create a Serializer instance.
  65139. *
  65140. * @param int $indent The number of times the indent string is
  65141. * repeated.
  65142. * @param string $indentString The string to indent the comment with.
  65143. * @param bool $indentFirstLine Whether to indent the first line.
  65144. * @param int|null $lineLength The max length of a line or NULL to
  65145. * disable line wrapping.
  65146. */
  65147. public function __construct(
  65148. $indent = 0,
  65149. $indentString = ' ',
  65150. $indentFirstLine = true,
  65151. $lineLength = null
  65152. ) {
  65153. $this->setIndentationString($indentString);
  65154. $this->setIndent($indent);
  65155. $this->setIsFirstLineIndented($indentFirstLine);
  65156. $this->setLineLength($lineLength);
  65157. }
  65158. /**
  65159. * Sets the string to indent comments with.
  65160. *
  65161. * @param string $indentationString The string to indent comments with.
  65162. *
  65163. * @return $this This serializer object.
  65164. */
  65165. public function setIndentationString($indentString)
  65166. {
  65167. $this->indentString = (string)$indentString;
  65168. return $this;
  65169. }
  65170. /**
  65171. * Gets the string to indent comments with.
  65172. *
  65173. * @return string The indent string.
  65174. */
  65175. public function getIndentationString()
  65176. {
  65177. return $this->indentString;
  65178. }
  65179. /**
  65180. * Sets the number of indents.
  65181. *
  65182. * @param int $indent The number of times the indent string is repeated.
  65183. *
  65184. * @return $this This serializer object.
  65185. */
  65186. public function setIndent($indent)
  65187. {
  65188. $this->indent = (int)$indent;
  65189. return $this;
  65190. }
  65191. /**
  65192. * Gets the number of indents.
  65193. *
  65194. * @return int The number of times the indent string is repeated.
  65195. */
  65196. public function getIndent()
  65197. {
  65198. return $this->indent;
  65199. }
  65200. /**
  65201. * Sets whether or not the first line should be indented.
  65202. *
  65203. * Sets whether or not the first line (the one with the "/**") should be
  65204. * indented.
  65205. *
  65206. * @param bool $indentFirstLine The new value for this setting.
  65207. *
  65208. * @return $this This serializer object.
  65209. */
  65210. public function setIsFirstLineIndented($indentFirstLine)
  65211. {
  65212. $this->isFirstLineIndented = (bool)$indentFirstLine;
  65213. return $this;
  65214. }
  65215. /**
  65216. * Gets whether or not the first line should be indented.
  65217. *
  65218. * @return bool Whether or not the first line should be indented.
  65219. */
  65220. public function isFirstLineIndented()
  65221. {
  65222. return $this->isFirstLineIndented;
  65223. }
  65224. /**
  65225. * Sets the line length.
  65226. *
  65227. * Sets the length of each line in the serialization. Content will be
  65228. * wrapped within this limit.
  65229. *
  65230. * @param int|null $lineLength The length of each line. NULL to disable line
  65231. * wrapping altogether.
  65232. *
  65233. * @return $this This serializer object.
  65234. */
  65235. public function setLineLength($lineLength)
  65236. {
  65237. $this->lineLength = null === $lineLength ? null : (int)$lineLength;
  65238. return $this;
  65239. }
  65240. /**
  65241. * Gets the line length.
  65242. *
  65243. * @return int|null The length of each line or NULL if line wrapping is
  65244. * disabled.
  65245. */
  65246. public function getLineLength()
  65247. {
  65248. return $this->lineLength;
  65249. }
  65250. /**
  65251. * Generate a DocBlock comment.
  65252. *
  65253. * @param DocBlock The DocBlock to serialize.
  65254. *
  65255. * @return string The serialized doc block.
  65256. */
  65257. public function getDocComment(DocBlock $docblock)
  65258. {
  65259. $indent = str_repeat($this->indentString, $this->indent);
  65260. $firstIndent = $this->isFirstLineIndented ? $indent : '';
  65261. $text = $docblock->getText();
  65262. if ($this->lineLength) {
  65263. //3 === strlen(' * ')
  65264. $wrapLength = $this->lineLength - strlen($indent) - 3;
  65265. $text = wordwrap($text, $wrapLength);
  65266. }
  65267. $text = str_replace("\n", "\n{$indent} * ", $text);
  65268. $comment = "{$firstIndent}/**\n{$indent} * {$text}\n{$indent} *\n";
  65269. /** @var Tag $tag */
  65270. foreach ($docblock->getTags() as $tag) {
  65271. $tagText = (string) $tag;
  65272. if ($this->lineLength) {
  65273. $tagText = wordwrap($tagText, $wrapLength);
  65274. }
  65275. $tagText = str_replace("\n", "\n{$indent} * ", $tagText);
  65276. $comment .= "{$indent} * {$tagText}\n";
  65277. }
  65278. $comment .= $indent . ' */';
  65279. return $comment;
  65280. }
  65281. }
  65282. <?php
  65283. /**
  65284. * phpDocumentor
  65285. *
  65286. * PHP Version 5.3
  65287. *
  65288. * @author Vasil Rangelov <boen.robot@gmail.com>
  65289. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  65290. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65291. * @link http://phpdoc.org
  65292. */
  65293. namespace phpDocumentor\Reflection\DocBlock;
  65294. /**
  65295. * The context in which a DocBlock occurs.
  65296. *
  65297. * @author Vasil Rangelov <boen.robot@gmail.com>
  65298. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65299. * @link http://phpdoc.org
  65300. */
  65301. class Context
  65302. {
  65303. /** @var string The current namespace. */
  65304. protected $namespace = '';
  65305. /** @var array List of namespace aliases => Fully Qualified Namespace. */
  65306. protected $namespace_aliases = array();
  65307. /** @var string Name of the structural element, within the namespace. */
  65308. protected $lsen = '';
  65309. /**
  65310. * Cteates a new context.
  65311. * @param string $namespace The namespace where this DocBlock
  65312. * resides in.
  65313. * @param array $namespace_aliases List of namespace aliases => Fully
  65314. * Qualified Namespace.
  65315. * @param string $lsen Name of the structural element, within
  65316. * the namespace.
  65317. */
  65318. public function __construct(
  65319. $namespace = '',
  65320. array $namespace_aliases = array(),
  65321. $lsen = ''
  65322. ) {
  65323. if (!empty($namespace)) {
  65324. $this->setNamespace($namespace);
  65325. }
  65326. $this->setNamespaceAliases($namespace_aliases);
  65327. $this->setLSEN($lsen);
  65328. }
  65329. /**
  65330. * @return string The namespace where this DocBlock resides in.
  65331. */
  65332. public function getNamespace()
  65333. {
  65334. return $this->namespace;
  65335. }
  65336. /**
  65337. * @return array List of namespace aliases => Fully Qualified Namespace.
  65338. */
  65339. public function getNamespaceAliases()
  65340. {
  65341. return $this->namespace_aliases;
  65342. }
  65343. /**
  65344. * Returns the Local Structural Element Name.
  65345. *
  65346. * @return string Name of the structural element, within the namespace.
  65347. */
  65348. public function getLSEN()
  65349. {
  65350. return $this->lsen;
  65351. }
  65352. /**
  65353. * Sets a new namespace.
  65354. *
  65355. * Sets a new namespace for the context. Leading and trailing slashes are
  65356. * trimmed, and the keywords "global" and "default" are treated as aliases
  65357. * to no namespace.
  65358. *
  65359. * @param string $namespace The new namespace to set.
  65360. *
  65361. * @return $this
  65362. */
  65363. public function setNamespace($namespace)
  65364. {
  65365. if ('global' !== $namespace
  65366. && 'default' !== $namespace
  65367. ) {
  65368. // Srip leading and trailing slash
  65369. $this->namespace = trim((string)$namespace, '\\');
  65370. } else {
  65371. $this->namespace = '';
  65372. }
  65373. return $this;
  65374. }
  65375. /**
  65376. * Sets the namespace aliases, replacing all previous ones.
  65377. *
  65378. * @param array $namespace_aliases List of namespace aliases => Fully
  65379. * Qualified Namespace.
  65380. *
  65381. * @return $this
  65382. */
  65383. public function setNamespaceAliases(array $namespace_aliases)
  65384. {
  65385. $this->namespace_aliases = array();
  65386. foreach ($namespace_aliases as $alias => $fqnn) {
  65387. $this->setNamespaceAlias($alias, $fqnn);
  65388. }
  65389. return $this;
  65390. }
  65391. /**
  65392. * Adds a namespace alias to the context.
  65393. *
  65394. * @param string $alias The alias name (the part after "as", or the last
  65395. * part of the Fully Qualified Namespace Name) to add.
  65396. * @param string $fqnn The Fully Qualified Namespace Name for this alias.
  65397. * Any form of leading/trailing slashes are accepted, but what will be
  65398. * stored is a name, prefixed with a slash, and no trailing slash.
  65399. *
  65400. * @return $this
  65401. */
  65402. public function setNamespaceAlias($alias, $fqnn)
  65403. {
  65404. $this->namespace_aliases[$alias] = '\\' . trim((string)$fqnn, '\\');
  65405. return $this;
  65406. }
  65407. /**
  65408. * Sets a new Local Structural Element Name.
  65409. *
  65410. * Sets a new Local Structural Element Name. A local name also contains
  65411. * punctuation determining the kind of structural element (e.g. trailing "("
  65412. * and ")" for functions and methods).
  65413. *
  65414. * @param string $lsen The new local name of a structural element.
  65415. *
  65416. * @return $this
  65417. */
  65418. public function setLSEN($lsen)
  65419. {
  65420. $this->lsen = (string)$lsen;
  65421. return $this;
  65422. }
  65423. }
  65424. <?php
  65425. /**
  65426. * phpDocumentor
  65427. *
  65428. * PHP Version 5.3
  65429. *
  65430. * @author Mike van Riel <mike.vanriel@naenius.com>
  65431. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  65432. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65433. * @link http://phpdoc.org
  65434. */
  65435. namespace phpDocumentor\Reflection\DocBlock\Type;
  65436. use phpDocumentor\Reflection\DocBlock\Context;
  65437. /**
  65438. * Collection
  65439. *
  65440. * @author Mike van Riel <mike.vanriel@naenius.com>
  65441. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  65442. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65443. * @link http://phpdoc.org
  65444. */
  65445. class Collection extends \ArrayObject
  65446. {
  65447. /** @var string Definition of the OR operator for types */
  65448. const OPERATOR_OR = '|';
  65449. /** @var string Definition of the ARRAY operator for types */
  65450. const OPERATOR_ARRAY = '[]';
  65451. /** @var string Definition of the NAMESPACE operator in PHP */
  65452. const OPERATOR_NAMESPACE = '\\';
  65453. /** @var string[] List of recognized keywords */
  65454. protected static $keywords = array(
  65455. 'string', 'int', 'integer', 'bool', 'boolean', 'float', 'double',
  65456. 'object', 'mixed', 'array', 'resource', 'void', 'null', 'scalar',
  65457. 'callback', 'callable', 'false', 'true', 'self', '$this', 'static'
  65458. );
  65459. /**
  65460. * Current invoking location.
  65461. *
  65462. * This is used to prepend to type with a relative location.
  65463. * May also be 'default' or 'global', in which case they are ignored.
  65464. *
  65465. * @var Context
  65466. */
  65467. protected $context = null;
  65468. /**
  65469. * Registers the namespace and aliases; uses that to add and expand the
  65470. * given types.
  65471. *
  65472. * @param string[] $types Array containing a list of types to add to this
  65473. * container.
  65474. * @param Context $location The current invoking location.
  65475. */
  65476. public function __construct(
  65477. array $types = array(),
  65478. Context $context = null
  65479. ) {
  65480. $this->context = null === $context ? new Context() : $context;
  65481. foreach ($types as $type) {
  65482. $this->add($type);
  65483. }
  65484. }
  65485. /**
  65486. * Returns the current invoking location.
  65487. *
  65488. * @return Context
  65489. */
  65490. public function getContext()
  65491. {
  65492. return $this->context;
  65493. }
  65494. /**
  65495. * Adds a new type to the collection and expands it if it contains a
  65496. * relative namespace.
  65497. *
  65498. * If a class in the type contains a relative namespace than this collection
  65499. * will try to expand that into a FQCN.
  65500. *
  65501. * @param string $type A 'Type' as defined in the phpDocumentor
  65502. * documentation.
  65503. *
  65504. * @throws \InvalidArgumentException if a non-string argument is passed.
  65505. *
  65506. * @see http://phpdoc.org/docs/latest/for-users/types.html for the
  65507. * definition of a type.
  65508. *
  65509. * @return void
  65510. */
  65511. public function add($type)
  65512. {
  65513. if (!is_string($type)) {
  65514. throw new \InvalidArgumentException(
  65515. 'A type should be represented by a string, received: '
  65516. .var_export($type, true)
  65517. );
  65518. }
  65519. // separate the type by the OR operator
  65520. $type_parts = explode(self::OPERATOR_OR, $type);
  65521. foreach ($type_parts as $part) {
  65522. $expanded_type = $this->expand($part);
  65523. if ($expanded_type) {
  65524. $this[] = $expanded_type;
  65525. }
  65526. }
  65527. }
  65528. /**
  65529. * Returns a string representation of the collection.
  65530. *
  65531. * @return string The resolved types across the collection, separated with
  65532. * {@link self::OPERATOR_OR}.
  65533. */
  65534. public function __toString()
  65535. {
  65536. return implode(self::OPERATOR_OR, $this->getArrayCopy());
  65537. }
  65538. /**
  65539. * Analyzes the given type and returns the FQCN variant.
  65540. *
  65541. * When a type is provided this method checks whether it is not a keyword or
  65542. * Fully Qualified Class Name. If so it will use the given namespace and
  65543. * aliases to expand the type to a FQCN representation.
  65544. *
  65545. * This method only works as expected if the namespace and aliases are set;
  65546. * no dynamic reflection is being performed here.
  65547. *
  65548. * @param string $type The relative or absolute type.
  65549. *
  65550. * @uses getNamespace to determine with what to prefix the type name.
  65551. * @uses getNamespaceAliases to check whether the first part of the relative
  65552. * type name should not be replaced with another namespace.
  65553. *
  65554. * @return string
  65555. */
  65556. protected function expand($type)
  65557. {
  65558. $type = trim($type);
  65559. if (!$type) {
  65560. return '';
  65561. }
  65562. if ($this->isTypeAnArray($type)) {
  65563. return $this->expand(substr($type, 0, -2)) . self::OPERATOR_ARRAY;
  65564. }
  65565. if ($this->isRelativeType($type) && !$this->isTypeAKeyword($type)) {
  65566. $type_parts = explode(self::OPERATOR_NAMESPACE, $type, 2);
  65567. $namespace_aliases = $this->context->getNamespaceAliases();
  65568. // if the first segment is not an alias; prepend namespace name and
  65569. // return
  65570. if (!isset($namespace_aliases[$type_parts[0]])) {
  65571. $namespace = $this->context->getNamespace();
  65572. if ('' !== $namespace) {
  65573. $namespace .= self::OPERATOR_NAMESPACE;
  65574. }
  65575. return self::OPERATOR_NAMESPACE . $namespace . $type;
  65576. }
  65577. $type_parts[0] = $namespace_aliases[$type_parts[0]];
  65578. $type = implode(self::OPERATOR_NAMESPACE, $type_parts);
  65579. }
  65580. return $type;
  65581. }
  65582. /**
  65583. * Detects whether the given type represents an array.
  65584. *
  65585. * @param string $type A relative or absolute type as defined in the
  65586. * phpDocumentor documentation.
  65587. *
  65588. * @return bool
  65589. */
  65590. protected function isTypeAnArray($type)
  65591. {
  65592. return substr($type, -2) === self::OPERATOR_ARRAY;
  65593. }
  65594. /**
  65595. * Detects whether the given type represents a PHPDoc keyword.
  65596. *
  65597. * @param string $type A relative or absolute type as defined in the
  65598. * phpDocumentor documentation.
  65599. *
  65600. * @return bool
  65601. */
  65602. protected function isTypeAKeyword($type)
  65603. {
  65604. return in_array(strtolower($type), static::$keywords, true);
  65605. }
  65606. /**
  65607. * Detects whether the given type represents a relative or absolute path.
  65608. *
  65609. * This method will detect keywords as being absolute; even though they are
  65610. * not preceeded by a namespace separator.
  65611. *
  65612. * @param string $type A relative or absolute type as defined in the
  65613. * phpDocumentor documentation.
  65614. *
  65615. * @return bool
  65616. */
  65617. protected function isRelativeType($type)
  65618. {
  65619. return ($type[0] !== self::OPERATOR_NAMESPACE)
  65620. || $this->isTypeAKeyword($type);
  65621. }
  65622. }
  65623. <?php
  65624. /**
  65625. * phpDocumentor
  65626. *
  65627. * PHP Version 5.3
  65628. *
  65629. * @author Mike van Riel <mike.vanriel@naenius.com>
  65630. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  65631. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65632. * @link http://phpdoc.org
  65633. */
  65634. namespace phpDocumentor\Reflection\DocBlock;
  65635. use phpDocumentor\Reflection\DocBlock;
  65636. /**
  65637. * Parses a tag definition for a DocBlock.
  65638. *
  65639. * @author Mike van Riel <mike.vanriel@naenius.com>
  65640. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65641. * @link http://phpdoc.org
  65642. */
  65643. class Tag implements \Reflector
  65644. {
  65645. /**
  65646. * PCRE regular expression matching a tag name.
  65647. */
  65648. const REGEX_TAGNAME = '[\w\-\_\\\\]+';
  65649. /** @var string Name of the tag */
  65650. protected $tag = '';
  65651. /**
  65652. * @var string|null Content of the tag.
  65653. * When set to NULL, it means it needs to be regenerated.
  65654. */
  65655. protected $content = '';
  65656. /** @var string Description of the content of this tag */
  65657. protected $description = '';
  65658. /**
  65659. * @var array|null The description, as an array of strings and Tag objects.
  65660. * When set to NULL, it means it needs to be regenerated.
  65661. */
  65662. protected $parsedDescription = null;
  65663. /** @var Location Location of the tag. */
  65664. protected $location = null;
  65665. /** @var DocBlock The DocBlock which this tag belongs to. */
  65666. protected $docblock = null;
  65667. /**
  65668. * @var array An array with a tag as a key, and an FQCN to a class that
  65669. * handles it as an array value. The class is expected to inherit this
  65670. * class.
  65671. */
  65672. private static $tagHandlerMappings = array(
  65673. 'author'
  65674. => '\phpDocumentor\Reflection\DocBlock\Tag\AuthorTag',
  65675. 'covers'
  65676. => '\phpDocumentor\Reflection\DocBlock\Tag\CoversTag',
  65677. 'deprecated'
  65678. => '\phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag',
  65679. 'example'
  65680. => '\phpDocumentor\Reflection\DocBlock\Tag\ExampleTag',
  65681. 'link'
  65682. => '\phpDocumentor\Reflection\DocBlock\Tag\LinkTag',
  65683. 'method'
  65684. => '\phpDocumentor\Reflection\DocBlock\Tag\MethodTag',
  65685. 'param'
  65686. => '\phpDocumentor\Reflection\DocBlock\Tag\ParamTag',
  65687. 'property-read'
  65688. => '\phpDocumentor\Reflection\DocBlock\Tag\PropertyReadTag',
  65689. 'property'
  65690. => '\phpDocumentor\Reflection\DocBlock\Tag\PropertyTag',
  65691. 'property-write'
  65692. => '\phpDocumentor\Reflection\DocBlock\Tag\PropertyWriteTag',
  65693. 'return'
  65694. => '\phpDocumentor\Reflection\DocBlock\Tag\ReturnTag',
  65695. 'see'
  65696. => '\phpDocumentor\Reflection\DocBlock\Tag\SeeTag',
  65697. 'since'
  65698. => '\phpDocumentor\Reflection\DocBlock\Tag\SinceTag',
  65699. 'source'
  65700. => '\phpDocumentor\Reflection\DocBlock\Tag\SourceTag',
  65701. 'throw'
  65702. => '\phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag',
  65703. 'throws'
  65704. => '\phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag',
  65705. 'uses'
  65706. => '\phpDocumentor\Reflection\DocBlock\Tag\UsesTag',
  65707. 'var'
  65708. => '\phpDocumentor\Reflection\DocBlock\Tag\VarTag',
  65709. 'version'
  65710. => '\phpDocumentor\Reflection\DocBlock\Tag\VersionTag'
  65711. );
  65712. /**
  65713. * Factory method responsible for instantiating the correct sub type.
  65714. *
  65715. * @param string $tag_line The text for this tag, including description.
  65716. * @param DocBlock $docblock The DocBlock which this tag belongs to.
  65717. * @param Location $location Location of the tag.
  65718. *
  65719. * @throws \InvalidArgumentException if an invalid tag line was presented.
  65720. *
  65721. * @return static A new tag object.
  65722. */
  65723. final public static function createInstance(
  65724. $tag_line,
  65725. DocBlock $docblock = null,
  65726. Location $location = null
  65727. ) {
  65728. if (!preg_match(
  65729. '/^@(' . self::REGEX_TAGNAME . ')(?:\s*([^\s].*)|$)?/us',
  65730. $tag_line,
  65731. $matches
  65732. )) {
  65733. throw new \InvalidArgumentException(
  65734. 'Invalid tag_line detected: ' . $tag_line
  65735. );
  65736. }
  65737. $handler = __CLASS__;
  65738. if (isset(self::$tagHandlerMappings[$matches[1]])) {
  65739. $handler = self::$tagHandlerMappings[$matches[1]];
  65740. } elseif (isset($docblock)) {
  65741. $tagName = (string)new Type\Collection(
  65742. array($matches[1]),
  65743. $docblock->getContext()
  65744. );
  65745. if (isset(self::$tagHandlerMappings[$tagName])) {
  65746. $handler = self::$tagHandlerMappings[$tagName];
  65747. }
  65748. }
  65749. return new $handler(
  65750. $matches[1],
  65751. isset($matches[2]) ? $matches[2] : '',
  65752. $docblock,
  65753. $location
  65754. );
  65755. }
  65756. /**
  65757. * Registers a handler for tags.
  65758. *
  65759. * Registers a handler for tags. The class specified is autoloaded if it's
  65760. * not available. It must inherit from this class.
  65761. *
  65762. * @param string $tag Name of tag to regiser a handler for. When
  65763. * registering a namespaced tag, the full name, along with a prefixing
  65764. * slash MUST be provided.
  65765. * @param string|null $handler FQCN of handler. Specifing NULL removes the
  65766. * handler for the specified tag, if any.
  65767. *
  65768. * @return bool TRUE on success, FALSE on failure.
  65769. */
  65770. final public static function registerTagHandler($tag, $handler)
  65771. {
  65772. $tag = trim((string)$tag);
  65773. if (null === $handler) {
  65774. unset(self::$tagHandlerMappings[$tag]);
  65775. return true;
  65776. }
  65777. if ('' !== $tag
  65778. && class_exists($handler, true)
  65779. && is_subclass_of($handler, __CLASS__)
  65780. && !strpos($tag, '\\') //Accept no slash, and 1st slash at offset 0.
  65781. ) {
  65782. self::$tagHandlerMappings[$tag] = $handler;
  65783. return true;
  65784. }
  65785. return false;
  65786. }
  65787. /**
  65788. * Parses a tag and populates the member variables.
  65789. *
  65790. * @param string $name Name of the tag.
  65791. * @param string $content The contents of the given tag.
  65792. * @param DocBlock $docblock The DocBlock which this tag belongs to.
  65793. * @param Location $location Location of the tag.
  65794. */
  65795. public function __construct(
  65796. $name,
  65797. $content,
  65798. DocBlock $docblock = null,
  65799. Location $location = null
  65800. ) {
  65801. $this
  65802. ->setName($name)
  65803. ->setContent($content)
  65804. ->setDocBlock($docblock)
  65805. ->setLocation($location);
  65806. }
  65807. /**
  65808. * Gets the name of this tag.
  65809. *
  65810. * @return string The name of this tag.
  65811. */
  65812. public function getName()
  65813. {
  65814. return $this->tag;
  65815. }
  65816. /**
  65817. * Sets the name of this tag.
  65818. *
  65819. * @param string $name The new name of this tag.
  65820. *
  65821. * @return $this
  65822. * @throws \InvalidArgumentException When an invalid tag name is provided.
  65823. */
  65824. public function setName($name)
  65825. {
  65826. if (!preg_match('/^' . self::REGEX_TAGNAME . '$/u', $name)) {
  65827. throw new \InvalidArgumentException(
  65828. 'Invalid tag name supplied: ' . $name
  65829. );
  65830. }
  65831. $this->tag = $name;
  65832. return $this;
  65833. }
  65834. /**
  65835. * Gets the content of this tag.
  65836. *
  65837. * @return string
  65838. */
  65839. public function getContent()
  65840. {
  65841. if (null === $this->content) {
  65842. $this->content = $this->description;
  65843. }
  65844. return $this->content;
  65845. }
  65846. /**
  65847. * Sets the content of this tag.
  65848. *
  65849. * @param string $content The new content of this tag.
  65850. *
  65851. * @return $this
  65852. */
  65853. public function setContent($content)
  65854. {
  65855. $this->setDescription($content);
  65856. $this->content = $content;
  65857. return $this;
  65858. }
  65859. /**
  65860. * Gets the description component of this tag.
  65861. *
  65862. * @return string
  65863. */
  65864. public function getDescription()
  65865. {
  65866. return $this->description;
  65867. }
  65868. /**
  65869. * Sets the description component of this tag.
  65870. *
  65871. * @param string $description The new description component of this tag.
  65872. *
  65873. * @return $this
  65874. */
  65875. public function setDescription($description)
  65876. {
  65877. $this->content = null;
  65878. $this->parsedDescription = null;
  65879. $this->description = trim($description);
  65880. return $this;
  65881. }
  65882. /**
  65883. * Gets the parsed text of this description.
  65884. *
  65885. * @return array An array of strings and tag objects, in the order they
  65886. * occur within the description.
  65887. */
  65888. public function getParsedDescription()
  65889. {
  65890. if (null === $this->parsedDescription) {
  65891. $description = new Description($this->description, $this->docblock);
  65892. $this->parsedDescription = $description->getParsedContents();
  65893. }
  65894. return $this->parsedDescription;
  65895. }
  65896. /**
  65897. * Gets the docblock this tag belongs to.
  65898. *
  65899. * @return DocBlock The docblock this tag belongs to.
  65900. */
  65901. public function getDocBlock()
  65902. {
  65903. return $this->docblock;
  65904. }
  65905. /**
  65906. * Sets the docblock this tag belongs to.
  65907. *
  65908. * @param DocBlock $docblock The new docblock this tag belongs to. Setting
  65909. * NULL removes any association.
  65910. *
  65911. * @return $this
  65912. */
  65913. public function setDocBlock(DocBlock $docblock = null)
  65914. {
  65915. $this->docblock = $docblock;
  65916. return $this;
  65917. }
  65918. /**
  65919. * Gets the location of the tag.
  65920. *
  65921. * @return Location The tag's location.
  65922. */
  65923. public function getLocation()
  65924. {
  65925. return $this->location;
  65926. }
  65927. /**
  65928. * Sets the location of the tag.
  65929. *
  65930. * @param Location $location The new location of the tag.
  65931. *
  65932. * @return $this
  65933. */
  65934. public function setLocation(Location $location = null)
  65935. {
  65936. $this->location = $location;
  65937. return $this;
  65938. }
  65939. /**
  65940. * Builds a string representation of this object.
  65941. *
  65942. * @todo determine the exact format as used by PHP Reflection and implement it.
  65943. *
  65944. * @return void
  65945. * @codeCoverageIgnore Not yet implemented
  65946. */
  65947. public static function export()
  65948. {
  65949. throw new \Exception('Not yet implemented');
  65950. }
  65951. /**
  65952. * Returns the tag as a serialized string
  65953. *
  65954. * @return string
  65955. */
  65956. public function __toString()
  65957. {
  65958. return "@{$this->getName()} {$this->getContent()}";
  65959. }
  65960. }
  65961. <?php
  65962. /**
  65963. * phpDocumentor
  65964. *
  65965. * PHP Version 5.3
  65966. *
  65967. * @author Mike van Riel <mike.vanriel@naenius.com>
  65968. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  65969. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65970. * @link http://phpdoc.org
  65971. */
  65972. namespace phpDocumentor\Reflection\DocBlock;
  65973. use phpDocumentor\Reflection\DocBlock;
  65974. /**
  65975. * Parses a Description of a DocBlock or tag.
  65976. *
  65977. * @author Mike van Riel <mike.vanriel@naenius.com>
  65978. * @license http://www.opensource.org/licenses/mit-license.php MIT
  65979. * @link http://phpdoc.org
  65980. */
  65981. class Description implements \Reflector
  65982. {
  65983. /** @var string */
  65984. protected $contents = '';
  65985. /** @var array The contents, as an array of strings and Tag objects. */
  65986. protected $parsedContents = null;
  65987. /** @var DocBlock The DocBlock which this description belongs to. */
  65988. protected $docblock = null;
  65989. /**
  65990. * Populates the fields of a description.
  65991. *
  65992. * @param string $content The description's conetnts.
  65993. * @param DocBlock $docblock The DocBlock which this description belongs to.
  65994. */
  65995. public function __construct($content, DocBlock $docblock = null)
  65996. {
  65997. $this->setContent($content)->setDocBlock($docblock);
  65998. }
  65999. /**
  66000. * Gets the text of this description.
  66001. *
  66002. * @return string
  66003. */
  66004. public function getContents()
  66005. {
  66006. return $this->contents;
  66007. }
  66008. /**
  66009. * Sets the text of this description.
  66010. *
  66011. * @param string $content The new text of this description.
  66012. *
  66013. * @return $this
  66014. */
  66015. public function setContent($content)
  66016. {
  66017. $this->contents = trim($content);
  66018. $this->parsedContents = null;
  66019. return $this;
  66020. }
  66021. /**
  66022. * Returns the parsed text of this description.
  66023. *
  66024. * @return array An array of strings and tag objects, in the order they
  66025. * occur within the description.
  66026. */
  66027. public function getParsedContents()
  66028. {
  66029. if (null === $this->parsedContents) {
  66030. $this->parsedContents = preg_split(
  66031. '/\{
  66032. # "{@}" is not a valid inline tag. This ensures that
  66033. # we do not treat it as one, but treat it literally.
  66034. (?!@\})
  66035. # We want to capture the whole tag line, but without the
  66036. # inline tag delimiters.
  66037. (\@
  66038. # Match everything up to the next delimiter.
  66039. [^{}]*
  66040. # Nested inline tag content should not be captured, or
  66041. # it will appear in the result separately.
  66042. (?:
  66043. # Match nested inline tags.
  66044. (?:
  66045. # Because we did not catch the tag delimiters
  66046. # earlier, we must be explicit with them here.
  66047. # Notice that this also matches "{}", as a way
  66048. # to later introduce it as an escape sequence.
  66049. \{(?1)?\}
  66050. |
  66051. # Make sure we match hanging "{".
  66052. \{
  66053. )
  66054. # Match content after the nested inline tag.
  66055. [^{}]*
  66056. )* # If there are more inline tags, match them as well.
  66057. # We use "*" since there may not be any nested inline
  66058. # tags.
  66059. )
  66060. \}/Sux',
  66061. $this->contents,
  66062. null,
  66063. PREG_SPLIT_DELIM_CAPTURE
  66064. );
  66065. $count = count($this->parsedContents);
  66066. for ($i=1; $i<$count; $i += 2) {
  66067. $this->parsedContents[$i] = Tag::createInstance(
  66068. $this->parsedContents[$i],
  66069. $this->docblock
  66070. );
  66071. }
  66072. //In order to allow "literal" inline tags, the otherwise invalid
  66073. //sequence "{@}" is changed to "@", and "{}" is changed to "}".
  66074. //See unit tests for examples.
  66075. for ($i=0; $i<$count; $i += 2) {
  66076. $this->parsedContents[$i] = str_replace(
  66077. array('{@}', '{}'),
  66078. array('@', '}'),
  66079. $this->parsedContents[$i]
  66080. );
  66081. }
  66082. }
  66083. return $this->parsedContents;
  66084. }
  66085. /**
  66086. * Return a formatted variant of the Long Description using MarkDown.
  66087. *
  66088. * @todo this should become a more intelligent piece of code where the
  66089. * configuration contains a setting what format long descriptions are.
  66090. *
  66091. * @codeCoverageIgnore Will be removed soon, in favor of adapters at
  66092. * PhpDocumentor itself that will process text in various formats.
  66093. *
  66094. * @return string
  66095. */
  66096. public function getFormattedContents()
  66097. {
  66098. $result = $this->contents;
  66099. // if the long description contains a plain HTML <code> element, surround
  66100. // it with a pre element. Please note that we explicitly used str_replace
  66101. // and not preg_replace to gain performance
  66102. if (strpos($result, '<code>') !== false) {
  66103. $result = str_replace(
  66104. array('<code>', "<code>\r\n", "<code>\n", "<code>\r", '</code>'),
  66105. array('<pre><code>', '<code>', '<code>', '<code>', '</code></pre>'),
  66106. $result
  66107. );
  66108. }
  66109. if (class_exists('Parsedown')) {
  66110. $markdown = \Parsedown::instance();
  66111. $result = $markdown->parse($result);
  66112. } elseif (class_exists('dflydev\markdown\MarkdownExtraParser')) {
  66113. $markdown = new \dflydev\markdown\MarkdownExtraParser();
  66114. $result = $markdown->transformMarkdown($result);
  66115. }
  66116. return trim($result);
  66117. }
  66118. /**
  66119. * Gets the docblock this tag belongs to.
  66120. *
  66121. * @return DocBlock The docblock this description belongs to.
  66122. */
  66123. public function getDocBlock()
  66124. {
  66125. return $this->docblock;
  66126. }
  66127. /**
  66128. * Sets the docblock this tag belongs to.
  66129. *
  66130. * @param DocBlock $docblock The new docblock this description belongs to.
  66131. * Setting NULL removes any association.
  66132. *
  66133. * @return $this
  66134. */
  66135. public function setDocBlock(DocBlock $docblock = null)
  66136. {
  66137. $this->docblock = $docblock;
  66138. return $this;
  66139. }
  66140. /**
  66141. * Builds a string representation of this object.
  66142. *
  66143. * @todo determine the exact format as used by PHP Reflection
  66144. * and implement it.
  66145. *
  66146. * @return void
  66147. * @codeCoverageIgnore Not yet implemented
  66148. */
  66149. public static function export()
  66150. {
  66151. throw new \Exception('Not yet implemented');
  66152. }
  66153. /**
  66154. * Returns the long description as a string.
  66155. *
  66156. * @return string
  66157. */
  66158. public function __toString()
  66159. {
  66160. return $this->getContents();
  66161. }
  66162. }
  66163. Version
  66164. Copyright (c) 2013-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  66165. All rights reserved.
  66166. Redistribution and use in source and binary forms, with or without
  66167. modification, are permitted provided that the following conditions
  66168. are met:
  66169. * Redistributions of source code must retain the above copyright
  66170. notice, this list of conditions and the following disclaimer.
  66171. * Redistributions in binary form must reproduce the above copyright
  66172. notice, this list of conditions and the following disclaimer in
  66173. the documentation and/or other materials provided with the
  66174. distribution.
  66175. * Neither the name of Sebastian Bergmann nor the names of his
  66176. contributors may be used to endorse or promote products derived
  66177. from this software without specific prior written permission.
  66178. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  66179. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  66180. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  66181. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  66182. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  66183. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  66184. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  66185. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  66186. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  66187. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  66188. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  66189. POSSIBILITY OF SUCH DAMAGE.
  66190. <?php
  66191. /*
  66192. * This file is part of the Version package.
  66193. *
  66194. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  66195. *
  66196. * For the full copyright and license information, please view the LICENSE
  66197. * file that was distributed with this source code.
  66198. */
  66199. namespace SebastianBergmann;
  66200. /**
  66201. * @package Version
  66202. * @author Sebastian Bergmann <sebastian@phpunit.de>
  66203. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  66204. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  66205. * @link http://github.com/sebastianbergmann/version
  66206. * @since Class available since Release 1.0.0
  66207. */
  66208. class Version
  66209. {
  66210. private $path;
  66211. private $release;
  66212. private $version;
  66213. /**
  66214. * @param string $release
  66215. * @param string $path
  66216. */
  66217. public function __construct($release, $path)
  66218. {
  66219. $this->release = $release;
  66220. $this->path = $path;
  66221. }
  66222. /**
  66223. * @return string
  66224. */
  66225. public function getVersion()
  66226. {
  66227. if ($this->version === null) {
  66228. if (count(explode('.', $this->release)) == 3) {
  66229. $this->version = $this->release;
  66230. } else {
  66231. $this->version = $this->release . '-dev';
  66232. }
  66233. $git = $this->getGitInformation($this->path);
  66234. if ($git) {
  66235. if (count(explode('.', $this->release)) == 3) {
  66236. $this->version = $git;
  66237. } else {
  66238. $git = explode('-', $git);
  66239. $this->version = $this->release . '-' . end($git);
  66240. }
  66241. }
  66242. }
  66243. return $this->version;
  66244. }
  66245. /**
  66246. * @param string $path
  66247. * @return boolean|string
  66248. */
  66249. private function getGitInformation($path)
  66250. {
  66251. if (!is_dir($path . DIRECTORY_SEPARATOR . '.git')) {
  66252. return false;
  66253. }
  66254. $dir = getcwd();
  66255. chdir($path);
  66256. $returnCode = 1;
  66257. $result = @exec('git describe --tags 2>&1', $output, $returnCode);
  66258. chdir($dir);
  66259. if ($returnCode !== 0) {
  66260. return false;
  66261. }
  66262. return $result;
  66263. }
  66264. }
  66265. hãw?=ä;@,Ž ?e­Ò^¤Ý·l¬–¦�‚�)Ñóµ“î ÖàÇ»8½ø‘iñKŽjã z"“xÇû'hÅ���GBMB