JFIFXX    $.' ",#(7),01444'9=82<.342  2!!22222222222222222222222222222222222222222222222222"4 ,PG"Z_4˷kjزZ,F+_z,© zh6٨icfu#ډb_N?wQ5-~I8TK<5oIv-k_U_~bMdӜUHh?]EwQk{_}qFW7HTՑYF?_'ϔ_Ջt=||I 6έ"D/[k9Y8ds|\Ҿp6Ҵ].6znopM[mei$[soᘨ˸ nɜG-ĨUycP3.DBli;hjx7Z^NhN3u{:jx힞#M&jL P@_ P&o89@Sz6t7#Oߋ s}YfTlmrZ)'Nk۞pw\Tȯ?8`Oi{wﭹW[r Q4F׊3m&L=h3z~#\l :F,j@ ʱwQT8"kJO6֚l}R>ډK]y&p}b;N1mr$|7>e@BTM*-iHgD) Em|ؘbҗaҾt4oG*oCNrPQ@z,|?W[0:n,jWiEW$~/hp\?{(0+Y8rΟ+>S-SVN;}s?. w9˟<Mq4Wv'{)01mBVW[8/< %wT^5b)iM pgN&ݝVO~qu9 !J27$O-! :%H ـyΠM=t{!S oK8txA& j0 vF Y|y ~6@c1vOpIg4lODL Rcj_uX63?nkWyf;^*B @~a`Eu+6L.ü>}y}_O6͐:YrGXkGl^w~㒶syIu! W XN7BVO!X2wvGRfT#t/?%8^WaTGcLMI(J1~8?aT ]ASE(*E} 2#I/׍qz^t̔bYz4xt){ OH+(EA&NXTo"XC')}Jzp ~5}^+6wcQ|LpdH}(.|kc4^"Z?ȕ a<L!039C EuCFEwç ;n?*oB8bʝ'#RqfM}7]s2tcS{\icTx;\7KPʇ Z O-~c>"?PEO8@8GQgaՎ󁶠䧘_%#r>1zaebqcPѵn#L =׀t L7`VA{C:ge@w1 Xp3c3ġpM"'-@n4fGB3DJ8[JoߐgK)ƛ$ 83+ 6ʻ SkI*KZlT _`?KQKdB`s}>`*>,*@JdoF*弝O}ks]yߘc1GV<=776qPTtXԀ!9*44Tހ3XΛex46YD  BdemDa\_l,G/֌7Y](xTt^%GE4}bTڹ;Y)BQu>J/J ⮶.XԄjݳ+Ed r5_D1 o Bx΢#<W8R6@gM. drD>(otU@x=~v2 ӣdoBd3eO6㣷ݜ66YQz`S{\P~z m5{J/L1xO\ZFu>ck#&:`$ai>2ΔloF[hlEܺΠk:)` $[69kOw\|8}ބ:񶐕IA1/=2[,!.}gN#ub ~݊}34qdELc$"[qU硬g^%B zrpJru%v\h1Yne`ǥ:gpQM~^Xi `S:V29.PV?Bk AEvw%_9CQwKekPؠ\;Io d{ ߞoc1eP\ `E=@KIRYK2NPlLɀ)&eB+ь( JTx_?EZ }@ 6U뙢طzdWIn` D噥[uV"G&Ú2g}&m?ċ"Om# {ON"SXNeysQ@FnVgdX~nj]J58up~.`r\O,ư0oS _Ml4kv\JSdxSW<AeIX$Iw:Sy›R9Q[,5;@]%u@ *rolbI  +%m:͇ZVủθau,RW33 dJeTYE.Mϧ-oj3+yy^cVO9NV\nd1 !͕_)av;թMlWR1)ElP;yوÏu 3k5Pr6<⒲l!˞*u־n!l:UNW %Chx8vL'X@*)̮ˍ D-M+JUkvK+x8cY?Ԡ~3mo|u@[XeYC\Kpx8oCC&N~3-H MXsu<`~"WL$8ξ3a)|:@m\^`@ҷ)5p+6p%i)P Mngc#0AruzRL+xSS?ʮ}()#tmˇ!0}}y$6Lt;$ʳ{^6{v6ķܰgVcnn ~zx«,2u?cE+ȘH؎%Za)X>uWTzNyosFQƤ$*&LLXL)1" LeOɟ9=:tZcŽY?ӭVwv~,Yrۗ|yGaFC.+ v1fήJ]STBn5sW}y$~z'c 8  ,! pVNSNNqy8z˱A4*'2n<s^ǧ˭PJޮɏUGLJ*#i}K%,)[z21z ?Nin1?TIR#m-1lA`fT5+ܐcq՝ʐ,3f2Uեmab#ŠdQy>\)SLYw#.ʑf ,"+w~N'cO3FN<)j&,- љ֊_zSTǦw>?nU仆Ve0$CdrP m׈eXmVu L.bֹ [Դaզ*\y8Է:Ez\0KqC b̘cөQ=0YsNS.3.Oo:#v7[#߫ 5܎LEr49nCOWlG^0k%;YߝZǓ:S#|}y,/kLd TA(AI$+I3;Y*Z}|ӧOdv..#:nf>>ȶITX 8y"dR|)0=n46ⲑ+ra ~]R̲c?6(q;5% |uj~z8R=XIV=|{vGj\gcqz؋%Mߍ1y#@f^^>N#x#۹6Y~?dfPO{P4Vu1E1J *|%JN`eWuzk M6q t[ gGvWIGu_ft5j"Y:Tɐ*; e54q$C2d} _SL#mYpO.C;cHi#֩%+) ӍƲVSYźg |tj38r|V1#;.SQA[S#`n+$$I P\[@s(EDzP])8G#0B[ىXIIq<9~[Z멜Z⊔IWU&A>P~#dp]9 "cP Md?٥Ifتuk/F9c*9Ǎ:ØFzn*@|Iށ9N3{'['ͬҲ4#}!V Fu,,mTIkv C7vB6kT91*l '~ƞFlU'M ][ΩũJ_{iIn$L jOdxkza۪#EClx˘oVɞljr)/,߬hL#^Lф,íMƁe̩NBLiLq}(q6IçJ$WE$:=#(KBzђ xlx?>Պ+>W,Ly!_DŌlQ![ SJ1ƐY}b,+Loxɓ)=yoh@꥟/Iѭ=Py9 ۍYӘe+pJnϱ?V\SO%(t =?MR[Șd/ nlB7j !;ӥ/[-A>dNsLj ,ɪv=1c.SQO3UƀܽE̻9GϷD7(}Ävӌ\y_0[w <΍>a_[0+LF.޺f>oNTq;y\bՃyjH<|q-eɏ_?_9+PHp$[uxK wMwNی'$Y2=qKBP~Yul:[<F12O5=d]Ysw:ϮEj,_QXz`H1,#II dwrP˂@ZJVy$\y{}^~[:NߌUOdؾe${p>G3cĖlʌ ת[`ϱ-WdgIig2 }s ؤ(%#sS@~3XnRG~\jc3vӍLM[JBTs3}jNʖW;7ç?=XF=-=qߚ#='c7ڑWI(O+=:uxqe2zi+kuGR0&eniT^J~\jyp'dtGsO39* b#Ɋ p[BwsT>d4ۧsnvnU_~,vƜJ1s QIz)(lv8MU=;56Gs#KMP=LvyGd}VwWBF'à ?MHUg2 !p7Qjڴ=ju JnA suMeƆҔ!)'8Ϣٔޝ(Vpצ֖d=ICJǠ{qkԭ߸i@Ku|p=..*+xz[Aqġ#s2aƊRR)*HRsi~a &fMP-KL@ZXy'x{}Zm+:)) IJ-iu ܒH'L(7yGӜq j 6ߌg1go,kرtY?W,pefOQS!K۟cҒA|սj>=⬒˧L[ ߿2JaB~Ru:Q] 0H~]7ƼI(}cq 'ήETq?fabӥvr )o-Q_'ᴎoK;Vo%~OK *bf:-ťIR`B5!RB@ï u ̯e\_U_ gES3QTaxU<~c?*#]MW,[8Oax]1bC|踤Plw5V%){t<d50iXSUm:Z┵i"1^B-PhJ&)O*DcWvM)}Pܗ-q\mmζZ-l@}aE6F@&Sg@ݚM ȹ 4#p\HdYDoH"\..RBHz_/5˘6KhJRPmƶim3,#ccoqa)*PtRmk7xDE\Y閣_X<~)c[[BP6YqS0%_;Àv~| VS؇ 'O0F0\U-d@7SJ*z3nyPOm~P3|Yʉr#CSN@ ƮRN)r"C:: #qbY. 6[2K2uǦHYRQMV G$Q+.>nNHq^ qmMVD+-#*U̒ p욳u:IBmPV@Or[b= 1UE_NmyKbNOU}the`|6֮P>\2PVIDiPO;9rmAHGWS]J*_G+kP2KaZH'KxWMZ%OYDRc+o?qGhmdSoh\D|:WUAQc yTq~^H/#pCZTI1ӏT4"ČZ}`w#*,ʹ 0i課Om*da^gJ݅{le9uF#Tֲ̲ٞC"qߍ ոޑo#XZTp@ o8(jdxw],f`~|,s^f1t|m򸄭/ctr5s79Q4H1꠲BB@l9@C+wpxu£Yc9?`@#omHs2)=2.ljg9$YS%*LRY7Z,*=䷘$armoϰUW.|rufIGwtZwo~5 YյhO+=8fF)W7L9lM̘·Y֘YLf큹pRF99.A "wz=E\Z'a 2Ǚ#;'}G*l^"q+2FQ hjkŦ${ޮ-T٭cf|3#~RJt$b(R(rdx >U b&9,>%E\ Άe$'q't*אެb-|dSBOO$R+H)܎K1m`;J2Y~9Og8=vqD`K[F)k[1m޼cn]skz$@)!I x՝"v9=ZA=`Ɠi :E)`7vI}dYI_ o:obo 3Q&D&2= Ά;>hy.*ⅥSӬ+q&j|UƧ}J0WW< ۋS)jQRjƯrN)Gű4Ѷ(S)Ǣ8iW52No˓ ۍ%5brOnL;n\G=^UdI8$&h'+(cȁ߫klS^cƗjԌEꭔgFȒ@}O*;evWVYJ\]X'5ղkFb 6Ro՜mi Ni>J?lPmU}>_Z&KKqrIDՉ~q3fL:Se>E-G{L6pe,8QIhaXaUA'ʂs+טIjP-y8ۈZ?J$WP Rs]|l(ԓsƊio(S0Y 8T97.WiLc~dxcE|2!XKƘਫ਼$((6~|d9u+qd^389Y6L.I?iIq9)O/뚅OXXVZF[یgQLK1RҖr@v#XlFНyS87kF!AsM^rkpjPDyS$Nqnxҍ!Uf!ehi2m`YI9r6 TFC}/y^Η5d'9A-J>{_l+`A['յϛ#w:݅%X}&PStQ"-\縵/$ƗhXb*yBS;Wջ_mcvt?2}1;qSdd~u:2k52R~z+|HE!)Ǟl7`0<,2*Hl-x^'_TVgZA'j ^2ΪN7t?w x1fIzC-ȖK^q;-WDvT78Z hK(P:Q- 8nZ܃e貾<1YT<,"6{/ ?͟|1:#gW>$dJdB=jf[%rE^il:BxSּ1հ,=*7 fcG#q eh?27,!7x6nLC4x},GeǝtC.vS F43zz\;QYC,6~;RYS/6|25vTimlv& nRh^ejRLGf? ۉҬܦƩ|Ȱ>3!viʯ>vオX3e_1zKȗ\qHS,EW[㺨uch⍸O}a>q6n6N6qN ! 1AQaq0@"2BRb#Pr3C`Scst$4D%Td ?Na3mCwxAmqmm$4n淿t'C"wzU=D\R+wp+YT&պ@ƃ3ޯ?AﶂaŘ@-Q=9Dռѻ@MVP܅G5fY6# ?0UQ,IX(6ڵ[DIMNލc&υj\XR|,4 jThAe^db#$]wOӪ1y%LYm뭛CUƃߜ}Cy1XνmF8jI]HۺиE@Ii;r8ӭVFՇ| &?3|xBMuSGe=Ӕ#BE5GY!z_eqр/W>|-Ci߇t1ޯќdR3ug=0 5[?#͏qcfH{ ?u=??ǯ}ZzhmΔBFTWPxs}G93 )gGR<>r h$'nchPBjJҧH -N1N?~}-q!=_2hcMlvY%UE@|vM2.Y[|y"EïKZF,ɯ?,q?vM 80jx";9vk+ ֧ ȺU?%vcVmA6Qg^MA}3nl QRNl8kkn'(M7m9وq%ޟ*h$Zk"$9: ?U8Sl,,|ɒxH(ѷGn/Q4PG%Ա8N! &7;eKM749R/%lc>x;>C:th?aKXbheᜋ^$Iհ hr7%F$EFdt5+(M6tÜUU|zW=aTsTgdqPQb'm1{|YXNb P~F^F:k6"j! Ir`1&-$Bevk:y#ywI0x=D4tUPZHڠ底taP6b>xaQ# WeFŮNjpJ* mQN*I-*ȩFg3 5Vʊɮa5FO@{NX?H]31Ri_uѕ 0 F~:60p͈SqX#a5>`o&+<2D: ڝ$nP*)N|yEjF5ټeihyZ >kbHavh-#!Po=@k̆IEN@}Ll?jO߭ʞQ|A07xwt!xfI2?Z<ץTcUj]陎Ltl }5ϓ$,Omˊ;@OjEj(ا,LXLOЦ90O .anA7j4 W_ٓzWjcBy՗+EM)dNg6y1_xp$Lv:9"zpʙ$^JԼ*ϭo=xLj6Ju82AH3$ٕ@=Vv]'qEz;I˼)=ɯx /W(Vp$ mu񶤑OqˎTr㠚xsrGCbypG1ߠw e8$⿄/M{*}W]˷.CK\ުx/$WPwr |i&}{X >$-l?-zglΆ(FhvS*b߲ڡn,|)mrH[a3ר[13o_U3TC$(=)0kgP u^=4 WYCҸ:vQרXàtkm,t*^,}D* "(I9R>``[~Q]#afi6l86:,ssN6j"A4IuQ6E,GnHzSHOuk5$I4ؤQ9@CwpBGv[]uOv0I4\yQѸ~>Z8Taqޣ;za/SI:ܫ_|>=Z8:SUIJ"IY8%b8H:QO6;7ISJҌAά3>cE+&jf$eC+z;V rʺmyeaQf&6ND.:NTvm<- uǝ\MvZYNNT-A>jr!SnO 13Ns%3D@`ܟ 1^c< aɽ̲Xë#w|ycW=9I*H8p^(4՗karOcWtO\ƍR8'KIQ?5>[}yUײ -h=% qThG2)"ו3]!kB*pFDlA,eEiHfPs5H:Փ~H0DتDIhF3c2E9H5zԑʚiX=:mxghd(v׊9iSOd@0ڽ:p5h-t&Xqӕ,ie|7A2O%PEhtjY1wЃ!  ࢽMy7\a@ţJ 4ȻF@o̒?4wx)]P~u57X 9^ܩU;Iꭆ 5 eK27({|Y׎ V\"Z1 Z}(Ǝ"1S_vE30>p; ΝD%xW?W?vo^Vidr[/&>~`9Why;R ;;ɮT?r$g1KACcKl:'3 cﳯ*"t8~l)m+U,z`(>yJ?h>]vЍG*{`;y]IT ;cNUfo¾h/$|NS1S"HVT4uhǜ]v;5͠x'C\SBplh}N ABx%ޭl/Twʽ]D=Kžr㻠l4SO?=k M: cCa#ha)ѐxcsgPiG{+xQI= zԫ+ 8"kñj=|c yCF/*9жh{ ?4o kmQNx;Y4膚aw?6>e]Qr:g,i"ԩA*M7qB?ӕFhV25r[7 Y }LR}*sg+xr2U=*'WSZDW]WǞ<叓{$9Ou4y90-1'*D`c^o?(9uݐ'PI& fJݮ:wSjfP1F:X H9dԯ˝[_54 }*;@ܨ ðynT?ןd#4rGͨH1|-#MrS3G3).᧏3vz֑r$G"`j 1tx0<ƆWh6y6,œGagAyb)hDß_mü gG;evݝnQ C-*oyaMI><]obD":GA-\%LT8c)+y76oQ#*{(F⽕y=rW\p۩cA^e6KʐcVf5$'->ՉN"F"UQ@fGb~#&M=8טJNu9D[̤so~ G9TtW^g5y$bY'سǴ=U-2 #MCt(i lj@Q 5̣i*OsxKf}\M{EV{υƇ);HIfeLȣr2>WIȂ6ik 5YOxȺ>Yf5'|H+98pjn.OyjY~iw'l;s2Y:'lgꥴ)o#'SaaKZ m}`169n"xI *+ }FP"l45'ZgE8?[X7(.Q-*ތL@̲v.5[=t\+CNܛ,gSQnH}*FG16&:t4ُ"Ạ$b |#rsaT ]ӽDP7ո0y)e$ٕvIh'QEAm*HRI=: 4牢) %_iNݧl] NtGHL ɱg<1V,J~ٹ"KQ 9HS9?@kr;we݁]I!{ @G["`J:n]{cAEVʆ#U96j#Ym\qe4hB7Cdv\MNgmAyQL4uLjj9#44tl^}LnR!t±]rh6ٍ>yҏNfU  Fm@8}/ujb9he:AyծwGpΧh5l}3p468)Udc;Us/֔YX1O2uqs`hwgr~{ RmhN؎*q 42*th>#E#HvOq}6e\,Wk#Xb>p}դ3T5†6[@Py*n|'f֧>lư΂̺SU'*qp_SM 'c6m ySʨ;MrƋmKxo,GmPAG:iw9}M(^V$ǒѽ9| aJSQarB;}ٻ֢2%Uc#gNaݕ'v[OY'3L3;,p]@S{lsX'cjwk'a.}}& dP*bK=ɍ!;3ngΊUߴmt'*{,=SzfD Ako~Gaoq_mi}#mPXhύmxǍ΂巿zfQc|kc?WY$_Lvl߶c`?ljݲˏ!V6UЂ(A4y)HpZ_x>eR$/`^'3qˏ-&Q=?CFVR DfV9{8gnh(P"6[D< E~0<@`G6Hгcc cK.5DdB`?XQ2ٿyqo&+1^ DW0ꊩG#QnL3c/x 11[yxპCWCcUĨ80me4.{muI=f0QRls9f9~fǨa"@8ȁQ#cicG$Gr/$W(WV"m7[mAmboD j۳ l^kh׽ # iXnveTka^Y4BNĕ0 !01@Q"2AaPq3BR?@4QT3,㺠W[=JKϞ2r^7vc:9 EߴwS#dIxu:Hp9E! V 2;73|F9Y*ʬFDu&y؟^EAA(ɩ^GV:ݜDy`Jr29ܾ㝉[E;FzxYGUeYC v-txIsםĘqEb+P\ :>iC';k|zرny]#ǿbQw(r|ӹs[D2v-%@;8<a[\o[ϧwI!*0krs)[J9^ʜp1) "/_>o<1AEy^C`x1'ܣnps`lfQ):lb>MejH^?kl3(z:1ŠK&?Q~{ٺhy/[V|6}KbXmn[-75q94dmc^h X5G-}دBޟ |rtMV+]c?-#ڛ^ǂ}LkrOu>-Dry D?:ޞUǜ7V?瓮"#rչģVR;n/_ ؉vݶe5db9/O009G5nWJpA*r9>1.[tsFnQ V 77R]ɫ8_0<՜IFu(v4Fk3E)N:yڮeP`1}$WSJSQNjٺ޵#lј(5=5lǏmoWv-1v,Wmn߀$x_DȬ0¤#QR[Vkzmw"9ZG7'[=Qj8R?zf\a=OU*oBA|G254 p.w7  &ξxGHp B%$gtЏ򤵍zHNuЯ-'40;_3 !01"@AQa2Pq#3BR?ʩcaen^8F<7;EA{EÖ1U/#d1an.1ě0ʾRh|RAo3m3 % 28Q yφHTo7lW>#i`qca m,B-j݋'mR1Ήt>Vps0IbIC.1Rea]H64B>o]($Bma!=?B KǾ+Ծ"nK*+[T#{EJSQs5:U\wĐf3܆&)IԆwE TlrTf6Q|Rh:[K zc֧GC%\_a84HcObiؖV7H )*ģK~Xhչ04?0 E<}3#u? |gS6ꊤ|I#Hڛ աwX97Ŀ%SLy6č|Fa 8b$sקhb9RAu7˨pČ_\*w묦F 4D~f|("mNKiS>$d7SlA/²SL|6N}S˯g]6; #. 403WebShell
403Webshell
Server IP : 45.32.152.128  /  Your IP : 216.73.216.91
Web Server : nginx/1.24.0
System : Linux stage-vultr 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User : forge ( 1000)
PHP Version : 8.2.14
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /home/forge/client.3digma.com/node_modules/esquery/dist/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/forge/client.3digma.com/node_modules/esquery/dist/esquery.esm.js
function _typeof(obj) {
  "@babel/helpers - typeof";

  if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
    _typeof = function (obj) {
      return typeof obj;
    };
  } else {
    _typeof = function (obj) {
      return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
    };
  }

  return _typeof(obj);
}

function _slicedToArray(arr, i) {
  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}

function _toConsumableArray(arr) {
  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}

function _arrayWithoutHoles(arr) {
  if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}

function _arrayWithHoles(arr) {
  if (Array.isArray(arr)) return arr;
}

function _iterableToArray(iter) {
  if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}

function _iterableToArrayLimit(arr, i) {
  if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
  var _arr = [];
  var _n = true;
  var _d = false;
  var _e = undefined;

  try {
    for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
      _arr.push(_s.value);

      if (i && _arr.length === i) break;
    }
  } catch (err) {
    _d = true;
    _e = err;
  } finally {
    try {
      if (!_n && _i["return"] != null) _i["return"]();
    } finally {
      if (_d) throw _e;
    }
  }

  return _arr;
}

function _unsupportedIterableToArray(o, minLen) {
  if (!o) return;
  if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === "Object" && o.constructor) n = o.constructor.name;
  if (n === "Map" || n === "Set") return Array.from(o);
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}

function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length;

  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];

  return arr2;
}

function _nonIterableSpread() {
  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

function _nonIterableRest() {
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

function _createForOfIteratorHelper(o, allowArrayLike) {
  var it;

  if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
    if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
      if (it) o = it;
      var i = 0;

      var F = function () {};

      return {
        s: F,
        n: function () {
          if (i >= o.length) return {
            done: true
          };
          return {
            done: false,
            value: o[i++]
          };
        },
        e: function (e) {
          throw e;
        },
        f: F
      };
    }

    throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  }

  var normalCompletion = true,
      didErr = false,
      err;
  return {
    s: function () {
      it = o[Symbol.iterator]();
    },
    n: function () {
      var step = it.next();
      normalCompletion = step.done;
      return step;
    },
    e: function (e) {
      didErr = true;
      err = e;
    },
    f: function () {
      try {
        if (!normalCompletion && it.return != null) it.return();
      } finally {
        if (didErr) throw err;
      }
    }
  };
}

var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

function createCommonjsModule(fn, module) {
	return module = { exports: {} }, fn(module, module.exports), module.exports;
}

var estraverse = createCommonjsModule(function (module, exports) {
  /*
    Copyright (C) 2012-2013 Yusuke Suzuki <utatane.tea@gmail.com>
    Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
  
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
  
      * Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
      * Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
  
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */

  /*jslint vars:false, bitwise:true*/

  /*jshint indent:4*/

  /*global exports:true*/
  (function clone(exports) {

    var Syntax, VisitorOption, VisitorKeys, BREAK, SKIP, REMOVE;

    function deepCopy(obj) {
      var ret = {},
          key,
          val;

      for (key in obj) {
        if (obj.hasOwnProperty(key)) {
          val = obj[key];

          if (typeof val === 'object' && val !== null) {
            ret[key] = deepCopy(val);
          } else {
            ret[key] = val;
          }
        }
      }

      return ret;
    } // based on LLVM libc++ upper_bound / lower_bound
    // MIT License


    function upperBound(array, func) {
      var diff, len, i, current;
      len = array.length;
      i = 0;

      while (len) {
        diff = len >>> 1;
        current = i + diff;

        if (func(array[current])) {
          len = diff;
        } else {
          i = current + 1;
          len -= diff + 1;
        }
      }

      return i;
    }

    Syntax = {
      AssignmentExpression: 'AssignmentExpression',
      AssignmentPattern: 'AssignmentPattern',
      ArrayExpression: 'ArrayExpression',
      ArrayPattern: 'ArrayPattern',
      ArrowFunctionExpression: 'ArrowFunctionExpression',
      AwaitExpression: 'AwaitExpression',
      // CAUTION: It's deferred to ES7.
      BlockStatement: 'BlockStatement',
      BinaryExpression: 'BinaryExpression',
      BreakStatement: 'BreakStatement',
      CallExpression: 'CallExpression',
      CatchClause: 'CatchClause',
      ChainExpression: 'ChainExpression',
      ClassBody: 'ClassBody',
      ClassDeclaration: 'ClassDeclaration',
      ClassExpression: 'ClassExpression',
      ComprehensionBlock: 'ComprehensionBlock',
      // CAUTION: It's deferred to ES7.
      ComprehensionExpression: 'ComprehensionExpression',
      // CAUTION: It's deferred to ES7.
      ConditionalExpression: 'ConditionalExpression',
      ContinueStatement: 'ContinueStatement',
      DebuggerStatement: 'DebuggerStatement',
      DirectiveStatement: 'DirectiveStatement',
      DoWhileStatement: 'DoWhileStatement',
      EmptyStatement: 'EmptyStatement',
      ExportAllDeclaration: 'ExportAllDeclaration',
      ExportDefaultDeclaration: 'ExportDefaultDeclaration',
      ExportNamedDeclaration: 'ExportNamedDeclaration',
      ExportSpecifier: 'ExportSpecifier',
      ExpressionStatement: 'ExpressionStatement',
      ForStatement: 'ForStatement',
      ForInStatement: 'ForInStatement',
      ForOfStatement: 'ForOfStatement',
      FunctionDeclaration: 'FunctionDeclaration',
      FunctionExpression: 'FunctionExpression',
      GeneratorExpression: 'GeneratorExpression',
      // CAUTION: It's deferred to ES7.
      Identifier: 'Identifier',
      IfStatement: 'IfStatement',
      ImportExpression: 'ImportExpression',
      ImportDeclaration: 'ImportDeclaration',
      ImportDefaultSpecifier: 'ImportDefaultSpecifier',
      ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
      ImportSpecifier: 'ImportSpecifier',
      Literal: 'Literal',
      LabeledStatement: 'LabeledStatement',
      LogicalExpression: 'LogicalExpression',
      MemberExpression: 'MemberExpression',
      MetaProperty: 'MetaProperty',
      MethodDefinition: 'MethodDefinition',
      ModuleSpecifier: 'ModuleSpecifier',
      NewExpression: 'NewExpression',
      ObjectExpression: 'ObjectExpression',
      ObjectPattern: 'ObjectPattern',
      Program: 'Program',
      Property: 'Property',
      RestElement: 'RestElement',
      ReturnStatement: 'ReturnStatement',
      SequenceExpression: 'SequenceExpression',
      SpreadElement: 'SpreadElement',
      Super: 'Super',
      SwitchStatement: 'SwitchStatement',
      SwitchCase: 'SwitchCase',
      TaggedTemplateExpression: 'TaggedTemplateExpression',
      TemplateElement: 'TemplateElement',
      TemplateLiteral: 'TemplateLiteral',
      ThisExpression: 'ThisExpression',
      ThrowStatement: 'ThrowStatement',
      TryStatement: 'TryStatement',
      UnaryExpression: 'UnaryExpression',
      UpdateExpression: 'UpdateExpression',
      VariableDeclaration: 'VariableDeclaration',
      VariableDeclarator: 'VariableDeclarator',
      WhileStatement: 'WhileStatement',
      WithStatement: 'WithStatement',
      YieldExpression: 'YieldExpression'
    };
    VisitorKeys = {
      AssignmentExpression: ['left', 'right'],
      AssignmentPattern: ['left', 'right'],
      ArrayExpression: ['elements'],
      ArrayPattern: ['elements'],
      ArrowFunctionExpression: ['params', 'body'],
      AwaitExpression: ['argument'],
      // CAUTION: It's deferred to ES7.
      BlockStatement: ['body'],
      BinaryExpression: ['left', 'right'],
      BreakStatement: ['label'],
      CallExpression: ['callee', 'arguments'],
      CatchClause: ['param', 'body'],
      ChainExpression: ['expression'],
      ClassBody: ['body'],
      ClassDeclaration: ['id', 'superClass', 'body'],
      ClassExpression: ['id', 'superClass', 'body'],
      ComprehensionBlock: ['left', 'right'],
      // CAUTION: It's deferred to ES7.
      ComprehensionExpression: ['blocks', 'filter', 'body'],
      // CAUTION: It's deferred to ES7.
      ConditionalExpression: ['test', 'consequent', 'alternate'],
      ContinueStatement: ['label'],
      DebuggerStatement: [],
      DirectiveStatement: [],
      DoWhileStatement: ['body', 'test'],
      EmptyStatement: [],
      ExportAllDeclaration: ['source'],
      ExportDefaultDeclaration: ['declaration'],
      ExportNamedDeclaration: ['declaration', 'specifiers', 'source'],
      ExportSpecifier: ['exported', 'local'],
      ExpressionStatement: ['expression'],
      ForStatement: ['init', 'test', 'update', 'body'],
      ForInStatement: ['left', 'right', 'body'],
      ForOfStatement: ['left', 'right', 'body'],
      FunctionDeclaration: ['id', 'params', 'body'],
      FunctionExpression: ['id', 'params', 'body'],
      GeneratorExpression: ['blocks', 'filter', 'body'],
      // CAUTION: It's deferred to ES7.
      Identifier: [],
      IfStatement: ['test', 'consequent', 'alternate'],
      ImportExpression: ['source'],
      ImportDeclaration: ['specifiers', 'source'],
      ImportDefaultSpecifier: ['local'],
      ImportNamespaceSpecifier: ['local'],
      ImportSpecifier: ['imported', 'local'],
      Literal: [],
      LabeledStatement: ['label', 'body'],
      LogicalExpression: ['left', 'right'],
      MemberExpression: ['object', 'property'],
      MetaProperty: ['meta', 'property'],
      MethodDefinition: ['key', 'value'],
      ModuleSpecifier: [],
      NewExpression: ['callee', 'arguments'],
      ObjectExpression: ['properties'],
      ObjectPattern: ['properties'],
      Program: ['body'],
      Property: ['key', 'value'],
      RestElement: ['argument'],
      ReturnStatement: ['argument'],
      SequenceExpression: ['expressions'],
      SpreadElement: ['argument'],
      Super: [],
      SwitchStatement: ['discriminant', 'cases'],
      SwitchCase: ['test', 'consequent'],
      TaggedTemplateExpression: ['tag', 'quasi'],
      TemplateElement: [],
      TemplateLiteral: ['quasis', 'expressions'],
      ThisExpression: [],
      ThrowStatement: ['argument'],
      TryStatement: ['block', 'handler', 'finalizer'],
      UnaryExpression: ['argument'],
      UpdateExpression: ['argument'],
      VariableDeclaration: ['declarations'],
      VariableDeclarator: ['id', 'init'],
      WhileStatement: ['test', 'body'],
      WithStatement: ['object', 'body'],
      YieldExpression: ['argument']
    }; // unique id

    BREAK = {};
    SKIP = {};
    REMOVE = {};
    VisitorOption = {
      Break: BREAK,
      Skip: SKIP,
      Remove: REMOVE
    };

    function Reference(parent, key) {
      this.parent = parent;
      this.key = key;
    }

    Reference.prototype.replace = function replace(node) {
      this.parent[this.key] = node;
    };

    Reference.prototype.remove = function remove() {
      if (Array.isArray(this.parent)) {
        this.parent.splice(this.key, 1);
        return true;
      } else {
        this.replace(null);
        return false;
      }
    };

    function Element(node, path, wrap, ref) {
      this.node = node;
      this.path = path;
      this.wrap = wrap;
      this.ref = ref;
    }

    function Controller() {} // API:
    // return property path array from root to current node


    Controller.prototype.path = function path() {
      var i, iz, j, jz, result, element;

      function addToPath(result, path) {
        if (Array.isArray(path)) {
          for (j = 0, jz = path.length; j < jz; ++j) {
            result.push(path[j]);
          }
        } else {
          result.push(path);
        }
      } // root node


      if (!this.__current.path) {
        return null;
      } // first node is sentinel, second node is root element


      result = [];

      for (i = 2, iz = this.__leavelist.length; i < iz; ++i) {
        element = this.__leavelist[i];
        addToPath(result, element.path);
      }

      addToPath(result, this.__current.path);
      return result;
    }; // API:
    // return type of current node


    Controller.prototype.type = function () {
      var node = this.current();
      return node.type || this.__current.wrap;
    }; // API:
    // return array of parent elements


    Controller.prototype.parents = function parents() {
      var i, iz, result; // first node is sentinel

      result = [];

      for (i = 1, iz = this.__leavelist.length; i < iz; ++i) {
        result.push(this.__leavelist[i].node);
      }

      return result;
    }; // API:
    // return current node


    Controller.prototype.current = function current() {
      return this.__current.node;
    };

    Controller.prototype.__execute = function __execute(callback, element) {
      var previous, result;
      result = undefined;
      previous = this.__current;
      this.__current = element;
      this.__state = null;

      if (callback) {
        result = callback.call(this, element.node, this.__leavelist[this.__leavelist.length - 1].node);
      }

      this.__current = previous;
      return result;
    }; // API:
    // notify control skip / break


    Controller.prototype.notify = function notify(flag) {
      this.__state = flag;
    }; // API:
    // skip child nodes of current node


    Controller.prototype.skip = function () {
      this.notify(SKIP);
    }; // API:
    // break traversals


    Controller.prototype['break'] = function () {
      this.notify(BREAK);
    }; // API:
    // remove node


    Controller.prototype.remove = function () {
      this.notify(REMOVE);
    };

    Controller.prototype.__initialize = function (root, visitor) {
      this.visitor = visitor;
      this.root = root;
      this.__worklist = [];
      this.__leavelist = [];
      this.__current = null;
      this.__state = null;
      this.__fallback = null;

      if (visitor.fallback === 'iteration') {
        this.__fallback = Object.keys;
      } else if (typeof visitor.fallback === 'function') {
        this.__fallback = visitor.fallback;
      }

      this.__keys = VisitorKeys;

      if (visitor.keys) {
        this.__keys = Object.assign(Object.create(this.__keys), visitor.keys);
      }
    };

    function isNode(node) {
      if (node == null) {
        return false;
      }

      return typeof node === 'object' && typeof node.type === 'string';
    }

    function isProperty(nodeType, key) {
      return (nodeType === Syntax.ObjectExpression || nodeType === Syntax.ObjectPattern) && 'properties' === key;
    }

    function candidateExistsInLeaveList(leavelist, candidate) {
      for (var i = leavelist.length - 1; i >= 0; --i) {
        if (leavelist[i].node === candidate) {
          return true;
        }
      }

      return false;
    }

    Controller.prototype.traverse = function traverse(root, visitor) {
      var worklist, leavelist, element, node, nodeType, ret, key, current, current2, candidates, candidate, sentinel;

      this.__initialize(root, visitor);

      sentinel = {}; // reference

      worklist = this.__worklist;
      leavelist = this.__leavelist; // initialize

      worklist.push(new Element(root, null, null, null));
      leavelist.push(new Element(null, null, null, null));

      while (worklist.length) {
        element = worklist.pop();

        if (element === sentinel) {
          element = leavelist.pop();
          ret = this.__execute(visitor.leave, element);

          if (this.__state === BREAK || ret === BREAK) {
            return;
          }

          continue;
        }

        if (element.node) {
          ret = this.__execute(visitor.enter, element);

          if (this.__state === BREAK || ret === BREAK) {
            return;
          }

          worklist.push(sentinel);
          leavelist.push(element);

          if (this.__state === SKIP || ret === SKIP) {
            continue;
          }

          node = element.node;
          nodeType = node.type || element.wrap;
          candidates = this.__keys[nodeType];

          if (!candidates) {
            if (this.__fallback) {
              candidates = this.__fallback(node);
            } else {
              throw new Error('Unknown node type ' + nodeType + '.');
            }
          }

          current = candidates.length;

          while ((current -= 1) >= 0) {
            key = candidates[current];
            candidate = node[key];

            if (!candidate) {
              continue;
            }

            if (Array.isArray(candidate)) {
              current2 = candidate.length;

              while ((current2 -= 1) >= 0) {
                if (!candidate[current2]) {
                  continue;
                }

                if (candidateExistsInLeaveList(leavelist, candidate[current2])) {
                  continue;
                }

                if (isProperty(nodeType, candidates[current])) {
                  element = new Element(candidate[current2], [key, current2], 'Property', null);
                } else if (isNode(candidate[current2])) {
                  element = new Element(candidate[current2], [key, current2], null, null);
                } else {
                  continue;
                }

                worklist.push(element);
              }
            } else if (isNode(candidate)) {
              if (candidateExistsInLeaveList(leavelist, candidate)) {
                continue;
              }

              worklist.push(new Element(candidate, key, null, null));
            }
          }
        }
      }
    };

    Controller.prototype.replace = function replace(root, visitor) {
      var worklist, leavelist, node, nodeType, target, element, current, current2, candidates, candidate, sentinel, outer, key;

      function removeElem(element) {
        var i, key, nextElem, parent;

        if (element.ref.remove()) {
          // When the reference is an element of an array.
          key = element.ref.key;
          parent = element.ref.parent; // If removed from array, then decrease following items' keys.

          i = worklist.length;

          while (i--) {
            nextElem = worklist[i];

            if (nextElem.ref && nextElem.ref.parent === parent) {
              if (nextElem.ref.key < key) {
                break;
              }

              --nextElem.ref.key;
            }
          }
        }
      }

      this.__initialize(root, visitor);

      sentinel = {}; // reference

      worklist = this.__worklist;
      leavelist = this.__leavelist; // initialize

      outer = {
        root: root
      };
      element = new Element(root, null, null, new Reference(outer, 'root'));
      worklist.push(element);
      leavelist.push(element);

      while (worklist.length) {
        element = worklist.pop();

        if (element === sentinel) {
          element = leavelist.pop();
          target = this.__execute(visitor.leave, element); // node may be replaced with null,
          // so distinguish between undefined and null in this place

          if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) {
            // replace
            element.ref.replace(target);
          }

          if (this.__state === REMOVE || target === REMOVE) {
            removeElem(element);
          }

          if (this.__state === BREAK || target === BREAK) {
            return outer.root;
          }

          continue;
        }

        target = this.__execute(visitor.enter, element); // node may be replaced with null,
        // so distinguish between undefined and null in this place

        if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) {
          // replace
          element.ref.replace(target);
          element.node = target;
        }

        if (this.__state === REMOVE || target === REMOVE) {
          removeElem(element);
          element.node = null;
        }

        if (this.__state === BREAK || target === BREAK) {
          return outer.root;
        } // node may be null


        node = element.node;

        if (!node) {
          continue;
        }

        worklist.push(sentinel);
        leavelist.push(element);

        if (this.__state === SKIP || target === SKIP) {
          continue;
        }

        nodeType = node.type || element.wrap;
        candidates = this.__keys[nodeType];

        if (!candidates) {
          if (this.__fallback) {
            candidates = this.__fallback(node);
          } else {
            throw new Error('Unknown node type ' + nodeType + '.');
          }
        }

        current = candidates.length;

        while ((current -= 1) >= 0) {
          key = candidates[current];
          candidate = node[key];

          if (!candidate) {
            continue;
          }

          if (Array.isArray(candidate)) {
            current2 = candidate.length;

            while ((current2 -= 1) >= 0) {
              if (!candidate[current2]) {
                continue;
              }

              if (isProperty(nodeType, candidates[current])) {
                element = new Element(candidate[current2], [key, current2], 'Property', new Reference(candidate, current2));
              } else if (isNode(candidate[current2])) {
                element = new Element(candidate[current2], [key, current2], null, new Reference(candidate, current2));
              } else {
                continue;
              }

              worklist.push(element);
            }
          } else if (isNode(candidate)) {
            worklist.push(new Element(candidate, key, null, new Reference(node, key)));
          }
        }
      }

      return outer.root;
    };

    function traverse(root, visitor) {
      var controller = new Controller();
      return controller.traverse(root, visitor);
    }

    function replace(root, visitor) {
      var controller = new Controller();
      return controller.replace(root, visitor);
    }

    function extendCommentRange(comment, tokens) {
      var target;
      target = upperBound(tokens, function search(token) {
        return token.range[0] > comment.range[0];
      });
      comment.extendedRange = [comment.range[0], comment.range[1]];

      if (target !== tokens.length) {
        comment.extendedRange[1] = tokens[target].range[0];
      }

      target -= 1;

      if (target >= 0) {
        comment.extendedRange[0] = tokens[target].range[1];
      }

      return comment;
    }

    function attachComments(tree, providedComments, tokens) {
      // At first, we should calculate extended comment ranges.
      var comments = [],
          comment,
          len,
          i,
          cursor;

      if (!tree.range) {
        throw new Error('attachComments needs range information');
      } // tokens array is empty, we attach comments to tree as 'leadingComments'


      if (!tokens.length) {
        if (providedComments.length) {
          for (i = 0, len = providedComments.length; i < len; i += 1) {
            comment = deepCopy(providedComments[i]);
            comment.extendedRange = [0, tree.range[0]];
            comments.push(comment);
          }

          tree.leadingComments = comments;
        }

        return tree;
      }

      for (i = 0, len = providedComments.length; i < len; i += 1) {
        comments.push(extendCommentRange(deepCopy(providedComments[i]), tokens));
      } // This is based on John Freeman's implementation.


      cursor = 0;
      traverse(tree, {
        enter: function (node) {
          var comment;

          while (cursor < comments.length) {
            comment = comments[cursor];

            if (comment.extendedRange[1] > node.range[0]) {
              break;
            }

            if (comment.extendedRange[1] === node.range[0]) {
              if (!node.leadingComments) {
                node.leadingComments = [];
              }

              node.leadingComments.push(comment);
              comments.splice(cursor, 1);
            } else {
              cursor += 1;
            }
          } // already out of owned node


          if (cursor === comments.length) {
            return VisitorOption.Break;
          }

          if (comments[cursor].extendedRange[0] > node.range[1]) {
            return VisitorOption.Skip;
          }
        }
      });
      cursor = 0;
      traverse(tree, {
        leave: function (node) {
          var comment;

          while (cursor < comments.length) {
            comment = comments[cursor];

            if (node.range[1] < comment.extendedRange[0]) {
              break;
            }

            if (node.range[1] === comment.extendedRange[0]) {
              if (!node.trailingComments) {
                node.trailingComments = [];
              }

              node.trailingComments.push(comment);
              comments.splice(cursor, 1);
            } else {
              cursor += 1;
            }
          } // already out of owned node


          if (cursor === comments.length) {
            return VisitorOption.Break;
          }

          if (comments[cursor].extendedRange[0] > node.range[1]) {
            return VisitorOption.Skip;
          }
        }
      });
      return tree;
    }

    exports.Syntax = Syntax;
    exports.traverse = traverse;
    exports.replace = replace;
    exports.attachComments = attachComments;
    exports.VisitorKeys = VisitorKeys;
    exports.VisitorOption = VisitorOption;
    exports.Controller = Controller;

    exports.cloneEnvironment = function () {
      return clone({});
    };

    return exports;
  })(exports);
  /* vim: set sw=4 ts=4 et tw=80 : */

});

var parser = createCommonjsModule(function (module) {
  /*
   * Generated by PEG.js 0.10.0.
   *
   * http://pegjs.org/
   */
  (function (root, factory) {
    if ( module.exports) {
      module.exports = factory();
    }
  })(commonjsGlobal, function () {

    function peg$subclass(child, parent) {
      function ctor() {
        this.constructor = child;
      }

      ctor.prototype = parent.prototype;
      child.prototype = new ctor();
    }

    function peg$SyntaxError(message, expected, found, location) {
      this.message = message;
      this.expected = expected;
      this.found = found;
      this.location = location;
      this.name = "SyntaxError";

      if (typeof Error.captureStackTrace === "function") {
        Error.captureStackTrace(this, peg$SyntaxError);
      }
    }

    peg$subclass(peg$SyntaxError, Error);

    peg$SyntaxError.buildMessage = function (expected, found) {
      var DESCRIBE_EXPECTATION_FNS = {
        literal: function literal(expectation) {
          return "\"" + literalEscape(expectation.text) + "\"";
        },
        "class": function _class(expectation) {
          var escapedParts = "",
              i;

          for (i = 0; i < expectation.parts.length; i++) {
            escapedParts += expectation.parts[i] instanceof Array ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) : classEscape(expectation.parts[i]);
          }

          return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
        },
        any: function any(expectation) {
          return "any character";
        },
        end: function end(expectation) {
          return "end of input";
        },
        other: function other(expectation) {
          return expectation.description;
        }
      };

      function hex(ch) {
        return ch.charCodeAt(0).toString(16).toUpperCase();
      }

      function literalEscape(s) {
        return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\0/g, '\\0').replace(/\t/g, '\\t').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/[\x00-\x0F]/g, function (ch) {
          return '\\x0' + hex(ch);
        }).replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) {
          return '\\x' + hex(ch);
        });
      }

      function classEscape(s) {
        return s.replace(/\\/g, '\\\\').replace(/\]/g, '\\]').replace(/\^/g, '\\^').replace(/-/g, '\\-').replace(/\0/g, '\\0').replace(/\t/g, '\\t').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/[\x00-\x0F]/g, function (ch) {
          return '\\x0' + hex(ch);
        }).replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) {
          return '\\x' + hex(ch);
        });
      }

      function describeExpectation(expectation) {
        return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
      }

      function describeExpected(expected) {
        var descriptions = new Array(expected.length),
            i,
            j;

        for (i = 0; i < expected.length; i++) {
          descriptions[i] = describeExpectation(expected[i]);
        }

        descriptions.sort();

        if (descriptions.length > 0) {
          for (i = 1, j = 1; i < descriptions.length; i++) {
            if (descriptions[i - 1] !== descriptions[i]) {
              descriptions[j] = descriptions[i];
              j++;
            }
          }

          descriptions.length = j;
        }

        switch (descriptions.length) {
          case 1:
            return descriptions[0];

          case 2:
            return descriptions[0] + " or " + descriptions[1];

          default:
            return descriptions.slice(0, -1).join(", ") + ", or " + descriptions[descriptions.length - 1];
        }
      }

      function describeFound(found) {
        return found ? "\"" + literalEscape(found) + "\"" : "end of input";
      }

      return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
    };

    function peg$parse(input, options) {
      options = options !== void 0 ? options : {};

      var peg$FAILED = {},
          peg$startRuleFunctions = {
        start: peg$parsestart
      },
          peg$startRuleFunction = peg$parsestart,
          peg$c0 = function peg$c0(ss) {
        return ss.length === 1 ? ss[0] : {
          type: 'matches',
          selectors: ss
        };
      },
          peg$c1 = function peg$c1() {
        return void 0;
      },
          peg$c2 = " ",
          peg$c3 = peg$literalExpectation(" ", false),
          peg$c4 = /^[^ [\],():#!=><~+.]/,
          peg$c5 = peg$classExpectation([" ", "[", "]", ",", "(", ")", ":", "#", "!", "=", ">", "<", "~", "+", "."], true, false),
          peg$c6 = function peg$c6(i) {
        return i.join('');
      },
          peg$c7 = ">",
          peg$c8 = peg$literalExpectation(">", false),
          peg$c9 = function peg$c9() {
        return 'child';
      },
          peg$c10 = "~",
          peg$c11 = peg$literalExpectation("~", false),
          peg$c12 = function peg$c12() {
        return 'sibling';
      },
          peg$c13 = "+",
          peg$c14 = peg$literalExpectation("+", false),
          peg$c15 = function peg$c15() {
        return 'adjacent';
      },
          peg$c16 = function peg$c16() {
        return 'descendant';
      },
          peg$c17 = ",",
          peg$c18 = peg$literalExpectation(",", false),
          peg$c19 = function peg$c19(s, ss) {
        return [s].concat(ss.map(function (s) {
          return s[3];
        }));
      },
          peg$c20 = function peg$c20(a, ops) {
        return ops.reduce(function (memo, rhs) {
          return {
            type: rhs[0],
            left: memo,
            right: rhs[1]
          };
        }, a);
      },
          peg$c21 = "!",
          peg$c22 = peg$literalExpectation("!", false),
          peg$c23 = function peg$c23(subject, as) {
        var b = as.length === 1 ? as[0] : {
          type: 'compound',
          selectors: as
        };
        if (subject) b.subject = true;
        return b;
      },
          peg$c24 = "*",
          peg$c25 = peg$literalExpectation("*", false),
          peg$c26 = function peg$c26(a) {
        return {
          type: 'wildcard',
          value: a
        };
      },
          peg$c27 = "#",
          peg$c28 = peg$literalExpectation("#", false),
          peg$c29 = function peg$c29(i) {
        return {
          type: 'identifier',
          value: i
        };
      },
          peg$c30 = "[",
          peg$c31 = peg$literalExpectation("[", false),
          peg$c32 = "]",
          peg$c33 = peg$literalExpectation("]", false),
          peg$c34 = function peg$c34(v) {
        return v;
      },
          peg$c35 = /^[><!]/,
          peg$c36 = peg$classExpectation([">", "<", "!"], false, false),
          peg$c37 = "=",
          peg$c38 = peg$literalExpectation("=", false),
          peg$c39 = function peg$c39(a) {
        return (a || '') + '=';
      },
          peg$c40 = /^[><]/,
          peg$c41 = peg$classExpectation([">", "<"], false, false),
          peg$c42 = ".",
          peg$c43 = peg$literalExpectation(".", false),
          peg$c44 = function peg$c44(a, as) {
        return [].concat.apply([a], as).join('');
      },
          peg$c45 = function peg$c45(name, op, value) {
        return {
          type: 'attribute',
          name: name,
          operator: op,
          value: value
        };
      },
          peg$c46 = function peg$c46(name) {
        return {
          type: 'attribute',
          name: name
        };
      },
          peg$c47 = "\"",
          peg$c48 = peg$literalExpectation("\"", false),
          peg$c49 = /^[^\\"]/,
          peg$c50 = peg$classExpectation(["\\", "\""], true, false),
          peg$c51 = "\\",
          peg$c52 = peg$literalExpectation("\\", false),
          peg$c53 = peg$anyExpectation(),
          peg$c54 = function peg$c54(a, b) {
        return a + b;
      },
          peg$c55 = function peg$c55(d) {
        return {
          type: 'literal',
          value: strUnescape(d.join(''))
        };
      },
          peg$c56 = "'",
          peg$c57 = peg$literalExpectation("'", false),
          peg$c58 = /^[^\\']/,
          peg$c59 = peg$classExpectation(["\\", "'"], true, false),
          peg$c60 = /^[0-9]/,
          peg$c61 = peg$classExpectation([["0", "9"]], false, false),
          peg$c62 = function peg$c62(a, b) {
        // Can use `a.flat().join('')` once supported
        var leadingDecimals = a ? [].concat.apply([], a).join('') : '';
        return {
          type: 'literal',
          value: parseFloat(leadingDecimals + b.join(''))
        };
      },
          peg$c63 = function peg$c63(i) {
        return {
          type: 'literal',
          value: i
        };
      },
          peg$c64 = "type(",
          peg$c65 = peg$literalExpectation("type(", false),
          peg$c66 = /^[^ )]/,
          peg$c67 = peg$classExpectation([" ", ")"], true, false),
          peg$c68 = ")",
          peg$c69 = peg$literalExpectation(")", false),
          peg$c70 = function peg$c70(t) {
        return {
          type: 'type',
          value: t.join('')
        };
      },
          peg$c71 = /^[imsu]/,
          peg$c72 = peg$classExpectation(["i", "m", "s", "u"], false, false),
          peg$c73 = "/",
          peg$c74 = peg$literalExpectation("/", false),
          peg$c75 = /^[^\/]/,
          peg$c76 = peg$classExpectation(["/"], true, false),
          peg$c77 = function peg$c77(d, flgs) {
        return {
          type: 'regexp',
          value: new RegExp(d.join(''), flgs ? flgs.join('') : '')
        };
      },
          peg$c78 = function peg$c78(i, is) {
        return {
          type: 'field',
          name: is.reduce(function (memo, p) {
            return memo + p[0] + p[1];
          }, i)
        };
      },
          peg$c79 = ":not(",
          peg$c80 = peg$literalExpectation(":not(", false),
          peg$c81 = function peg$c81(ss) {
        return {
          type: 'not',
          selectors: ss
        };
      },
          peg$c82 = ":matches(",
          peg$c83 = peg$literalExpectation(":matches(", false),
          peg$c84 = function peg$c84(ss) {
        return {
          type: 'matches',
          selectors: ss
        };
      },
          peg$c85 = ":has(",
          peg$c86 = peg$literalExpectation(":has(", false),
          peg$c87 = function peg$c87(ss) {
        return {
          type: 'has',
          selectors: ss
        };
      },
          peg$c88 = ":first-child",
          peg$c89 = peg$literalExpectation(":first-child", false),
          peg$c90 = function peg$c90() {
        return nth(1);
      },
          peg$c91 = ":last-child",
          peg$c92 = peg$literalExpectation(":last-child", false),
          peg$c93 = function peg$c93() {
        return nthLast(1);
      },
          peg$c94 = ":nth-child(",
          peg$c95 = peg$literalExpectation(":nth-child(", false),
          peg$c96 = function peg$c96(n) {
        return nth(parseInt(n.join(''), 10));
      },
          peg$c97 = ":nth-last-child(",
          peg$c98 = peg$literalExpectation(":nth-last-child(", false),
          peg$c99 = function peg$c99(n) {
        return nthLast(parseInt(n.join(''), 10));
      },
          peg$c100 = ":",
          peg$c101 = peg$literalExpectation(":", false),
          peg$c102 = "statement",
          peg$c103 = peg$literalExpectation("statement", true),
          peg$c104 = "expression",
          peg$c105 = peg$literalExpectation("expression", true),
          peg$c106 = "declaration",
          peg$c107 = peg$literalExpectation("declaration", true),
          peg$c108 = "function",
          peg$c109 = peg$literalExpectation("function", true),
          peg$c110 = "pattern",
          peg$c111 = peg$literalExpectation("pattern", true),
          peg$c112 = function peg$c112(c) {
        return {
          type: 'class',
          name: c
        };
      },
          peg$currPos = 0,
          peg$posDetailsCache = [{
        line: 1,
        column: 1
      }],
          peg$maxFailPos = 0,
          peg$maxFailExpected = [],
          peg$resultsCache = {},
          peg$result;

      if ("startRule" in options) {
        if (!(options.startRule in peg$startRuleFunctions)) {
          throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
        }

        peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
      }

      function peg$literalExpectation(text, ignoreCase) {
        return {
          type: "literal",
          text: text,
          ignoreCase: ignoreCase
        };
      }

      function peg$classExpectation(parts, inverted, ignoreCase) {
        return {
          type: "class",
          parts: parts,
          inverted: inverted,
          ignoreCase: ignoreCase
        };
      }

      function peg$anyExpectation() {
        return {
          type: "any"
        };
      }

      function peg$endExpectation() {
        return {
          type: "end"
        };
      }

      function peg$computePosDetails(pos) {
        var details = peg$posDetailsCache[pos],
            p;

        if (details) {
          return details;
        } else {
          p = pos - 1;

          while (!peg$posDetailsCache[p]) {
            p--;
          }

          details = peg$posDetailsCache[p];
          details = {
            line: details.line,
            column: details.column
          };

          while (p < pos) {
            if (input.charCodeAt(p) === 10) {
              details.line++;
              details.column = 1;
            } else {
              details.column++;
            }

            p++;
          }

          peg$posDetailsCache[pos] = details;
          return details;
        }
      }

      function peg$computeLocation(startPos, endPos) {
        var startPosDetails = peg$computePosDetails(startPos),
            endPosDetails = peg$computePosDetails(endPos);
        return {
          start: {
            offset: startPos,
            line: startPosDetails.line,
            column: startPosDetails.column
          },
          end: {
            offset: endPos,
            line: endPosDetails.line,
            column: endPosDetails.column
          }
        };
      }

      function peg$fail(expected) {
        if (peg$currPos < peg$maxFailPos) {
          return;
        }

        if (peg$currPos > peg$maxFailPos) {
          peg$maxFailPos = peg$currPos;
          peg$maxFailExpected = [];
        }

        peg$maxFailExpected.push(expected);
      }

      function peg$buildStructuredError(expected, found, location) {
        return new peg$SyntaxError(peg$SyntaxError.buildMessage(expected, found), expected, found, location);
      }

      function peg$parsestart() {
        var s0, s1, s2, s3;
        var key = peg$currPos * 30 + 0,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;
        s1 = peg$parse_();

        if (s1 !== peg$FAILED) {
          s2 = peg$parseselectors();

          if (s2 !== peg$FAILED) {
            s3 = peg$parse_();

            if (s3 !== peg$FAILED) {
              s1 = peg$c0(s2);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        if (s0 === peg$FAILED) {
          s0 = peg$currPos;
          s1 = peg$parse_();

          if (s1 !== peg$FAILED) {
            s1 = peg$c1();
          }

          s0 = s1;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parse_() {
        var s0, s1;
        var key = peg$currPos * 30 + 1,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = [];

        if (input.charCodeAt(peg$currPos) === 32) {
          s1 = peg$c2;
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c3);
          }
        }

        while (s1 !== peg$FAILED) {
          s0.push(s1);

          if (input.charCodeAt(peg$currPos) === 32) {
            s1 = peg$c2;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;

            {
              peg$fail(peg$c3);
            }
          }
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseidentifierName() {
        var s0, s1, s2;
        var key = peg$currPos * 30 + 2,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;
        s1 = [];

        if (peg$c4.test(input.charAt(peg$currPos))) {
          s2 = input.charAt(peg$currPos);
          peg$currPos++;
        } else {
          s2 = peg$FAILED;

          {
            peg$fail(peg$c5);
          }
        }

        if (s2 !== peg$FAILED) {
          while (s2 !== peg$FAILED) {
            s1.push(s2);

            if (peg$c4.test(input.charAt(peg$currPos))) {
              s2 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s2 = peg$FAILED;

              {
                peg$fail(peg$c5);
              }
            }
          }
        } else {
          s1 = peg$FAILED;
        }

        if (s1 !== peg$FAILED) {
          s1 = peg$c6(s1);
        }

        s0 = s1;
        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsebinaryOp() {
        var s0, s1, s2, s3;
        var key = peg$currPos * 30 + 3,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;
        s1 = peg$parse_();

        if (s1 !== peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 62) {
            s2 = peg$c7;
            peg$currPos++;
          } else {
            s2 = peg$FAILED;

            {
              peg$fail(peg$c8);
            }
          }

          if (s2 !== peg$FAILED) {
            s3 = peg$parse_();

            if (s3 !== peg$FAILED) {
              s1 = peg$c9();
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        if (s0 === peg$FAILED) {
          s0 = peg$currPos;
          s1 = peg$parse_();

          if (s1 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 126) {
              s2 = peg$c10;
              peg$currPos++;
            } else {
              s2 = peg$FAILED;

              {
                peg$fail(peg$c11);
              }
            }

            if (s2 !== peg$FAILED) {
              s3 = peg$parse_();

              if (s3 !== peg$FAILED) {
                s1 = peg$c12();
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }

          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            s1 = peg$parse_();

            if (s1 !== peg$FAILED) {
              if (input.charCodeAt(peg$currPos) === 43) {
                s2 = peg$c13;
                peg$currPos++;
              } else {
                s2 = peg$FAILED;

                {
                  peg$fail(peg$c14);
                }
              }

              if (s2 !== peg$FAILED) {
                s3 = peg$parse_();

                if (s3 !== peg$FAILED) {
                  s1 = peg$c15();
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }

            if (s0 === peg$FAILED) {
              s0 = peg$currPos;

              if (input.charCodeAt(peg$currPos) === 32) {
                s1 = peg$c2;
                peg$currPos++;
              } else {
                s1 = peg$FAILED;

                {
                  peg$fail(peg$c3);
                }
              }

              if (s1 !== peg$FAILED) {
                s2 = peg$parse_();

                if (s2 !== peg$FAILED) {
                  s1 = peg$c16();
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            }
          }
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseselectors() {
        var s0, s1, s2, s3, s4, s5, s6, s7;
        var key = peg$currPos * 30 + 4,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;
        s1 = peg$parseselector();

        if (s1 !== peg$FAILED) {
          s2 = [];
          s3 = peg$currPos;
          s4 = peg$parse_();

          if (s4 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 44) {
              s5 = peg$c17;
              peg$currPos++;
            } else {
              s5 = peg$FAILED;

              {
                peg$fail(peg$c18);
              }
            }

            if (s5 !== peg$FAILED) {
              s6 = peg$parse_();

              if (s6 !== peg$FAILED) {
                s7 = peg$parseselector();

                if (s7 !== peg$FAILED) {
                  s4 = [s4, s5, s6, s7];
                  s3 = s4;
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }

          while (s3 !== peg$FAILED) {
            s2.push(s3);
            s3 = peg$currPos;
            s4 = peg$parse_();

            if (s4 !== peg$FAILED) {
              if (input.charCodeAt(peg$currPos) === 44) {
                s5 = peg$c17;
                peg$currPos++;
              } else {
                s5 = peg$FAILED;

                {
                  peg$fail(peg$c18);
                }
              }

              if (s5 !== peg$FAILED) {
                s6 = peg$parse_();

                if (s6 !== peg$FAILED) {
                  s7 = peg$parseselector();

                  if (s7 !== peg$FAILED) {
                    s4 = [s4, s5, s6, s7];
                    s3 = s4;
                  } else {
                    peg$currPos = s3;
                    s3 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          }

          if (s2 !== peg$FAILED) {
            s1 = peg$c19(s1, s2);
            s0 = s1;
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseselector() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 5,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;
        s1 = peg$parsesequence();

        if (s1 !== peg$FAILED) {
          s2 = [];
          s3 = peg$currPos;
          s4 = peg$parsebinaryOp();

          if (s4 !== peg$FAILED) {
            s5 = peg$parsesequence();

            if (s5 !== peg$FAILED) {
              s4 = [s4, s5];
              s3 = s4;
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }

          while (s3 !== peg$FAILED) {
            s2.push(s3);
            s3 = peg$currPos;
            s4 = peg$parsebinaryOp();

            if (s4 !== peg$FAILED) {
              s5 = peg$parsesequence();

              if (s5 !== peg$FAILED) {
                s4 = [s4, s5];
                s3 = s4;
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          }

          if (s2 !== peg$FAILED) {
            s1 = peg$c20(s1, s2);
            s0 = s1;
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsesequence() {
        var s0, s1, s2, s3;
        var key = peg$currPos * 30 + 6,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.charCodeAt(peg$currPos) === 33) {
          s1 = peg$c21;
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c22);
          }
        }

        if (s1 === peg$FAILED) {
          s1 = null;
        }

        if (s1 !== peg$FAILED) {
          s2 = [];
          s3 = peg$parseatom();

          if (s3 !== peg$FAILED) {
            while (s3 !== peg$FAILED) {
              s2.push(s3);
              s3 = peg$parseatom();
            }
          } else {
            s2 = peg$FAILED;
          }

          if (s2 !== peg$FAILED) {
            s1 = peg$c23(s1, s2);
            s0 = s1;
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseatom() {
        var s0;
        var key = peg$currPos * 30 + 7,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$parsewildcard();

        if (s0 === peg$FAILED) {
          s0 = peg$parseidentifier();

          if (s0 === peg$FAILED) {
            s0 = peg$parseattr();

            if (s0 === peg$FAILED) {
              s0 = peg$parsefield();

              if (s0 === peg$FAILED) {
                s0 = peg$parsenegation();

                if (s0 === peg$FAILED) {
                  s0 = peg$parsematches();

                  if (s0 === peg$FAILED) {
                    s0 = peg$parsehas();

                    if (s0 === peg$FAILED) {
                      s0 = peg$parsefirstChild();

                      if (s0 === peg$FAILED) {
                        s0 = peg$parselastChild();

                        if (s0 === peg$FAILED) {
                          s0 = peg$parsenthChild();

                          if (s0 === peg$FAILED) {
                            s0 = peg$parsenthLastChild();

                            if (s0 === peg$FAILED) {
                              s0 = peg$parseclass();
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsewildcard() {
        var s0, s1;
        var key = peg$currPos * 30 + 8,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.charCodeAt(peg$currPos) === 42) {
          s1 = peg$c24;
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c25);
          }
        }

        if (s1 !== peg$FAILED) {
          s1 = peg$c26(s1);
        }

        s0 = s1;
        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseidentifier() {
        var s0, s1, s2;
        var key = peg$currPos * 30 + 9,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.charCodeAt(peg$currPos) === 35) {
          s1 = peg$c27;
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c28);
          }
        }

        if (s1 === peg$FAILED) {
          s1 = null;
        }

        if (s1 !== peg$FAILED) {
          s2 = peg$parseidentifierName();

          if (s2 !== peg$FAILED) {
            s1 = peg$c29(s2);
            s0 = s1;
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseattr() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 10,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.charCodeAt(peg$currPos) === 91) {
          s1 = peg$c30;
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c31);
          }
        }

        if (s1 !== peg$FAILED) {
          s2 = peg$parse_();

          if (s2 !== peg$FAILED) {
            s3 = peg$parseattrValue();

            if (s3 !== peg$FAILED) {
              s4 = peg$parse_();

              if (s4 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 93) {
                  s5 = peg$c32;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  {
                    peg$fail(peg$c33);
                  }
                }

                if (s5 !== peg$FAILED) {
                  s1 = peg$c34(s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseattrOps() {
        var s0, s1, s2;
        var key = peg$currPos * 30 + 11,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (peg$c35.test(input.charAt(peg$currPos))) {
          s1 = input.charAt(peg$currPos);
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c36);
          }
        }

        if (s1 === peg$FAILED) {
          s1 = null;
        }

        if (s1 !== peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 61) {
            s2 = peg$c37;
            peg$currPos++;
          } else {
            s2 = peg$FAILED;

            {
              peg$fail(peg$c38);
            }
          }

          if (s2 !== peg$FAILED) {
            s1 = peg$c39(s1);
            s0 = s1;
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        if (s0 === peg$FAILED) {
          if (peg$c40.test(input.charAt(peg$currPos))) {
            s0 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s0 = peg$FAILED;

            {
              peg$fail(peg$c41);
            }
          }
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseattrEqOps() {
        var s0, s1, s2;
        var key = peg$currPos * 30 + 12,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.charCodeAt(peg$currPos) === 33) {
          s1 = peg$c21;
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c22);
          }
        }

        if (s1 === peg$FAILED) {
          s1 = null;
        }

        if (s1 !== peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 61) {
            s2 = peg$c37;
            peg$currPos++;
          } else {
            s2 = peg$FAILED;

            {
              peg$fail(peg$c38);
            }
          }

          if (s2 !== peg$FAILED) {
            s1 = peg$c39(s1);
            s0 = s1;
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseattrName() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 13,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;
        s1 = peg$parseidentifierName();

        if (s1 !== peg$FAILED) {
          s2 = [];
          s3 = peg$currPos;

          if (input.charCodeAt(peg$currPos) === 46) {
            s4 = peg$c42;
            peg$currPos++;
          } else {
            s4 = peg$FAILED;

            {
              peg$fail(peg$c43);
            }
          }

          if (s4 !== peg$FAILED) {
            s5 = peg$parseidentifierName();

            if (s5 !== peg$FAILED) {
              s4 = [s4, s5];
              s3 = s4;
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          } else {
            peg$currPos = s3;
            s3 = peg$FAILED;
          }

          while (s3 !== peg$FAILED) {
            s2.push(s3);
            s3 = peg$currPos;

            if (input.charCodeAt(peg$currPos) === 46) {
              s4 = peg$c42;
              peg$currPos++;
            } else {
              s4 = peg$FAILED;

              {
                peg$fail(peg$c43);
              }
            }

            if (s4 !== peg$FAILED) {
              s5 = peg$parseidentifierName();

              if (s5 !== peg$FAILED) {
                s4 = [s4, s5];
                s3 = s4;
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          }

          if (s2 !== peg$FAILED) {
            s1 = peg$c44(s1, s2);
            s0 = s1;
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseattrValue() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 14,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;
        s1 = peg$parseattrName();

        if (s1 !== peg$FAILED) {
          s2 = peg$parse_();

          if (s2 !== peg$FAILED) {
            s3 = peg$parseattrEqOps();

            if (s3 !== peg$FAILED) {
              s4 = peg$parse_();

              if (s4 !== peg$FAILED) {
                s5 = peg$parsetype();

                if (s5 === peg$FAILED) {
                  s5 = peg$parseregex();
                }

                if (s5 !== peg$FAILED) {
                  s1 = peg$c45(s1, s3, s5);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        if (s0 === peg$FAILED) {
          s0 = peg$currPos;
          s1 = peg$parseattrName();

          if (s1 !== peg$FAILED) {
            s2 = peg$parse_();

            if (s2 !== peg$FAILED) {
              s3 = peg$parseattrOps();

              if (s3 !== peg$FAILED) {
                s4 = peg$parse_();

                if (s4 !== peg$FAILED) {
                  s5 = peg$parsestring();

                  if (s5 === peg$FAILED) {
                    s5 = peg$parsenumber();

                    if (s5 === peg$FAILED) {
                      s5 = peg$parsepath();
                    }
                  }

                  if (s5 !== peg$FAILED) {
                    s1 = peg$c45(s1, s3, s5);
                    s0 = s1;
                  } else {
                    peg$currPos = s0;
                    s0 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }

          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            s1 = peg$parseattrName();

            if (s1 !== peg$FAILED) {
              s1 = peg$c46(s1);
            }

            s0 = s1;
          }
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsestring() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 15,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.charCodeAt(peg$currPos) === 34) {
          s1 = peg$c47;
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c48);
          }
        }

        if (s1 !== peg$FAILED) {
          s2 = [];

          if (peg$c49.test(input.charAt(peg$currPos))) {
            s3 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s3 = peg$FAILED;

            {
              peg$fail(peg$c50);
            }
          }

          if (s3 === peg$FAILED) {
            s3 = peg$currPos;

            if (input.charCodeAt(peg$currPos) === 92) {
              s4 = peg$c51;
              peg$currPos++;
            } else {
              s4 = peg$FAILED;

              {
                peg$fail(peg$c52);
              }
            }

            if (s4 !== peg$FAILED) {
              if (input.length > peg$currPos) {
                s5 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s5 = peg$FAILED;

                {
                  peg$fail(peg$c53);
                }
              }

              if (s5 !== peg$FAILED) {
                s4 = peg$c54(s4, s5);
                s3 = s4;
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$FAILED;
            }
          }

          while (s3 !== peg$FAILED) {
            s2.push(s3);

            if (peg$c49.test(input.charAt(peg$currPos))) {
              s3 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s3 = peg$FAILED;

              {
                peg$fail(peg$c50);
              }
            }

            if (s3 === peg$FAILED) {
              s3 = peg$currPos;

              if (input.charCodeAt(peg$currPos) === 92) {
                s4 = peg$c51;
                peg$currPos++;
              } else {
                s4 = peg$FAILED;

                {
                  peg$fail(peg$c52);
                }
              }

              if (s4 !== peg$FAILED) {
                if (input.length > peg$currPos) {
                  s5 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  {
                    peg$fail(peg$c53);
                  }
                }

                if (s5 !== peg$FAILED) {
                  s4 = peg$c54(s4, s5);
                  s3 = s4;
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            }
          }

          if (s2 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 34) {
              s3 = peg$c47;
              peg$currPos++;
            } else {
              s3 = peg$FAILED;

              {
                peg$fail(peg$c48);
              }
            }

            if (s3 !== peg$FAILED) {
              s1 = peg$c55(s2);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        if (s0 === peg$FAILED) {
          s0 = peg$currPos;

          if (input.charCodeAt(peg$currPos) === 39) {
            s1 = peg$c56;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;

            {
              peg$fail(peg$c57);
            }
          }

          if (s1 !== peg$FAILED) {
            s2 = [];

            if (peg$c58.test(input.charAt(peg$currPos))) {
              s3 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s3 = peg$FAILED;

              {
                peg$fail(peg$c59);
              }
            }

            if (s3 === peg$FAILED) {
              s3 = peg$currPos;

              if (input.charCodeAt(peg$currPos) === 92) {
                s4 = peg$c51;
                peg$currPos++;
              } else {
                s4 = peg$FAILED;

                {
                  peg$fail(peg$c52);
                }
              }

              if (s4 !== peg$FAILED) {
                if (input.length > peg$currPos) {
                  s5 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  {
                    peg$fail(peg$c53);
                  }
                }

                if (s5 !== peg$FAILED) {
                  s4 = peg$c54(s4, s5);
                  s3 = s4;
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$FAILED;
              }
            }

            while (s3 !== peg$FAILED) {
              s2.push(s3);

              if (peg$c58.test(input.charAt(peg$currPos))) {
                s3 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s3 = peg$FAILED;

                {
                  peg$fail(peg$c59);
                }
              }

              if (s3 === peg$FAILED) {
                s3 = peg$currPos;

                if (input.charCodeAt(peg$currPos) === 92) {
                  s4 = peg$c51;
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;

                  {
                    peg$fail(peg$c52);
                  }
                }

                if (s4 !== peg$FAILED) {
                  if (input.length > peg$currPos) {
                    s5 = input.charAt(peg$currPos);
                    peg$currPos++;
                  } else {
                    s5 = peg$FAILED;

                    {
                      peg$fail(peg$c53);
                    }
                  }

                  if (s5 !== peg$FAILED) {
                    s4 = peg$c54(s4, s5);
                    s3 = s4;
                  } else {
                    peg$currPos = s3;
                    s3 = peg$FAILED;
                  }
                } else {
                  peg$currPos = s3;
                  s3 = peg$FAILED;
                }
              }
            }

            if (s2 !== peg$FAILED) {
              if (input.charCodeAt(peg$currPos) === 39) {
                s3 = peg$c56;
                peg$currPos++;
              } else {
                s3 = peg$FAILED;

                {
                  peg$fail(peg$c57);
                }
              }

              if (s3 !== peg$FAILED) {
                s1 = peg$c55(s2);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsenumber() {
        var s0, s1, s2, s3;
        var key = peg$currPos * 30 + 16,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;
        s1 = peg$currPos;
        s2 = [];

        if (peg$c60.test(input.charAt(peg$currPos))) {
          s3 = input.charAt(peg$currPos);
          peg$currPos++;
        } else {
          s3 = peg$FAILED;

          {
            peg$fail(peg$c61);
          }
        }

        while (s3 !== peg$FAILED) {
          s2.push(s3);

          if (peg$c60.test(input.charAt(peg$currPos))) {
            s3 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s3 = peg$FAILED;

            {
              peg$fail(peg$c61);
            }
          }
        }

        if (s2 !== peg$FAILED) {
          if (input.charCodeAt(peg$currPos) === 46) {
            s3 = peg$c42;
            peg$currPos++;
          } else {
            s3 = peg$FAILED;

            {
              peg$fail(peg$c43);
            }
          }

          if (s3 !== peg$FAILED) {
            s2 = [s2, s3];
            s1 = s2;
          } else {
            peg$currPos = s1;
            s1 = peg$FAILED;
          }
        } else {
          peg$currPos = s1;
          s1 = peg$FAILED;
        }

        if (s1 === peg$FAILED) {
          s1 = null;
        }

        if (s1 !== peg$FAILED) {
          s2 = [];

          if (peg$c60.test(input.charAt(peg$currPos))) {
            s3 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s3 = peg$FAILED;

            {
              peg$fail(peg$c61);
            }
          }

          if (s3 !== peg$FAILED) {
            while (s3 !== peg$FAILED) {
              s2.push(s3);

              if (peg$c60.test(input.charAt(peg$currPos))) {
                s3 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s3 = peg$FAILED;

                {
                  peg$fail(peg$c61);
                }
              }
            }
          } else {
            s2 = peg$FAILED;
          }

          if (s2 !== peg$FAILED) {
            s1 = peg$c62(s1, s2);
            s0 = s1;
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsepath() {
        var s0, s1;
        var key = peg$currPos * 30 + 17,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;
        s1 = peg$parseidentifierName();

        if (s1 !== peg$FAILED) {
          s1 = peg$c63(s1);
        }

        s0 = s1;
        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsetype() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 18,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.substr(peg$currPos, 5) === peg$c64) {
          s1 = peg$c64;
          peg$currPos += 5;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c65);
          }
        }

        if (s1 !== peg$FAILED) {
          s2 = peg$parse_();

          if (s2 !== peg$FAILED) {
            s3 = [];

            if (peg$c66.test(input.charAt(peg$currPos))) {
              s4 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s4 = peg$FAILED;

              {
                peg$fail(peg$c67);
              }
            }

            if (s4 !== peg$FAILED) {
              while (s4 !== peg$FAILED) {
                s3.push(s4);

                if (peg$c66.test(input.charAt(peg$currPos))) {
                  s4 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;

                  {
                    peg$fail(peg$c67);
                  }
                }
              }
            } else {
              s3 = peg$FAILED;
            }

            if (s3 !== peg$FAILED) {
              s4 = peg$parse_();

              if (s4 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 41) {
                  s5 = peg$c68;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  {
                    peg$fail(peg$c69);
                  }
                }

                if (s5 !== peg$FAILED) {
                  s1 = peg$c70(s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseflags() {
        var s0, s1;
        var key = peg$currPos * 30 + 19,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = [];

        if (peg$c71.test(input.charAt(peg$currPos))) {
          s1 = input.charAt(peg$currPos);
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c72);
          }
        }

        if (s1 !== peg$FAILED) {
          while (s1 !== peg$FAILED) {
            s0.push(s1);

            if (peg$c71.test(input.charAt(peg$currPos))) {
              s1 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s1 = peg$FAILED;

              {
                peg$fail(peg$c72);
              }
            }
          }
        } else {
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseregex() {
        var s0, s1, s2, s3, s4;
        var key = peg$currPos * 30 + 20,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.charCodeAt(peg$currPos) === 47) {
          s1 = peg$c73;
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c74);
          }
        }

        if (s1 !== peg$FAILED) {
          s2 = [];

          if (peg$c75.test(input.charAt(peg$currPos))) {
            s3 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s3 = peg$FAILED;

            {
              peg$fail(peg$c76);
            }
          }

          if (s3 !== peg$FAILED) {
            while (s3 !== peg$FAILED) {
              s2.push(s3);

              if (peg$c75.test(input.charAt(peg$currPos))) {
                s3 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s3 = peg$FAILED;

                {
                  peg$fail(peg$c76);
                }
              }
            }
          } else {
            s2 = peg$FAILED;
          }

          if (s2 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 47) {
              s3 = peg$c73;
              peg$currPos++;
            } else {
              s3 = peg$FAILED;

              {
                peg$fail(peg$c74);
              }
            }

            if (s3 !== peg$FAILED) {
              s4 = peg$parseflags();

              if (s4 === peg$FAILED) {
                s4 = null;
              }

              if (s4 !== peg$FAILED) {
                s1 = peg$c77(s2, s4);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsefield() {
        var s0, s1, s2, s3, s4, s5, s6;
        var key = peg$currPos * 30 + 21,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.charCodeAt(peg$currPos) === 46) {
          s1 = peg$c42;
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c43);
          }
        }

        if (s1 !== peg$FAILED) {
          s2 = peg$parseidentifierName();

          if (s2 !== peg$FAILED) {
            s3 = [];
            s4 = peg$currPos;

            if (input.charCodeAt(peg$currPos) === 46) {
              s5 = peg$c42;
              peg$currPos++;
            } else {
              s5 = peg$FAILED;

              {
                peg$fail(peg$c43);
              }
            }

            if (s5 !== peg$FAILED) {
              s6 = peg$parseidentifierName();

              if (s6 !== peg$FAILED) {
                s5 = [s5, s6];
                s4 = s5;
              } else {
                peg$currPos = s4;
                s4 = peg$FAILED;
              }
            } else {
              peg$currPos = s4;
              s4 = peg$FAILED;
            }

            while (s4 !== peg$FAILED) {
              s3.push(s4);
              s4 = peg$currPos;

              if (input.charCodeAt(peg$currPos) === 46) {
                s5 = peg$c42;
                peg$currPos++;
              } else {
                s5 = peg$FAILED;

                {
                  peg$fail(peg$c43);
                }
              }

              if (s5 !== peg$FAILED) {
                s6 = peg$parseidentifierName();

                if (s6 !== peg$FAILED) {
                  s5 = [s5, s6];
                  s4 = s5;
                } else {
                  peg$currPos = s4;
                  s4 = peg$FAILED;
                }
              } else {
                peg$currPos = s4;
                s4 = peg$FAILED;
              }
            }

            if (s3 !== peg$FAILED) {
              s1 = peg$c78(s2, s3);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsenegation() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 22,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.substr(peg$currPos, 5) === peg$c79) {
          s1 = peg$c79;
          peg$currPos += 5;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c80);
          }
        }

        if (s1 !== peg$FAILED) {
          s2 = peg$parse_();

          if (s2 !== peg$FAILED) {
            s3 = peg$parseselectors();

            if (s3 !== peg$FAILED) {
              s4 = peg$parse_();

              if (s4 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 41) {
                  s5 = peg$c68;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  {
                    peg$fail(peg$c69);
                  }
                }

                if (s5 !== peg$FAILED) {
                  s1 = peg$c81(s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsematches() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 23,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.substr(peg$currPos, 9) === peg$c82) {
          s1 = peg$c82;
          peg$currPos += 9;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c83);
          }
        }

        if (s1 !== peg$FAILED) {
          s2 = peg$parse_();

          if (s2 !== peg$FAILED) {
            s3 = peg$parseselectors();

            if (s3 !== peg$FAILED) {
              s4 = peg$parse_();

              if (s4 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 41) {
                  s5 = peg$c68;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  {
                    peg$fail(peg$c69);
                  }
                }

                if (s5 !== peg$FAILED) {
                  s1 = peg$c84(s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsehas() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 24,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.substr(peg$currPos, 5) === peg$c85) {
          s1 = peg$c85;
          peg$currPos += 5;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c86);
          }
        }

        if (s1 !== peg$FAILED) {
          s2 = peg$parse_();

          if (s2 !== peg$FAILED) {
            s3 = peg$parseselectors();

            if (s3 !== peg$FAILED) {
              s4 = peg$parse_();

              if (s4 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 41) {
                  s5 = peg$c68;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  {
                    peg$fail(peg$c69);
                  }
                }

                if (s5 !== peg$FAILED) {
                  s1 = peg$c87(s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsefirstChild() {
        var s0, s1;
        var key = peg$currPos * 30 + 25,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.substr(peg$currPos, 12) === peg$c88) {
          s1 = peg$c88;
          peg$currPos += 12;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c89);
          }
        }

        if (s1 !== peg$FAILED) {
          s1 = peg$c90();
        }

        s0 = s1;
        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parselastChild() {
        var s0, s1;
        var key = peg$currPos * 30 + 26,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.substr(peg$currPos, 11) === peg$c91) {
          s1 = peg$c91;
          peg$currPos += 11;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c92);
          }
        }

        if (s1 !== peg$FAILED) {
          s1 = peg$c93();
        }

        s0 = s1;
        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsenthChild() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 27,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.substr(peg$currPos, 11) === peg$c94) {
          s1 = peg$c94;
          peg$currPos += 11;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c95);
          }
        }

        if (s1 !== peg$FAILED) {
          s2 = peg$parse_();

          if (s2 !== peg$FAILED) {
            s3 = [];

            if (peg$c60.test(input.charAt(peg$currPos))) {
              s4 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s4 = peg$FAILED;

              {
                peg$fail(peg$c61);
              }
            }

            if (s4 !== peg$FAILED) {
              while (s4 !== peg$FAILED) {
                s3.push(s4);

                if (peg$c60.test(input.charAt(peg$currPos))) {
                  s4 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;

                  {
                    peg$fail(peg$c61);
                  }
                }
              }
            } else {
              s3 = peg$FAILED;
            }

            if (s3 !== peg$FAILED) {
              s4 = peg$parse_();

              if (s4 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 41) {
                  s5 = peg$c68;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  {
                    peg$fail(peg$c69);
                  }
                }

                if (s5 !== peg$FAILED) {
                  s1 = peg$c96(s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parsenthLastChild() {
        var s0, s1, s2, s3, s4, s5;
        var key = peg$currPos * 30 + 28,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.substr(peg$currPos, 16) === peg$c97) {
          s1 = peg$c97;
          peg$currPos += 16;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c98);
          }
        }

        if (s1 !== peg$FAILED) {
          s2 = peg$parse_();

          if (s2 !== peg$FAILED) {
            s3 = [];

            if (peg$c60.test(input.charAt(peg$currPos))) {
              s4 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s4 = peg$FAILED;

              {
                peg$fail(peg$c61);
              }
            }

            if (s4 !== peg$FAILED) {
              while (s4 !== peg$FAILED) {
                s3.push(s4);

                if (peg$c60.test(input.charAt(peg$currPos))) {
                  s4 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;

                  {
                    peg$fail(peg$c61);
                  }
                }
              }
            } else {
              s3 = peg$FAILED;
            }

            if (s3 !== peg$FAILED) {
              s4 = peg$parse_();

              if (s4 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 41) {
                  s5 = peg$c68;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;

                  {
                    peg$fail(peg$c69);
                  }
                }

                if (s5 !== peg$FAILED) {
                  s1 = peg$c99(s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$FAILED;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$FAILED;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$FAILED;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function peg$parseclass() {
        var s0, s1, s2;
        var key = peg$currPos * 30 + 29,
            cached = peg$resultsCache[key];

        if (cached) {
          peg$currPos = cached.nextPos;
          return cached.result;
        }

        s0 = peg$currPos;

        if (input.charCodeAt(peg$currPos) === 58) {
          s1 = peg$c100;
          peg$currPos++;
        } else {
          s1 = peg$FAILED;

          {
            peg$fail(peg$c101);
          }
        }

        if (s1 !== peg$FAILED) {
          if (input.substr(peg$currPos, 9).toLowerCase() === peg$c102) {
            s2 = input.substr(peg$currPos, 9);
            peg$currPos += 9;
          } else {
            s2 = peg$FAILED;

            {
              peg$fail(peg$c103);
            }
          }

          if (s2 === peg$FAILED) {
            if (input.substr(peg$currPos, 10).toLowerCase() === peg$c104) {
              s2 = input.substr(peg$currPos, 10);
              peg$currPos += 10;
            } else {
              s2 = peg$FAILED;

              {
                peg$fail(peg$c105);
              }
            }

            if (s2 === peg$FAILED) {
              if (input.substr(peg$currPos, 11).toLowerCase() === peg$c106) {
                s2 = input.substr(peg$currPos, 11);
                peg$currPos += 11;
              } else {
                s2 = peg$FAILED;

                {
                  peg$fail(peg$c107);
                }
              }

              if (s2 === peg$FAILED) {
                if (input.substr(peg$currPos, 8).toLowerCase() === peg$c108) {
                  s2 = input.substr(peg$currPos, 8);
                  peg$currPos += 8;
                } else {
                  s2 = peg$FAILED;

                  {
                    peg$fail(peg$c109);
                  }
                }

                if (s2 === peg$FAILED) {
                  if (input.substr(peg$currPos, 7).toLowerCase() === peg$c110) {
                    s2 = input.substr(peg$currPos, 7);
                    peg$currPos += 7;
                  } else {
                    s2 = peg$FAILED;

                    {
                      peg$fail(peg$c111);
                    }
                  }
                }
              }
            }
          }

          if (s2 !== peg$FAILED) {
            s1 = peg$c112(s2);
            s0 = s1;
          } else {
            peg$currPos = s0;
            s0 = peg$FAILED;
          }
        } else {
          peg$currPos = s0;
          s0 = peg$FAILED;
        }

        peg$resultsCache[key] = {
          nextPos: peg$currPos,
          result: s0
        };
        return s0;
      }

      function nth(n) {
        return {
          type: 'nth-child',
          index: {
            type: 'literal',
            value: n
          }
        };
      }

      function nthLast(n) {
        return {
          type: 'nth-last-child',
          index: {
            type: 'literal',
            value: n
          }
        };
      }

      function strUnescape(s) {
        return s.replace(/\\(.)/g, function (match, ch) {
          switch (ch) {
            case 'b':
              return '\b';

            case 'f':
              return '\f';

            case 'n':
              return '\n';

            case 'r':
              return '\r';

            case 't':
              return '\t';

            case 'v':
              return '\v';

            default:
              return ch;
          }
        });
      }

      peg$result = peg$startRuleFunction();

      if (peg$result !== peg$FAILED && peg$currPos === input.length) {
        return peg$result;
      } else {
        if (peg$result !== peg$FAILED && peg$currPos < input.length) {
          peg$fail(peg$endExpectation());
        }

        throw peg$buildStructuredError(peg$maxFailExpected, peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, peg$maxFailPos < input.length ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) : peg$computeLocation(peg$maxFailPos, peg$maxFailPos));
      }
    }

    return {
      SyntaxError: peg$SyntaxError,
      parse: peg$parse
    };
  });
});

function _objectEntries(obj) {
  var entries = [];
  var keys = Object.keys(obj);

  for (var k = 0; k < keys.length; k++) entries.push([keys[k], obj[keys[k]]]);

  return entries;
}
/**
* @typedef {"LEFT_SIDE"|"RIGHT_SIDE"} Side
*/

var LEFT_SIDE = 'LEFT_SIDE';
var RIGHT_SIDE = 'RIGHT_SIDE';
/**
 * @external AST
 * @see https://esprima.readthedocs.io/en/latest/syntax-tree-format.html
 */

/**
 * One of the rules of `grammar.pegjs`
 * @typedef {PlainObject} SelectorAST
 * @see grammar.pegjs
*/

/**
 * The `sequence` production of `grammar.pegjs`
 * @typedef {PlainObject} SelectorSequenceAST
*/

/**
 * Get the value of a property which may be multiple levels down
 * in the object.
 * @param {?PlainObject} obj
 * @param {string} key
 * @returns {undefined|boolean|string|number|external:AST}
 */

function getPath(obj, key) {
  var keys = key.split('.');

  var _iterator = _createForOfIteratorHelper(keys),
      _step;

  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var _key = _step.value;

      if (obj == null) {
        return obj;
      }

      obj = obj[_key];
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }

  return obj;
}
/**
 * Determine whether `node` can be reached by following `path`,
 * starting at `ancestor`.
 * @param {?external:AST} node
 * @param {?external:AST} ancestor
 * @param {string[]} path
 * @returns {boolean}
 */


function inPath(node, ancestor, path) {
  if (path.length === 0) {
    return node === ancestor;
  }

  if (ancestor == null) {
    return false;
  }

  var field = ancestor[path[0]];
  var remainingPath = path.slice(1);

  if (Array.isArray(field)) {
    var _iterator2 = _createForOfIteratorHelper(field),
        _step2;

    try {
      for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
        var component = _step2.value;

        if (inPath(node, component, remainingPath)) {
          return true;
        }
      }
    } catch (err) {
      _iterator2.e(err);
    } finally {
      _iterator2.f();
    }

    return false;
  } else {
    return inPath(node, field, remainingPath);
  }
}
/**
 * @callback TraverseOptionFallback
 * @param {external:AST} node The given node.
 * @returns {string[]} An array of visitor keys for the given node.
 */

/**
 * @typedef {object} ESQueryOptions
 * @property { { [nodeType: string]: string[] } } [visitorKeys] By passing `visitorKeys` mapping, we can extend the properties of the nodes that traverse the node.
 * @property {TraverseOptionFallback} [fallback] By passing `fallback` option, we can control the properties of traversing nodes when encountering unknown nodes.
 */

/**
 * Given a `node` and its ancestors, determine if `node` is matched
 * by `selector`.
 * @param {?external:AST} node
 * @param {?SelectorAST} selector
 * @param {external:AST[]} [ancestry=[]]
 * @param {ESQueryOptions} [options]
 * @throws {Error} Unknowns (operator, class name, selector type, or
 * selector value type)
 * @returns {boolean}
 */


function matches(node, selector, ancestry, options) {
  if (!selector) {
    return true;
  }

  if (!node) {
    return false;
  }

  if (!ancestry) {
    ancestry = [];
  }

  switch (selector.type) {
    case 'wildcard':
      return true;

    case 'identifier':
      return selector.value.toLowerCase() === node.type.toLowerCase();

    case 'field':
      {
        var path = selector.name.split('.');
        var ancestor = ancestry[path.length - 1];
        return inPath(node, ancestor, path);
      }

    case 'matches':
      var _iterator3 = _createForOfIteratorHelper(selector.selectors),
          _step3;

      try {
        for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
          var sel = _step3.value;

          if (matches(node, sel, ancestry, options)) {
            return true;
          }
        }
      } catch (err) {
        _iterator3.e(err);
      } finally {
        _iterator3.f();
      }

      return false;

    case 'compound':
      var _iterator4 = _createForOfIteratorHelper(selector.selectors),
          _step4;

      try {
        for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
          var _sel = _step4.value;

          if (!matches(node, _sel, ancestry, options)) {
            return false;
          }
        }
      } catch (err) {
        _iterator4.e(err);
      } finally {
        _iterator4.f();
      }

      return true;

    case 'not':
      var _iterator5 = _createForOfIteratorHelper(selector.selectors),
          _step5;

      try {
        for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
          var _sel2 = _step5.value;

          if (matches(node, _sel2, ancestry, options)) {
            return false;
          }
        }
      } catch (err) {
        _iterator5.e(err);
      } finally {
        _iterator5.f();
      }

      return true;

    case 'has':
      {
        var _ret = function () {
          var collector = [];

          var _iterator6 = _createForOfIteratorHelper(selector.selectors),
              _step6;

          try {
            var _loop = function _loop() {
              var sel = _step6.value;
              var a = [];
              estraverse.traverse(node, {
                enter: function enter(node, parent) {
                  if (parent != null) {
                    a.unshift(parent);
                  }

                  if (matches(node, sel, a, options)) {
                    collector.push(node);
                  }
                },
                leave: function leave() {
                  a.shift();
                },
                keys: options && options.visitorKeys,
                fallback: options && options.fallback || 'iteration'
              });
            };

            for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
              _loop();
            }
          } catch (err) {
            _iterator6.e(err);
          } finally {
            _iterator6.f();
          }

          return {
            v: collector.length !== 0
          };
        }();

        if (_typeof(_ret) === "object") return _ret.v;
      }

    case 'child':
      if (matches(node, selector.right, ancestry, options)) {
        return matches(ancestry[0], selector.left, ancestry.slice(1), options);
      }

      return false;

    case 'descendant':
      if (matches(node, selector.right, ancestry, options)) {
        for (var i = 0, l = ancestry.length; i < l; ++i) {
          if (matches(ancestry[i], selector.left, ancestry.slice(i + 1), options)) {
            return true;
          }
        }
      }

      return false;

    case 'attribute':
      {
        var p = getPath(node, selector.name);

        switch (selector.operator) {
          case void 0:
            return p != null;

          case '=':
            switch (selector.value.type) {
              case 'regexp':
                return typeof p === 'string' && selector.value.value.test(p);

              case 'literal':
                return "".concat(selector.value.value) === "".concat(p);

              case 'type':
                return selector.value.value === _typeof(p);
            }

            throw new Error("Unknown selector value type: ".concat(selector.value.type));

          case '!=':
            switch (selector.value.type) {
              case 'regexp':
                return !selector.value.value.test(p);

              case 'literal':
                return "".concat(selector.value.value) !== "".concat(p);

              case 'type':
                return selector.value.value !== _typeof(p);
            }

            throw new Error("Unknown selector value type: ".concat(selector.value.type));

          case '<=':
            return p <= selector.value.value;

          case '<':
            return p < selector.value.value;

          case '>':
            return p > selector.value.value;

          case '>=':
            return p >= selector.value.value;
        }

        throw new Error("Unknown operator: ".concat(selector.operator));
      }

    case 'sibling':
      return matches(node, selector.right, ancestry, options) && sibling(node, selector.left, ancestry, LEFT_SIDE, options) || selector.left.subject && matches(node, selector.left, ancestry, options) && sibling(node, selector.right, ancestry, RIGHT_SIDE, options);

    case 'adjacent':
      return matches(node, selector.right, ancestry, options) && adjacent(node, selector.left, ancestry, LEFT_SIDE, options) || selector.right.subject && matches(node, selector.left, ancestry, options) && adjacent(node, selector.right, ancestry, RIGHT_SIDE, options);

    case 'nth-child':
      return matches(node, selector.right, ancestry, options) && nthChild(node, ancestry, function () {
        return selector.index.value - 1;
      }, options);

    case 'nth-last-child':
      return matches(node, selector.right, ancestry, options) && nthChild(node, ancestry, function (length) {
        return length - selector.index.value;
      }, options);

    case 'class':
      switch (selector.name.toLowerCase()) {
        case 'statement':
          if (node.type.slice(-9) === 'Statement') return true;
        // fallthrough: interface Declaration <: Statement { }

        case 'declaration':
          return node.type.slice(-11) === 'Declaration';

        case 'pattern':
          if (node.type.slice(-7) === 'Pattern') return true;
        // fallthrough: interface Expression <: Node, Pattern { }

        case 'expression':
          return node.type.slice(-10) === 'Expression' || node.type.slice(-7) === 'Literal' || node.type === 'Identifier' && (ancestry.length === 0 || ancestry[0].type !== 'MetaProperty') || node.type === 'MetaProperty';

        case 'function':
          return node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';
      }

      throw new Error("Unknown class name: ".concat(selector.name));
  }

  throw new Error("Unknown selector type: ".concat(selector.type));
}
/**
 * Get visitor keys of a given node.
 * @param {external:AST} node The AST node to get keys.
 * @param {ESQueryOptions|undefined} options
 * @returns {string[]} Visitor keys of the node.
 */


function getVisitorKeys(node, options) {
  var nodeType = node.type;

  if (options && options.visitorKeys && options.visitorKeys[nodeType]) {
    return options.visitorKeys[nodeType];
  }

  if (estraverse.VisitorKeys[nodeType]) {
    return estraverse.VisitorKeys[nodeType];
  }

  if (options && typeof options.fallback === 'function') {
    return options.fallback(node);
  } // 'iteration' fallback


  return Object.keys(node).filter(function (key) {
    return key !== 'type';
  });
}
/**
 * Check whether the given value is an ASTNode or not.
 * @param {any} node The value to check.
 * @returns {boolean} `true` if the value is an ASTNode.
 */


function isNode(node) {
  return node !== null && _typeof(node) === 'object' && typeof node.type === 'string';
}
/**
 * Determines if the given node has a sibling that matches the
 * given selector.
 * @param {external:AST} node
 * @param {SelectorSequenceAST} selector
 * @param {external:AST[]} ancestry
 * @param {Side} side
 * @param {ESQueryOptions|undefined} options
 * @returns {boolean}
 */


function sibling(node, selector, ancestry, side, options) {
  var _ancestry = _slicedToArray(ancestry, 1),
      parent = _ancestry[0];

  if (!parent) {
    return false;
  }

  var keys = getVisitorKeys(parent, options);

  var _iterator7 = _createForOfIteratorHelper(keys),
      _step7;

  try {
    for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
      var key = _step7.value;
      var listProp = parent[key];

      if (Array.isArray(listProp)) {
        var startIndex = listProp.indexOf(node);

        if (startIndex < 0) {
          continue;
        }

        var lowerBound = void 0,
            upperBound = void 0;

        if (side === LEFT_SIDE) {
          lowerBound = 0;
          upperBound = startIndex;
        } else {
          lowerBound = startIndex + 1;
          upperBound = listProp.length;
        }

        for (var k = lowerBound; k < upperBound; ++k) {
          if (isNode(listProp[k]) && matches(listProp[k], selector, ancestry, options)) {
            return true;
          }
        }
      }
    }
  } catch (err) {
    _iterator7.e(err);
  } finally {
    _iterator7.f();
  }

  return false;
}
/**
 * Determines if the given node has an adjacent sibling that matches
 * the given selector.
 * @param {external:AST} node
 * @param {SelectorSequenceAST} selector
 * @param {external:AST[]} ancestry
 * @param {Side} side
 * @param {ESQueryOptions|undefined} options
 * @returns {boolean}
 */


function adjacent(node, selector, ancestry, side, options) {
  var _ancestry2 = _slicedToArray(ancestry, 1),
      parent = _ancestry2[0];

  if (!parent) {
    return false;
  }

  var keys = getVisitorKeys(parent, options);

  var _iterator8 = _createForOfIteratorHelper(keys),
      _step8;

  try {
    for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
      var key = _step8.value;
      var listProp = parent[key];

      if (Array.isArray(listProp)) {
        var idx = listProp.indexOf(node);

        if (idx < 0) {
          continue;
        }

        if (side === LEFT_SIDE && idx > 0 && isNode(listProp[idx - 1]) && matches(listProp[idx - 1], selector, ancestry, options)) {
          return true;
        }

        if (side === RIGHT_SIDE && idx < listProp.length - 1 && isNode(listProp[idx + 1]) && matches(listProp[idx + 1], selector, ancestry, options)) {
          return true;
        }
      }
    }
  } catch (err) {
    _iterator8.e(err);
  } finally {
    _iterator8.f();
  }

  return false;
}
/**
* @callback IndexFunction
* @param {Integer} len Containing list's length
* @returns {Integer}
*/

/**
 * Determines if the given node is the nth child, determined by
 * `idxFn`, which is given the containing list's length.
 * @param {external:AST} node
 * @param {external:AST[]} ancestry
 * @param {IndexFunction} idxFn
 * @param {ESQueryOptions|undefined} options
 * @returns {boolean}
 */


function nthChild(node, ancestry, idxFn, options) {
  var _ancestry3 = _slicedToArray(ancestry, 1),
      parent = _ancestry3[0];

  if (!parent) {
    return false;
  }

  var keys = getVisitorKeys(parent, options);

  var _iterator9 = _createForOfIteratorHelper(keys),
      _step9;

  try {
    for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
      var key = _step9.value;
      var listProp = parent[key];

      if (Array.isArray(listProp)) {
        var idx = listProp.indexOf(node);

        if (idx >= 0 && idx === idxFn(listProp.length)) {
          return true;
        }
      }
    }
  } catch (err) {
    _iterator9.e(err);
  } finally {
    _iterator9.f();
  }

  return false;
}
/**
 * For each selector node marked as a subject, find the portion of the
 * selector that the subject must match.
 * @param {SelectorAST} selector
 * @param {SelectorAST} [ancestor] Defaults to `selector`
 * @returns {SelectorAST[]}
 */


function subjects(selector, ancestor) {
  if (selector == null || _typeof(selector) != 'object') {
    return [];
  }

  if (ancestor == null) {
    ancestor = selector;
  }

  var results = selector.subject ? [ancestor] : [];

  for (var _i = 0, _Object$entries = _objectEntries(selector); _i < _Object$entries.length; _i++) {
    var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
        p = _Object$entries$_i[0],
        sel = _Object$entries$_i[1];

    results.push.apply(results, _toConsumableArray(subjects(sel, p === 'left' ? sel : ancestor)));
  }

  return results;
}
/**
* @callback TraverseVisitor
* @param {?external:AST} node
* @param {?external:AST} parent
* @param {external:AST[]} ancestry
*/

/**
 * From a JS AST and a selector AST, collect all JS AST nodes that
 * match the selector.
 * @param {external:AST} ast
 * @param {?SelectorAST} selector
 * @param {TraverseVisitor} visitor
 * @param {ESQueryOptions} [options]
 * @returns {external:AST[]}
 */


function traverse(ast, selector, visitor, options) {
  if (!selector) {
    return;
  }

  var ancestry = [];
  var altSubjects = subjects(selector);
  estraverse.traverse(ast, {
    enter: function enter(node, parent) {
      if (parent != null) {
        ancestry.unshift(parent);
      }

      if (matches(node, selector, ancestry, options)) {
        if (altSubjects.length) {
          for (var i = 0, l = altSubjects.length; i < l; ++i) {
            if (matches(node, altSubjects[i], ancestry, options)) {
              visitor(node, parent, ancestry);
            }

            for (var k = 0, m = ancestry.length; k < m; ++k) {
              var succeedingAncestry = ancestry.slice(k + 1);

              if (matches(ancestry[k], altSubjects[i], succeedingAncestry, options)) {
                visitor(ancestry[k], parent, succeedingAncestry);
              }
            }
          }
        } else {
          visitor(node, parent, ancestry);
        }
      }
    },
    leave: function leave() {
      ancestry.shift();
    },
    keys: options && options.visitorKeys,
    fallback: options && options.fallback || 'iteration'
  });
}
/**
 * From a JS AST and a selector AST, collect all JS AST nodes that
 * match the selector.
 * @param {external:AST} ast
 * @param {?SelectorAST} selector
 * @param {ESQueryOptions} [options]
 * @returns {external:AST[]}
 */


function match(ast, selector, options) {
  var results = [];
  traverse(ast, selector, function (node) {
    results.push(node);
  }, options);
  return results;
}
/**
 * Parse a selector string and return its AST.
 * @param {string} selector
 * @returns {SelectorAST}
 */


function parse(selector) {
  return parser.parse(selector);
}
/**
 * Query the code AST using the selector string.
 * @param {external:AST} ast
 * @param {string} selector
 * @param {ESQueryOptions} [options]
 * @returns {external:AST[]}
 */


function query(ast, selector, options) {
  return match(ast, parse(selector), options);
}

query.parse = parse;
query.match = match;
query.traverse = traverse;
query.matches = matches;
query.query = query;

export default query;

Youez - 2016 - github.com/yon3zu
LinuXploit