From f2dd4878514556daa737e3194ee9e4ab49fa997d Mon Sep 17 00:00:00 2001 From: adipandas <10423256+adipandas@users.noreply.github.com> Date: Thu, 11 May 2023 11:14:53 -0400 Subject: [PATCH 1/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index caf306f..88f454f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # Multi-object trackers in Python Easy to use implementation of various multi-object tracking algorithms. -[![DOI](https://zenodo.org/badge/148338463.svg)](https://zenodo.org/badge/latestdoi/148338463) +[![DOI](https://zenodo.org/badge/148338463.svg)](https://zenodo.org/badge/latestdoi/148338463) [![Upload motrackers to PyPI](https://github.com/adipandas/multi-object-tracker/actions/workflows/python-publish.yml/badge.svg)](https://github.com/adipandas/multi-object-tracker/actions/workflows/python-publish.yml) `YOLOv3 + CentroidTracker` | `TF-MobileNetSSD + CentroidTracker` From 5d5474f4d95cb5aa4be21a4d14f4333a392579d5 Mon Sep 17 00:00:00 2001 From: adipandas Date: Thu, 1 Jun 2023 11:25:07 -0400 Subject: [PATCH 2/8] Update docs --- README.md | 23 +- docs/.doctrees/environment.pickle | Bin 26907 -> 155888 bytes docs/.doctrees/includeme/apidocuments.doctree | Bin 31616 -> 455355 bytes docs/.doctrees/includeme/readmefile.doctree | Bin 27052 -> 30567 bytes docs/.doctrees/index.doctree | Bin 4354 -> 4377 bytes .../motrackers/centroid_kf_tracker.html | 4 +- docs/_modules/motrackers/detectors/caffe.html | 2 +- .../motrackers/detectors/detector.html | 8 +- docs/_modules/motrackers/detectors/tf.html | 2 +- docs/_modules/motrackers/detectors/yolo.html | 2 +- docs/_modules/motrackers/iou_tracker.html | 2 +- docs/_modules/motrackers/kalman_tracker.html | 14 +- docs/_modules/motrackers/sort_tracker.html | 4 +- docs/_modules/motrackers/track.html | 22 +- docs/_modules/motrackers/tracker.html | 14 +- docs/_modules/motrackers/utils/misc.html | 18 +- docs/_static/basic.css | 47 +- docs/_static/doctools.js | 130 +- docs/_static/jquery-3.5.1.js | 10872 ---------------- docs/_static/searchtools.js | 74 +- docs/_static/underscore-1.3.1.js | 999 -- docs/genindex.html | 277 + docs/includeme/apidocuments.html | 1199 +- docs/includeme/readmefile.html | 27 +- docs/index.html | 74 +- docs/objects.inv | Bin 335 -> 945 bytes docs/search.html | 1 + docs/searchindex.js | 2 +- 28 files changed, 1697 insertions(+), 12120 deletions(-) delete mode 100644 docs/_static/jquery-3.5.1.js delete mode 100644 docs/_static/underscore-1.3.1.js diff --git a/README.md b/README.md index 88f454f..cd96f5f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ # Multi-object trackers in Python Easy to use implementation of various multi-object tracking algorithms. -[![DOI](https://zenodo.org/badge/148338463.svg)](https://zenodo.org/badge/latestdoi/148338463) [![Upload motrackers to PyPI](https://github.com/adipandas/multi-object-tracker/actions/workflows/python-publish.yml/badge.svg)](https://github.com/adipandas/multi-object-tracker/actions/workflows/python-publish.yml) +[![DOI](https://zenodo.org/badge/148338463.svg)](https://zenodo.org/badge/latestdoi/148338463) +[![Upload motrackers to PyPI](https://github.com/adipandas/multi-object-tracker/actions/workflows/python-publish.yml/badge.svg)](https://github.com/adipandas/multi-object-tracker/actions/workflows/python-publish.yml) `YOLOv3 + CentroidTracker` | `TF-MobileNetSSD + CentroidTracker` @@ -12,22 +13,20 @@ Easy to use implementation of various multi-object tracking algorithms. ![Cars with YOLO][cars-yolo-output] | ![Cows with tf-SSD][cows-tf-ssd-output] Video source: [link](https://flic.kr/p/L6qyxj) | Video source: [link](https://flic.kr/p/26WeEWy) + ## Available Multi Object Trackers -``` -CentroidTracker -IOUTracker -CentroidKF_Tracker -SORT -``` +- CentroidTracker +- IOUTracker +- CentroidKF_Tracker +- SORT + ## Available OpenCV-based object detectors: -``` -detector.TF_SSDMobileNetV2 -detector.Caffe_SSDMobileNet -detector.YOLOv3 -``` +- detector.TF_SSDMobileNetV2 +- detector.Caffe_SSDMobileNet +- detector.YOLOv3 ## Installation diff --git a/docs/.doctrees/environment.pickle b/docs/.doctrees/environment.pickle index b1a8c641db56e02d3cea478e47fcf24d4d333a8b..fefc416e5d7a5260f45f580e94deaaeaa98abaf6 100644 GIT binary patch literal 155888 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 bH=$Nwe4lSXA!%VX7q>E%EdG9hFq!`WG$`4H literal 26907 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 diff --git a/docs/.doctrees/includeme/apidocuments.doctree b/docs/.doctrees/includeme/apidocuments.doctree index 714579b911cb9a5784adf05ca2ebf01fef34deb1..9cd3e6b594a7039e45635744bdd4580ac9e08436 100644 GIT binary patch literal 455355 zcmeEv37lL-nK&VL0)zk#H$2YiKr*>FBoYvU#282r0wRbrJu{tjzsz)x-90%#6!GBj zskn@~>*BgDE8?}R?#kl5qAQAv2d>xZs<7y~t_SMk_4oLHU)`@>RlTa$-IHX0`ujka$wH)B8iU$Uq*QLWW?4U|Vm>y6P$Ybu#H+8CJ}uhiR9cTO#N z+0>0wrDT4yytCDqY>rf>lKlW;q*@yrZC2`2*FoVy2;Z)awFX!Nb4MEEsruE~$)aXu zYXxeIR0aXOwPvb1_qwU-{AAXa$}U8d1$gBY!CjqQos-O&C_~-$RP}(#;c~K|+-^5( z!;@{G7O9(A8*Kq4$=s2#a;pU&;rHx%d7S>5H##{X{}?WhYzI;Z%=}&BV{2LyW$e|w ziDso$Y3`^@O(t{Ok+DX- z(po+~Io7T%YYfMgk@m876VO$f%dyMLX}#sO`pDSiXa#Fd)Of?Kfo7{cmCPEe)hkmQ z_n#aF*34}|6SYQNhyhuFY%4+G>~^g^R#A$QxmzeQ%Gt&8Z^_8j(4CdlQ>!zp{hO*w zHUTfIhXVtvM}jDhhW{T6|34o7f5LTBlhsqI%K>~T1+SK>OE%5|vi3`6*XpB{T?%GO zl(nT~E=aCfBf=;F_iFWRKzMQrBR47$sYSJVG~QtRY7MX-OQw>evR?;8Pv>lEPnD6> z^ChXYXF%vI(B_d0oh2wa2ulWAHIQ<9vYF!I8rF7cyu530tkG((J#%Tqs2OZbwkIar zgIgQT@p5}@KTtL}QZ0{-RqER+{YwbrvH3-$`EtG9XqPnsCabPJ_oOzc{F^`Cbh$b-myaWb3Kn3D3G1HHaZm8aS_+L+S+WJbhw1Ae7j*`~IV z){11t&Z)Al8WqGmIb5+yy?RphWE9M`0QfxGc(TpkV5HEOGv*IW>|TRr1gccu7B#jS zv_?rnY%M^M~6xTT-OFTbBtwacD>Zju2QlP6l)o{6M{225J@0{ zBY#&^PI4yQD4A4!F&G*pem)^yr`*HLQ7vBYqHrEkNXeUrNbHoo&PdrIgfj5Sz}0r8 zIaUMTr7(A8u0)aqn}P?$aAOo8W24bPVx zcz|?8?kJBaz>)SgH0Li+Qu6Ko9RPSYu<2ep zg8-8|#mkE_(f*yN_B3NP-e*f`n&1Cp=R@^F8P|pa{x6{X2;0G&xFecn{YX%b90!RV)w1?WZTL~knP){{Auq^aZ(NfRGt zfF?SO!?bqZ*2%Fk;<Y?c{%C; z@kMl?8)?+r>bzZ@FwRG(x~*BBsH$G-9qXHw%INNB3!OVgJ8SJKo$lZ$J6vv6Mx#bO z8X6kGNnE2gIy4lGHAcv^1_$AGwGs_CChMaFys?Xaqih*iu%%jS@##|pKg(mSMg)?m zG@HMpk>ZC!8Kz`pnj z=#6l7hZ;o9nYTz&0!b&~;kJ%=c$iV4ghNft<%a$!o*=tgiq|8N{nIZSEuXWIpzO5Uh4QQ$2n*AQK9?nNJa;Qmx)z5-nR6 zU0U8%8=oAH>XYNcl_okfaH+5ihwY6Wm1rx@cUuwlZP8BfUa-Q8Mqvs((yokh9|g-x z<}(IivC^n-Q^-i4i!TlKA#92&#r|JK!hR^Nx9-{PriqLNdg?%U- z#K+6E`c$(2#O|qNA&w=xCdO(bwf59)$z1rey?dfE6|aS+2soQ3#Gk_t2;Q2gjMTQ) zMy75}=EItj4b^1Cg_#XI&TOU=jv_YP0oa#p7))(KW;7Ba11E#f>Qo&f_(`N6Vwi~;0Vt<((&VWi5JH#T@4&zTM1T&_5M)?GD z&304R8U9Ywca+win?7b|hZFkjpsJn4-v(*|?Ccn5JANGM+#3HU{Fm5O`~>`}sum?U zl(8tCLEv7D7G;1t)~z6daY+s!ScKlXmqq*mdYQAQnzjgctACA5>xRBepHR`BU|*a5xisj9j+EM`ff56?~ap;Wz!e@ND{l}M(|((rI& zSEaQyB16O=oH{IJqd)A@54J`caD>2jfnOk+TP=5dX@^3#eCN6V6*S> z#y4rTH2ZI+HVr^ks<6o$BPy3l@hwc)=Z)I}L9%O_wt6!%nqu3hcLRr{hq?Y}h6|iTjup*wqX6T;o-w2{k@=zt>^-IbQ+8kPmjs|jv zEcJPD!v9Qn=H1TDn76^=cR(eVL*qS$&A#|<0;^CvUs#DwuwJq_QNE(FwB$UcZP5esVZo2i4OIE~V$dM_ney zNV2&`#>r^3+%D4@E=-49AVTBfL!mQ(doljwd*aLYF!rqX2C5HYR0GFuHgN0~!?#5F zmZ*CaY__j{5?msF{?s5Av2BZ!u#%86c**!Kg#b2@e_Q5LDR&Wc19kFI3AZt#MiciU zCUy_hN6XD-c{f=HU4XxE{iE)@!o~#IyseZ+su8wJvlK}!Cj0tEShnXwzO-! zR$m(JCjZ@88*NvYM%7AfTeZE!xQ61x31cJwGtI&af>_8_No%2!WtD_Qs@CSNk|1yb z&LA0$^p7-!S7|M#2XlQJmaUVnAQaj`)pb(ne#F(#wz^J2=aXG0Q69yq72zz@3ei{c zN4l?#B7J3;KABP3H1Y#e>d2|kzNX2!sR%hYLM7MKLuGxu9e@Lts5b++FYCeIW|pYB zcG{Mx2Dr5y*{)m$Bpo&cJ~l(${A3XcDjLK+H4>_&?)M!#eJ+kHon zTD%>h4Mc-@24utdhXKkyCBmu3dQf?&v<5J^G!8-8e%9FpG}o1{6Ek2hZ@vzr*P;y< zp+%3Chbv?7+vt*&*)sEZ%9ph5JrcxZ=9oWAx(8aF-A2Zu?mFhjwHEE(76rf@^LGe^ zcF<0|!xPYUzIUKJO8drK$NbwOePx(>;FuTAN(I$`~R(6%q@O^#XD zPMc#kz#S(Xv)K%VStWUp;7auNz5LIob96e~|7_EjvR-aTREp@1R#YkvY#%5O$gQpj zHt~kb!!^wn$voEiL@A9P3yZqzv98uy^fH?(359mh zPR!;SXgl9*D31a?)R{U5ho%3 z7Q80@?V%tQX1fia!b*9&4XNOUD=va9BRndVZX31(S`pn7igt625{3ro^51~ zHn^V$6l)kQdq6CFCoMT?h@8#1s259=6LLW%u|#5zX{hZ^oTx3( zWuO<0UsRVdh=gm%!zi#d^ zeV>h$g7p0e;RIWBmUHbE)bQ)rd7NPb2_&*WR?=jCtT)vi4BRRF`2+ZoK$B&^42yCm zInZ6xzSwH5rd>Rpbd+Ka=;DlPHG%l`a5fRTR&~R)bdjMB>Em@8p?V+DXXpV(I*gaY z=p&kA7p>wj(DH&DhMNEuLcsU)`SH8E(uH(Gh98?qM*#O?(ltwT>u(MX5zwQsS)>?+ znG0ciG&JlL&_%f92=`u;zvtE)^j_O-$pP#q#wG8Dpt42v1`Diiu}{FS>Se^qaZc?AFSOeZC>tVhaPFOIAoR831VYd$RKO{O&PenD$Hr{E8?}tjR zSpz>E#>4#g6IkUiKf7utBfktnumI$ria%PUFQ4zEFUn@A)(O4D5t#79B4mF*nC!H> zQ;(^*xbQGv8bka(q>CtMj}P+?O1laB5xyiYbAp9h_!$@45F_w<0QY6IX`QBPC%_oP*bQ(m z*|Uy7E=rR>-Vf6xj-DjKL+V13s%r+M?Ep@0qS7(IUlam z*&g7A9NkAy7OikG0nLq8*siZ$qEh}?CF+R7LU}d_!D=wtka#pPhOv9WBwVDFzN}Mt z1@Vm_*|34-D}*T^k!*|u7WH~y`H6_N?#eKjt7>*iy%J?D)nk$ITG6TWwdEv(Y4byuo&RZ=L1Vos}+-@q~oT*wd)jm z`MpPTY#`k4-Ka!qUAT>j~fFS>}PUBO%kn;>6U zr}15zgVdY(zKuk^jlK_ydhPp0H5^|4piF4CgLdNkwnE$aCP}##==)w=q^}H9$G-11 zMUda#Lq@+YfYB!3r)#Ip_Zi@>;J&Ym1}x`@Nl%&wAF1~wJ^h_Cgg!*fZD-+Mk|;89 zeSeS+u!*aV6=h+VxaweD4*c0U`jv6u?p9go$2yN;fgOqC7LR_8q;9Mt0W9=mIRWij z=*RbhWWjc%9>+>~J5s68kNdf*lMTsMG+e=ZA8gxbY&T2CGa3!UPZ*-uwk6w1B7foN zB({%W=ZQm-yCn3M3Egmlvv!gc1Mb4IEQ#dT@bDn+BrSz|D3HErg8a+2k>CrxZ31T_ zjr!K55$ra>Ce!swbjjFs(l5;=nO?kL+`rWHA#L0nhq}gF;UPA3tx3r@;%5G+b;UkV z6Z@vYFM9tiZbk=lI|Q~q{sj=^n!+O)%pstKb=e`L;$iY*WKNxzo^`po#~i~+SSiRc z$Xz(YUMVo&6d&>oZ_+xLficYabFj04nmnm81vtY4lm`P6P`6s8Mg%t~i+SLO9YHY< z{Om~z))4bRwla+|5Am&Vc15;2Mr12Rv z`y9_kryEd-<_%%F?$Y;i36Ypqgc5m!Ad>uY5eeytS*V4i5YjcX#K+_)5r=a1lakN) zG)S2@ldf(=KI7AQ3?aBNl4f@W|B%eOV)Nx&_{Aprhgbl|2@nk~{C51u_w)@DD#y2o z8ia-gaJo@6pT-4nUkGv-57Kddl~~me)*6!-NS8faQdNPhdPL0({D2ZA$ z;AmS5E|EQ=2fS5BZjDPE&62oG))|~KG|HJ76wfoMgVI1@^-t9r=DI z9a)^QUM46hj0003w5N*`?Q6Op`_FfJUvnJPA1IT3()-2-yAc>O{KgD{O!7MuoE7g6 z`JL{?ac(3b$$S}ZIXLQR{j=JZ4~r2-Ml&rOVHBBi_NwkoB<_tr2GX)-2a!}!$0Pd^ z|1H$>2rW9?GGfpKg4H=RMFu{w?coFw)z{-1|F`P2^gcm*k z0y4t4N@&PuS=~xbnbR`Wh1bR&3LkrP{#+5V=#3%%pK%Qlo3RED2{)h-d>LCW9 zhxNj50VgjH66 zc?t)ggw-?jRgT>Hj0IJUZRy;QqvHt5VqSI;(A=1po!b05$gf?h__a&TjB8iR?FgQ( z!Z2XidFQ9WM$eX+vol|j`7YQ_ME}bm(K8SCbHW}_$!zos7WLZ0EnJYsVRu_7Qs&|2 zK_%BhO7(E@d!QEq(S8R)+qoW2FfHTZbe`EfoB_`6y@Z(E9!_sFE(WH;6*(~$EGo3Dg3K$v@xO*Nxi(iY%+0+VV|lT|H9R?H<;pps?Mg+)OwX*TI0 zUvjg*gd~aEe2Lbko8Qa@-9TuxgLdMAZi2RRU65c>#s%p-vbi7w+#+2I1gDZr5h%6Z zf|pVc=Ws4Fbh}$+r~Z>3rozs6a9O0EQCLp>%LKG*r~aP`(loY;`vg|XTg9oT{#QQ+ z({OV8ndfwXiyd&fzqK(o*4T+#0ql-Qi{B&J22Wbl;R4ENrMYGSJg(Lrslv8FI_7uD znn+|BVXHaF9l46H=IUu@I#I4QTO>U{zU{LW-pz?fvxuE;sKUh(B_G8=M4ktNDQCG3 zvm}<(l3YholUef1EpSzZQaKtSCJZiyE4wvFCk|2IcmxDV#o=X2^`W!wXO9Dq}BJn`My@L5SWAl|XSs zf5)}{iY8OKqoVRuo}m(Gk3h4Xpz%>4d?jZVSf~0xPI69R=fTI>4q6Z+PW%IOe0}lv zgPi6Q)LRaL;wNRVlYNI~gYLN}on#lPKW1L$K&bya z;$?D_jc$+rhJdCvq>`!_33@!Z7;OAp)J$gMXBMJE5qiM}fP?3029mb^IdmZ9<~0k4 zRf(2Z*u`1{Il`cpk63*y-%Z`jp>b*X;~HJh?})CG(v~meqs|y4!o&;Q!0ixy$5C|+ z;ad)i?fO0{`oZEWawp(LXE^Ec?0S?1)Ag0XG$?#7P#L)PVoen?I*zkAspIgML`ih~ z6bM;NJjFxas+>w@EF;eglWmLC2=Ysh5#)byI>x88c5FDa`8I+I1Zc9~^g!?pir_2w zk1`W;^MIYnJnGRt+k(M8jV^D&1jbo^FGyke1q`edvK5oeCR-SE(9K@r!ksw^Ae5U} z`ER|6>tLIaqt4xF{H2E(FctWP2PhAFFOE!kyvZ;%N524+BE-y;cSCr`SKoN zQpm%5EO0$-q8EdRRS)U+?%pP?mgZN@@9rTgm$T%7eE9C(g#tmrTzG2e-GFbzG1VO! zuiJwV>=Dr^b5OA>1Y0sB9>!)Ukup1>E3%*X;uqy0cSSUtk;|w5ZrMxhg^W*XMnX6P z;D*e~WN@zcyVbWiIcJHHemPWvxvE!4?i<_)%pti9fegu=v4T&y;aA$o?{*^y3df~* z?SmM%VhsL%DP@9;Tt9_u1Lrx@jHoQn8sh>8rXH5kGz&iBW`Q}b`TU?Fq?zyO-hJJTJV?Nlrh)?QO;G&L+}$$^@5cec`=c9yS$GVA6kbkH{DB9i zhgxmW3=$H>T~J7eTP7wMyF1hX$TiYfme$Hs-5oZI?L?^L>p0JFBQT4NAyC8yb28qm znfN>1iwoUIg2YB~7Zlskj%i~?bcb7jc}K0~>CRv4?z~xq&kGP?&5gh;LWaOwggf0x zf<#Dh7Zl+_WpbYp*?dvRg`|8*i{%b?hstuHZUknrFa%O8Ggk7Rz^`-<-s46P zBoc}@L?rpJctglI?VXMrLM<4MtT%)tRhb(?YoT7(ZU`X}^oG#CgRElwlid&^zhQ5# zijM;G)d=wGd;r0S#;^-Si2U{OA{h*2iF=mkWi@jF;u3$_&aW$GGE3i zmN&Sw*H)=hq(miqKBn+B_&1Z&9B?|*~%!uAM%hLwbPVMy-QrJMD9O@_C* zY0T!OnKslmN(vVwr{D`RA*_nL0eLC(3DrYbC+b0JhB z=MUKsb1YJ~QF1TQ%!IykH7CE*B0E`YPn#=h^s!jZ69|2FP<4|v^uo-k(6+k6N_+xd znBmTVUz!n2%EWW(JhH`e8sN?>rXhl-Nx=rdP<3kTLkFH#u>IqCIg%hD8}!6wHUUkY zqJz=G$~JZ2mz--{IY*^dyGgF9Z6>>uBvKLXXFwbwo-46BMpLn@nnTvq*8%CO(%Ur; z`^${z`J}%f`>YXRk=kCq5kc>T5#etkaN_rxT6=E#m=QGyeRfdQh~jeqIN(l38^FDc zNH8g5L^_XbMr43H)~zFgcS#N)7=_-tmr-1m!`X17I6oD#pSlH5hhV@~g`9CjjU5oS zJ6VV0jtHKJuZ>TRM?1=6ljcm71uh4?3p%FitzCH(JGh5%!)OOsq_&r92OgILKCZRt zrjgmgM+l8}&`xaO6VSGoEeJ+sY(eLf%@z!Br*8055NQ;?HNZM_d|uXZcMh+^t>ae1 z?hUgMe54_j7?zA7m(la8h#W~l%>9mXvqmr2m*Il_E*w=@#Qf@|(ds1&ppg{NHVEII z9IfE(d_3$bHyvhX+&*H1kFiWhg1Giy1*tO|dVWDzY&1D6>bA)puqfT8-HuSU%;e@n zCGRVN=K$3K!_Ps`wwK9KMx}3k=RUS@a*^&bOxcivH1Yyh&d)4D&Z-`A|LidCgPLX> zp01@fhi8Dhx@X2M3^VB+4sfb^pS+yvlf>fPhQ}@*dd|aNYuQ(II@U|&dB2BqUAeR~ z*J|C`W$x8lE+k1@?0Ap?F&A4S24r-xSk!G7d$ZQ2Thh$MzLd~t2km55^9pF&%f(Vg zrM+CPi+yvE?lMe0aIx<$Le9NCPxtq$cFg}FfGi{LDA zdjA=u(#+|7hjicQ^sp$%>E-MT{#t9#?!}Zj3Uqh}ADm{N zy$?!v8Kyjk=dox$p$Pippi-}9@Fzjr0o*n@I9(%c4$c5~jMMOhAti1&a58$^UQXs) zIa-`?GVWH{ef#}AW{51(7f(c7@ry_Ri}d{o0d;FDi}d9OK|Ip8aO&Iv_P8-*$#uoX zVz#_$V-!MYPjZ2=*0j918DbrIaaZ68A14Zv5>+7Mt;l|xeNLDMyWSyk-}0wUnbYQf z3PmFx`=w4Bb-%cLgQ%NKPG4SIg)cmhtqi3+$%9j5%Uca|oI@+ot#BFPnEJdJu5J(^ zXq)736g)5mrCOpJ{|qX*e4H8t_*w#6l|g`(SJ5Qh7J&SRm;bIvU*6S8U-ajdWhe9! z$HU8?E<*N$!DQS0Ar}`0JxH5~UxRdY_VBWQTGV8rY8Te%2T5Kg`e6r<+i~;*InJah zQhx;P(Ey15gmt;A!h%c^qxTSZzO|n2737T0mB2{knD0W#p1fkiUenhMG@pr_K??4h4I=nyy!Y=8(s`>9Y3Nh$A^xaf|Y?zp_ljj zyBz6+d%u19J?7I7Nqa22i$KOO57-ZtEE8-j>a_=ariQ~!GxLCJ3C(uUPCVd+(6*Nc zq>KynfL9mkF2mHZ2douAzO{$E-X6wllLypw)aC&Va6Nf8S$f5uG!LFq?@4+p?C~n| zYlGB)O=5MdC=0_RRtNKP<0t2+SjLUJTV>}($9oJ8?7Rp!eLT;L7820>ovOK)SK5=! zdW#3Wi@$|}kTa1_1j&N!QGE<6O^?L1$Vmd7sB|0?sNnm(kBd!Krh z`I}l-?87y&Z<;tx@4v;(=wNP#z}CuN0D@dcVMqpZ2xwtlb_jvl!uCHjJ@;~Rk2!`v zBFlpugWQxeTwMU>oA&7r_a?1_d6?l;cMj0GS!218yZ`K?M8+ zgda+{E3tH8{9H=P){riYY;HOpX2x=wEbKYJ1ez?2{BkA>BXI~G~ezK-J;x1^UeKmwq!~C zc5Ft^+O|NYpJuaCKcxxz#~eaj8Qjc-$grcE_@(@{d&q2vP}G(|%a2+Vm>7y>0v3hg3JOIK-D`+YZppgbuQuYGR7jTuw7JxG}# zqqZ`cz0S;trNGtMKf1eTPGs}{C~aN>I`A;(7-<#|Lm&kNnZ0OtK}6(t+A@!JBMA}` z#a&QH$GC>KjJ%GpK@&*msvRKR|1;eEH%oB^RPr^m3*89JQe+5HQapoq4WxL6W@?wY zkpxMR;w~&j$27zsMGG|V>JheCjn@B~yZ>e>Rsy8B(~ZC^MTQ_H#j|bGa`6%FP0^Am1Dy$oIGrm<7oYNI_Y!H*ztqojnT=mN^7}XL@iflv{T9KCOn=tIu+j!BcnBRRuYv7oxKU_d4$gP zN&EvU{&+2hfzF{}vq%FCoBaVuijc(fhG7xxhmpKtd_D}^x*0y>I@Tv|Sd>lNa3#s? z!PcVeJ-Nk6KA=#m_@}5+eesXonx!ROB6~mmdu*u#^!||13!~_Kkox3svo@l<2$n3k zys{NusE5_9I51E@$^P&6G}8Y+1oi)Slxds@*qQl%_+`n)Ss=&kGi0d{q2z@d#wW%| z0`xMbp{EIpU^Bfuwyn{uwX5W9!fK_wqXutG50_i;`XWG8+wFpmbeNF|tv4adKuMG;$0p+5o7-p(sUVI|!6wKKKQy z0jgehZy^g7aNc50D_}r>hnA3zN+1J6;rI`*Mw(AYr!J5yxvy{ze}u3OV3wp~Go zHDQ|O08{GHzT}1=HDv?Ovxu4+O$m#-ZAvfH+VnD|YYB~Z&`wNg2-@~CCBdkSDd~K& znUVpnq?wXkaiksj*8wBaae5iig*p5VACmTx1hj7q(mrM(e@3`rv=A)nwuQV~Ytydw zCcdmhKI%#4tQE^%&((tgDbI2GRcmbi^mLW&a{&u z+mUJKEEz@8`+Pg|4^R7sv~jxg?aUT+likxFAtV@0qi|&K%e3d*i3A^vTX*IIx?`Y{ zYvQd&ZyZ5jt1^1Sl2S*8)K~!WbM8F7NMFwAq%V4A9oY%J#F2C7vLa+(5=^$;M{;rD zaiO$}_;94Fvz$BL$A!t_jN_QHo*qgXGpC390nMGB9+GoHdVshCnxhAZFM(f)8W5Ms zzH?}%2bhEB4RiN{JyZA}J8R@j1y=8m{PjF*ER;}(?GqHLD+c@cRwT18eifsZ4_;|! ztMBoz$Bp9tJ?&b7?3YU>XOBU;osj1*gLuTwLH-;o^>b?jzuK*HkUu5lxj#rAY%%hF zsAM^O!J?qWNP&brpVM%-?Tjr>K0|1>gQ|;@&;yxAplx+=f}W5jxjf3az~N=A zNOu{gj)#{Uiy*(ghrE7i7_Uvki>{-#;l%*gaTXo1CP_MO3LLynp_li2dX99$z282a zkmmzI8qPf6`v?y~aSSQRwDxk3mJ3XK2gdMfOZkmraa z(=4;w5%HgN602iHSr{gs%`dZjo~z9k|758L(=e+va6(Lfu6WWn~Ro{g3A_Ne}pkf%8iJ*zxYrH>u&BMEt4 zpy@-}xc8}qJQb}gUT#M3zs1eyU~Y%N*2>QZf?Qig=w_HhKnv@#LkLXBlLT>(IfmP? zQjlXPl91Kg>v2Jy~g-FY-UrYzy>;cMj0GS!218yZ`Q3w14gdg0vE3t$; z{A^0f){u~gY;HOd@?bg5a`SJ{Gn$Zx{BmZwA>js@EH{pXJp9fc(8_P}>0B()fN6U| zo>xN@2PO3}K`Qy>B$XtF$&i{XRPKK%d3o?N9U3Z4`0Pl}gUN6l>3L30y)(z|q^+ye z+s#I8RL|Sv2Q20Y@z0_EFz0&`|50vmIdz>R^!c%8;2nvnZvgBxPNAF-Ar zNcNtdNxO0cmHn}l@S!BehouquLvRD%uwrZ&Z1Y(2wJTQ)tl)`%WCEJwbNbD%*X6PLyvN4i8~?9B2hQ_n?eyd1_=*1a`l+N{RP2u`rN_i;K^wrm1#nqkSb|LpD37R z3e$0iI!Q*yCtx#r%+Z;Jbc|gym2o`_m1d|q$!M5t+2SPiE#2FvJ9}%%m2(DEa!s~) zlnbVmSwUcxprl2bY3Us>moH8--_sqrtVl;L>7*lvTU-JYmlVk%SwPz9#fhmX-LGnq zevMM5d*#a6;YMIi>%b7mv<|b-8S-AyKhphpg&R#!0tbrSKD)~5Up_2GWEsu3Z~}*Z zQvwHrYm|u`P6i%XL$M@rnNX|+P|qV2>p1twG?hx|fV9wftoP$D{F5bgNS6A$W94l$ z?ht{`2S8&uM_VHoRH3|Lzkl%o<{f1lVrP#-Nfo8{e0qGik2Vj-iXJ8SJ~ z)T)*zDo|-@bjFee<@#t;!M&|!V<&2EX%}2*TpH~r|J_*|ZC95@)k7&vqysGk_liagiM?Jpq+0N9$OmE@ygiu=INkhue(U!P0LD&2~_ALnAbD>yOa3 zday)%CSIlAgd0x}!VfSG!L&>ykDgyB>vzfC}MBZscnX6+^qCzi|lK&<+>arAK!__zg~__)ks zfcd%1cQFDJL0uapDCX;)2bCkUDIVsD}7 zn1LIMGu9yynF@31@4COcw@W=W`8%BkjUO_H#JuBXOf$JIEYGi?$ue`hL6ySzt& zWW`+GX9+(+7qf9gSQO;)JW^6TuC;0RTPR58;=V&@w1aly;+}xEb6uQZQpUyUJhHhs z1Kjg_r&&TTk{%)fXQcPa%Yr|hBh8EjyIW;pBH#3w2eA`DTo>wRS^8Bgb`SX>I%T>= zS#-ewKwcd$5++hQCT&r6l}0A8W$Yg(=LMpgUu0iS6drn zV~w5oSA`~LY^_-UdDz<{RoGq87P4!i3vfY;nH%Mrb=8t+XB83-Ms*Ctkcrb1gg-00;OM5(u8d&9N%~>Q(7=KPlXX^CzWm_P+3}^kt0YyW z?5b!^B5S3v(DSu?c5W9Kwj(1@J|--*IXYUz|Gq#j&Zr{B-%&nY{hbiWFJny2=LT5? zu39q0gg;at+GoVSED{0>kw4A@Wq-%D{)#43I-sKRRDz)rXn|nsc7n!75lZp*6tO2I zUu);fc>fAwD2XpdKhzgr6y(F605ZXOeH#2I9FZ-C`p<;=uod@|LO;{wY);uyYO$I; z?(3@dU4112O63ZSuR(_6kOOlIc>TuDSu5)Z|2iO@7iiMWERSG&5*z{7BeET|YKg=~ zmPeynBkp02Esqd0S$ofAUPd;Wh)=l`&II4YiJMWEO%S?vc0|{``-;z#y-xNWnhlb5 z&-=*!m+&kHL;b6X2IVLl-3q&sfTq1mRe1Ft4-^I)|8vw#X5(iTqC*jS!3KbXZ`KSX zZT)lTpvcW@77mdTEwQk_(Hh7R28~HatUi|Srf%lYxU~Fnjjj)LMAu1a%NO!dM}LVh z@d7t+J4D}cBz+^{TMmou`aUZ9!9t;Or>sS1E9vpnnq4Q21P+GH~tdnkr;; z9A{)w$KfxDlIZw%wFYtoKy@6k`slcux|u`U1!*(3YjpjhBf5yv=1o1tWRU839=L(q zAv%5t)c-faw;UF$I&McmQoF|=h5YWgxF*{Mso~>t4^;n)(^)=;wWC4=-_Fc@*LooM z21RgAkSxhi*cYGW(LUP(!99g8Z-E2`#-D#IaMCvvmT!fei&8Ub}K>BuLDji>zG@ zp?{w5q%Msnnhn^YYYo;LwN_=YHBug{tX+xq$1CO5WRtuOlPzr5#sRopnOM7$M_l*t zsnx#*O;O!Y)$6I%d$n5H_+)-+6;Zhij)yYhQ>%9g1j+4tDvUd;COllb=MnH972P)n zX5U_Yb;|xZ>uyZ3F8&BMqd&=dh^b#N9fh&LRFobVK9@t7>xot=Q(Q0pS@pjdCbX3OECI>KqZ(&d&N5c)Q!L#>&y_ySmznEi=Z3uE3FE@cOwXj za;A9gVrPvEfbkDskxzWu6vnbaGi1PVv1ZGh(1X7fl7bI~% z0hBiLJuTpEZsb7%rZg24@ZpxJQN~gaH2`uIHkPG3e3QGwW^ukaK%B32BQT4TA&}yn z39~}pEAl(ti@V%Ng2YB~7Zlskj)`kVbcb7jc}K0~>CS(^-FdSJ-xnalPr4D9MaU3% zi||WsBtasixC@GKp|ZTlh-|(ncZbYk`F?;{e(gqJ77Ifl#p0O1%sJjU zY6ppg;tdf=J}lnSGESMN@s`#jFxRr)(vrkwZfU&<>UH~;7Scj*X`KO*i}6qX>@NO> zEl2X~E?@Hi_x=JtxGw0Yi8o-e!DqtX;!2o;1V;-)kL? zA=aivBU51T?W74|T=6qdE&Jkg+}de=s&{W&DnmccV*LOaWN%4z`N7alK|Ev8WgD?l zKVOl;l)PJ)r1q)@Lu)~-VWF`Vs6@_evZ1k9q;4DK-h9e=F!Uu_d)g98Q}>7HfyWJm zK0BzoHywJ*=_Y7f-Iyjmhdda{oDIL}B$$*5jn#PsF2eX=r~$6ScRqzT>B57dI(7De z3lDwRHvDjoWDt}+PdrFKQ;`U81OdyL)S+pzH$E8pPe8hA1a?it{xYNb2hv~Ag{)Cw zk=kCqQMn%s{a39$H+{^gK1=AcgQ`Xq-wD70*J(Zv;9f>0n3ORpokupKGQj1$11gOs z2M|Uzy>&06`1>5rh8xALhSf23Q21XebnDljJk?t}~*|X;~ z@&dO7FDydN`90+RMPb|r*OhT^x|Z79n*r|Xo*B0=%%pcXz^Uqe@^Y%b@48cct!3ZJ z=~yq7C%PWab>-3}3&1}YcCFT}Gv;2c!EEg7fTtH_Hwxo*Sw=hcNwN0xY!4Zkn@2aa{ohN+&8&cT}y2) z)&O@+56xVdX3|S6;AZuHdAZqEj!eVnu1^QU*I7^(~lR+xYoZgQ}_l-^ui-Me9&Q8ee6VmP3y_n+g_J>NY2)Rxi z-dt$g%i&Qb1vSWxlvWw9#@R%X8kWkzUc15V6#j%Ug&-Q4Qg@p1ga2^s`ILLCH@quO$ z%OX?K8sa78gUwG5jCD$mWMtS`ufvw6YFU$MQGW5;@kpIB*hl}*( zpE~J_{*1HigkIu!;Q7l%$o@hw*>)ex#f1me(q7^>BVC<6@En{@G&$1hVC)Y*OPVw1 z*Dr@YbnE<@oK(|?pML|*(j)8{C&I?LDcm;m0QAw;o+$}OInO~7uSE8H9(osg!Fy+~dFkd+3`q9A2xWnAEDb6b(_GE8}^P5A^3EV$?&!rhUbhh0UGPeLWvoJr+%JOaQ0$FbJ~cmS_W zYfW88ZEH;f+@IcsR^Ely`IEksJ#Ftoza>aTS>h6%cGMHYlX^OsePW5rY%evJBD1yAzLtgI+N;xkfCjjpJlrh3Vo#cfJruns>8Y^C zyU>3bqy}sft7Ao37$&hgn3o%0nWJJEH|}ngoog-i7#!HS7H;}@o@*UJK=UtVh(=5SSfFhN=^8i+t!k*0hY zeu}K+Mc-8}ZEcnzMMrIvB?2M8hKC2oDqGw5n&M!)F+u)i57@vL`i2dp7HQPCE{z~h z@9w41_54X2P_?n?q+j0SpJu#Z+~3jkA#L3I)Vt6>(7IwDu8Dom1f9`LFnym6WX^{}tKXbi50V z6F zHBpyjYjX1T^4NH}zKq^nT}E!MF5^KV%g7a0@-p<%kRbx@(Q)`Fb<>r@`@JNMuP{4a zlAc2{fVKD?a{i~78N`#&YjB1w{Kxn3kGuvwA!?Ad(i=j?|Wgq%y@t5a$Mf1E48vng;p2j&f9@NNpsGuCcu z)ZtH(sSNUn!PDQ6R;R_R|F zop##xo#p1X)-X%U+LrxTiIq36@-RX)NjjXhgFem2Eb~DmCBwL4z z%~X```B&XNH_PwQ0Qo)PMqrj7Lm=gsNdd?0fxNb2?yV-dv~zOGr7^&7q4Uj)wo4Ms=hcm01xest}&!!(!mIabjIK zL)ejn1Ff4*SPLc(TuW^7wuY=FH%K)LS>!2b2v^T7%V69V1 zXPG&33!Wd~Ha&keu-t~k7{iloc$N>IG9?5-&Wk3v{Z=LcSi#ytyW&exv-;wVZUxhl zA(5TG{^?rF0(sA7O6UeeAc8JtZf*WMXI~2qUwoQB;R_f>LT(IzN z#WfH6y#0q)?8@P#;&Y#CUN-iGv!`nmx5$F}s_Is8LV76SPq0-75Fc@%MDu-PKj znEJg9qjb=X?^7J5vb(|6m)F_7QpDXbGM-S`qTPpR}w|v4}nS+ca23s`d;9|$LSglH_gljN`z)RXeTzX4BGax z0l~P84d{Hc*?<9VV>fk3no(Dq1xwT^_p-!AIZ_L^#OIoJKv`ZSG8?*xKR-<(UFhi* zH#C|qH!4BSy5aJ0ZLHSb%_CsaHb~s6Bw1akHhu1^fUUn!Lm9ayePc}O=z^x3|93k_hKxMEgoeD3TdO?l^ z!fmR=chjR1Wb?!{IFJp8E-moTHySGs!?R7bcyvhWkko)c?~% zPCpsOX;8GsAQQEV^Nr&0q@D3A+ZD@Pck)lhSr{&J~r$=ozQ0o?ZnTl zg|@x?j9^km`*j}KwBG=CWp6Y`@I2`e0HkuJT3jljv|ONQaq?HAv5mV>uQD*_g-l_ExP;yYVRF z`6~&HcF<1j>~?6|%gzL&GIpl($!2E;xZ`pZLI^m?g9Odj+xOD^u^irpYyRuAhpA)= zOXjYdNfaVxZ-gjBlEe|AVQR|lvzv}$ zWseg2?4X@k+1H?LFDnyF%2=7sBb${O;8qvVI=O|N6sivPs8bSOq3)iaJ~ZU1*+b%K z`+mbpci`f=crw3*m- z71i3_57PxcU07bu^Mg4i6Ye~h(?El$G+G;>tNjZ`M{DR1%VW{@%I;_<>|;j|s69Cj zH`vURaUPw(+!_Bf?ZQ?C@shc)0jOk|kYiDh3!8;K!v6MDa=aO2fVZLD zCCL!!NUC}eIlog{!g!Xdd@KIUYtKEYUD?%M6ZLa~`p;V$ojY1-jSRMG+Xh<`<&nyo zNI*sX=bZCnZboQpgX&bjc|9pdi?Mo5OXTLUuO(1U5s6kY*U)1s{vYT9K$K5^j~~Iz~gU zz6#AJ?2ZV8gTn~bY(Qw(EmQFYFsX>Y2E|~bBoK>}2NL=#q|`GIt8{s#J=uiS0_ahy0~M|RMQ-8HQhP}bbeFvFZ-0DM{-GVMW0O= z#NUD=L@$34#10m6^(0p6=gJ61YYMqaUD=P;F|~n1dN`pc=kZ3#<^u})lYCg<Ok%?q^1|h{l;P{g1T;TpF7R^oi9tPNB0L@|1&PoQeqadE!39O? zB{FS1Ioq39by61?DW;R4&hOBh(G-(f(Aa7ZnXjj-s1+WdOg)g#LFys>x+zMG&2G4J z;7aYT#O_^lk1WM*xOe?5pjVj;RMarP_}1CLJA|OunYZJw+wmLu<-E>JraJ8Ab>X?# znr)Rf#4Ia!T-nXn(vrwFJA>HMYGV}UW=fDV4K=3Iw*gz59n94tI#;u`45^&ywCfHY zo}3(EgXL=}JAm+q#Gk(cWTLLv(!-lO4gO7{ZgPF^CspvJ>&2VSh+ty$q30j&n=fo|0UWnhBr30Z8x0lrDZJ zG(@Ly?}J}r8fRB0HmytYb(l~3IGcg_HzLP9Cw;G9UxD*UnV%=(d&ZY;-V%vR?0i!h z&NIs_gDM<+R>mr1r$mX}Uob>7^}s!OxM*J_K@Z)KE5Qi1xyz)R0?t!@xO}omu#F3bM?0=8`dBOShuEP z$di+wR~c^A+LdTcRBg8>T5Fc$&?zi(pk8S&UqHsC^mUq(JnD)4h6NH>Dn+7x1^R!a zbvi!wX$lLEv{J_hO$UTvFj2&(G(>hqBzK`Eo3*Ly=_&*B&!6wMAoKONptmtJgmzT$!4$SdQ`VzCX$&py8 zpAX-_pWNl;$d<{8F^GcM8m(L*2Zv^5qFHId!V{y$J9S;`yb-+MiTTJBmG*%Kc`VZy zwa@tQvoykUbeSeb(|ZeCH67pRVD4oOTb!K+1i35&?SU=MP|@;imTf)v5zwx$-LDJc z9MTch&{v=pyljeZl*n>cc#VL4r)--Ex%3Z4Aw{R;goT-8A! z#~_X5pb;THtMk(>Cnu)%I#`(>BiCwKD%s>juF4NHW2Za)=EAfEeH{32AO75{@ehl- z$&Tq+jq4nlVtJzquEb>r;zzJAy>U>SqpQB2awC2tM3mGR?#&#O(KWkT32nj;-bqpZ+cd=jwg}h>+hYl zc9pHa%Pqdv9<0?zE3lv6hR_ADd%Ey$>=Lm1dBy<{+1Uj1HUk$V7V>wM%Z2}?1}40Wcv2UoTouqWLpD9X>Ic^2CWIAST- zcVFCx|9G#d*j4~X4ik%~Vf`f==NPvFO6k3T2w42(3!m(v-g zdeRp!!PZ$&fx4U*1EapkKV9oidXaya6)ntK&4mIJ(Y@7L^LE{nOZzjS4lWbe(jF2*aC~^B=2LtbF=1 z*z8``ZZyWW*J#*WYD+ENiELq_n=cwyWT$+D&g@2T#WSRZcLv`t3nmH#TC8$f$S>2# zvvXYv`Q<1dX^PmxFd@$ezD$x@c632PK2^xU#ZS`)=_y_{*(wCy0v6y_f&aC}(X_yi zaS_NT2yURX0N<&hvvX7m@ZHFJDL|w+On?hOfOnBvc62!cw9gKV+oWuOL?_ONP4LIP z+$Q~^H)FA0NVZPGWN=R+ z6j8I;-rcu>AkQsaG=e;T!nSZ9CZJv4!d<*9J?Of*$87f?tQ2Is#kO!y^(L;%Te!H- zVcfz!5h%)&EmMQzJwVwOF7h)-4cvOjws5)k=SzEcCANjjcVVP>4O_Tp0KKj)Tr8(s zxYyt>vV}{2^?nO?2^^Z?Ee@Yu+v6;|wyX*3Mr~5-{f?%fVF|3JT(2}NqPvEo+iU_R zw}I!1rs&SE_&Ys2YJ;TI*>~CzxHo$zMBV9S%|_78YQghUk{=+u)bj(iOVFcX2b?1>+pqxaB;9Im$S)&$e-!S`j9zH;ltc z9tJ;QhEk@OusKR1sp@e5BdW9@Ed=bOk^p+l`9P;vFg_QmD|9@5H&WRbzmpNmonl(e z^`ITLFEWOeKtZ7XJ)*Pjn#`SY-heyh9Mc_riG~L|PQ?Bha8h^r3H(LeDf#8$PGd?t zI+3EU&y*%7Ah@mK<57>bcvRYg)uB>7cX_#CYCDV)p4t>6k@Za@gM(gq$gLOl%BS$7{=Ib`<_Pk`f5K zyiE+m?{${}-W%fR6tB6Z7u;l{km<3HH|)0`gapC=aBE1(XFZS8!PoZkLz?A36Ktb; zqZy((r}dAal566|gK+VslK&>KRY|;(T~X%WRz8|v{g^*M{i0blEHA3ehDwF$G$)+X z`0N1kd-dalBKc^FCG(idQDR%qX zz-btTU;U`NdtkQVI6x9Fb|WxLf+3KSaJ>3)yBk4}3@F}$GU(o`A9uUEWERR>1BCKE zHv+Rz7y>DjoL4_S?nV+M7>c`~U<$qt@pU)-W+wd`m4Y0dc!mYy{1+$u&-6(8eK#tz zz$vN_p5(*g)fYJ%ihqD3eD4=z2dI-u`+7_gmRXN|2?*`VdhCGZd_8s;{1WRiKIi1i zF?Pk7O@o(A@zoe-7_jln$UEC=OnX9N@s(s|FYmF4#g?H&s7`zwkO-KL!GDzVI&B_i zzKcA)6J4P4NJgdc3?zR$RekP(*^>H6Foi4zRt9l|ZKe)jrGBpSF!?hbgk*0$q(dD5 zJKnd@dXG2T=ta*p}gi7AoMouZd^J1cvcSo5R}D@ zTu4Auks>BF-fL6pzZvLP_0_I4*lDK!ZzP=tv1Roii`4dV^B%GjaKCz~A_;0k2Lm)2IGGT4+(g_lizH%9{DHl?K0hiuT8QXi7fcRi*487tB% zY}X;hBvwEr%Tx`Ef=nW3se)cF<1DVI#EdWe$`{>3L~xO8s(??lMf- z3vg-VIcZp%MNl_-$mw<%r@^UY9FMMzHpgRt%jC_MZY5I$PD5|O%V{jj;a<4Y*lSbj zzbi<)*p&Dl!XM+%i$&e^GauL5vpWwI3iC4`A@tcnJMlB0fVRE-j9^km`*j}KwBG>N zqm1{`hI)hmEK%=`mnGhvBgt?}+yg1~e-)&|%*K8}dTz8aEDEwQkLm3JE7NV-jYqMw z`B2Gq^x27>9RzKA*_mKe#?Ev;+3d^!mzOAC8cZG}XujUQm*zj&bN^$%>3eQg=;v!KdTIMrghD%LC)$23wC$zsf=wB1*STcVb^}~qu4hHtbMi-n zw(ISCY5Uq7-e&x~yH%DI`h1VY9}DQkJ$*gSOOGvMaowkTw8{c{`B4TBC~;HGBGCAG zkUU~A1oZ9zB3uEzSWY9*-i@k7BGAY$j|epV&`eK%hr(dA^5@TiR{kiu&czaaw{|vp zOm51M;PLH{Wt)=vfFPCpa*{fM53hHc;IV(>#pFcsip`gAiRi)}uchlTagfdN82#IT zQdJ9+Bcv(EY_2f5e^Ht#k?1gTt(`|!bt7Ib`;yAq%ws5!jT~`CSevu8ieU3@Rxy&isLW)v~ftnY<@d z#4>zjUb+A>?28X+J|D6wZAqFo4kqr7NPUJPUv*RhDy2}Kz;$F*A(g3Rh{&!TLGlaB9zw& z<$eLAH@Oj*gTEL886lS&K>AuYnxGgtirqdJbsBTw0Md83dtmlEcLzw~18xLnNiYOb z5{>}UPr4BV$$;W5D1+_=kbcYEC9_bz9w3w-x)GR#!VpNIs z*JdNSbk3%S0$E^)sVF@#E?!+=Fh39~!7<^-#RPK3T0Q{7uQY<=-3ZL`V+f@D7HJC( zjxO^(jeMCKd5~NwO$Ft8xMh8m5$2%=K;BtnS-Qg)yE|+)#|s0*xy6mZEKY_%igP9` z4SBD~?{qJQ-AIDOMsXJu+tH5IYesa3TYz~-t>x*?-{9`NS%fWxl zqlo_i%XX4|XS6Xg6|aJrT-+W!iN@wia`ZjL_%l$icp!dt4tYV0V5hgD{|CfC{(KdC zCkzP#QpnwBzCQsRdYEl9K-Bg+Ad-)PG>%n^w!dHtUe}C<%dN_21b3b{mdD1+^=NBt z3?AU-Zw*J2SPGeEBeIK#3AQd6gS3*6iECU$=Xaqcp>^@kQRDjJC*6u?j^>}%T`C~* z$BfA72y$fmXixZt}ddK+G9ye)@+;cC3s-aYv+bXC+isfAnOK63YD-kE7TvMa7)m$RUfWjcjLL3Zg8oOi6&rkh4) zher__?Vz35;qlP6mmLa5W$aMrlg$nda0RZ9NNX!l8765u6<#(qBS!+^Hl^G>flDWN z_k=Gk){T{0t!S(~Tp5E03F*4Cq^&SWBnE_+@Exsr;)7rhar;*WsT-TBJ(qOWI8^hDdX6CSs&}Rqj#2m(;Z7*}6OiEw>$h~`VbCK>cOu2VYK!3P8kab;J z6Yea6`i>rQ`VC>626fCh9$g!4j>iC(xnLr=m1K&*Y3MC@IgL#@+zWRad+ptm&jo20 z^D_?-{uuoX7KQm4xAuQmYtQaH6hHGHgg!fHCw}H}Xxq!r2qtB;U+0lc`wehCx*8&F zs7DCE67}AAS>mU1BpGgrd*JTL5oe`s!mgOu9cE*PK_$!d7K?&x%wu}HOl#9kBOA|8 zBQ)AUJF&Cn(6*PI2}Wh?Oy`r$&J1vQH%g?z+O4K{^A_ohHL(9*}#aX#P3aS zo@`G{w)x9nc#?w97>G@_&@0V>1)C@EajsT$trkeIH0p;}F

jt8WDqG8t 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 Y$LPYjGEN6srbw@#??9t%gg0~l9|aB6fB*mh delta 7011 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 delta 5249 zcmbVQd2mzb5$EZ$k!5_z#zwXz%MKXhQ|2}lADBzv3v*3sK(>WHKije`O9l#rLI_xy z2Q=A7Y05xpXPEX6NMTIEv$k3!GZAsGsLYzNf5{^t}k~ATqboZ0qvurEVV?6%! z-goT&_P6`(u5|aIaQd%;{`>kPKkaxy|KSVw4(76nQk>7z>kD{0T6@|&GRTstsHnKH zrgHJBnxgJD`8jzH>=!O;EvyW(jrsagmc>e7m!`(Jy{O3E(d};c%!el$3*6PL)*6j6 z3~$Mbm9*|Izszc2v$i^6O@DyRU`v^WRr9miC3d*kIT3DXor#q=Yhsy9ODoJ;3$`jN z{4k~g)wMxiZs8>69$9te!gRB3x3k*g_4|4{+M0as)=rPlxV&zS@~AAimTXd{R@XH) z$tW@*y@a})`Xcgcv;-{0b9wq0;%_GEZXHznQ|!tBb!H8*(U2J~nFVk8q{Os#0b zVKO0;Nf9O#1zK4Dbds3I^wJVA#!nH9a6jIXVQlmGJ+1y8U(trTm30GU3g(DCxbxbi zG(GA&-VZ{8C6(=E&l0%`6eli8a6I7vhf>6$EKQt&P+lb{$!sVB${d8^gv*JaC0W>& z(0nbr0B5TpE}2~Ld-V8Js3?hvk#x-C!{|7kJV#GHy8<_pzc+>5BIWN(MxSR3E_+)& zZL&+?%iB}RQNR`Gw&bVskU?tZ;R**p9Ka&;60+n=Zb{ZyOBP1#b;6&`Cv+CkAV6hL zfhulM#Fl=zlzJzYSwyoiVM26?)e+mBL!YJ{5>RBG0Ht*WbEo1dJnX;^#Fi#$CfF(P zxtBuIqxhL9X?^akcvm1>mkX0J5>e6ul9UODbOq^QTg3S!mB+OUqhEADUq+smJ}+cc z$6TT{13X>Gd=+r0eU9~s_!8!DCW}jfThy!$(Umw+V zzqIZ~;m?rpJn~(egI-VOU^>X1c%}rB za_A+(iE*&5v;~F4L6UQX!cKw!=W@)j$yvvVsOLmnbFRa^OHg3}oHXgp)hZ^+&Mq(U zFtoL-M1y#n)HOBqYG&`nA#)Y#6hQxYEoVk7^?&vIsykpM(9QLuBO>dSZ17?wc zuR|8Q#@NuLfx@}-qO1J*+?P=0E=46&&YP^IFh5)5go^29!zgW>XhCa1C@ zzNUe`1)ZrD@uDgsM4;Fxz^aA$sOAc)DV!Nj473foN|W?$5ca?;t9<;)z`?AjU5;x0poLSl`|#oKL`A{G z>x76;zu|V|Qr3M(#VFMlvz~5Gv8OHI_O+-JhM6$M5yY=Kz^Xn}<+NK%iWTrMykDXfBRtE~w4 z=;~`4rw-xHx2Zs@@q`MrgpP-S&VYwaRt|QQP{>-dO#vGZm)w~q$)K;N?sk+aP4f7BJ-$uYqxH0Pc-v)3AMkG}oGVM2d;w0bONYs_fG(o(AgQTMlLat>&wx6A4XT%$Hi{HZ`oZ)N5AJNPa8h%Z~ z1sWHQEWgCy0&oxRnM!4Zoq`bs8q2 zO=27kjWpEZ5RfK%-Q6Dl_FgQH*j|eSKPbMAOM@&JWM_jMc2K-XGaT?B2Rq1t206$< z4lu~Uxdu71AV(D>M0kwA400er4kE|_1OqIaR1#Ut6sC*aR&u^%fs-v}c%wN6@|zPh zmvvCyTxC=mExd>an>WN^`1}cx^;5j)H&!L!MZs76k`N*v_LwrU35d1crrDd~AMt|% zoWhyTVS;`WKfvy^PF1e54c91ZD>%e!bQTK}KLM3xS;a~V6|HzZz}=(HOQkUEp9U2H zBh+uo7o4zTQw3!PjXsnaY=%;Nd!mEkb{m*B&&Vs`;61X-K!3ag|WHULgG18sNEH($}(A%00_PQAIM;Gp

    ua;U1tv zkF`B}q*SNiE)UH)lEbCCg-8h(d2idS+!5UeqUxqu_-Abi>66Ck3y#re#$C^GeX)u@ zBwgtT>Ph$LHk|-&90l-c+7t$O-}8_3DAa{ol%;5%UhLjitOj{#m%o{p1Be5a{dn3Y6?dPp>@8Y6cZtYmK)s5A|e zC>#D9Vu3_|%ry0jSs2s!*cor)qyJ#yl>g4e1Vi`^<1aiG(F7l~myWW~@;_SmP<&fY z7EVP;^n1@V`rSZ0hhBH2C|4uw(gq|F?3I>`Z)*-yptH-Squq3~c8e~=8fc096Y1iM zWjJ7kaGpa{u?i$ B6QlqD diff --git a/docs/.doctrees/index.doctree b/docs/.doctrees/index.doctree index 4f2c6998ff79c98b45fca2915cf4ae0633924be7..262f3cc0b1afafa548ba9d5f15baf6246a50967f 100644 GIT binary patch delta 159 zcmZotnyJLvz%rFja3gB~lb}WhYX(~nTR~z`YF^2d44%@-iA)pu5>qnu(=$urlXLR( zQi~@se_?0MFwPLmFr2)KO>eU*OA`|_YewnjWo-P6Kp8fm%uJw+)aFa<+Dx0-xn?tp zf9v5(Eh@?{icif;&QHnAOP|ui8XDrZc_+6&GcQkSZc=JWd}eN9dTQ}xR{j|*ei;}1 KHZSB)WCQ@h`ZQqx delta 137 zcmV;40CxYGB7!0XfCZKJ5U~YN0t}1>aA9&~ZgiAr40Dra0+9}7WOZS3WN$A=X>>?+ zVv_{}^t1f~vjPJaXmgSTE|cX3-2)bAnUVw=v*QOV0t$=Mnfj0JUcX0yNxPXm)550wOoXwZqXxDR0gNwYGM diff --git a/docs/_modules/motrackers/centroid_kf_tracker.html b/docs/_modules/motrackers/centroid_kf_tracker.html index 84b6c9d..34c3b99 100644 --- a/docs/_modules/motrackers/centroid_kf_tracker.html +++ b/docs/_modules/motrackers/centroid_kf_tracker.html @@ -87,7 +87,7 @@

    Source code for motrackers.centroid_kf_tracker

    [docs]def assign_tracks2detection_centroid_distances(bbox_tracks, bbox_detections, distance_threshold=10.): - """ + """ Assigns detected bounding boxes to tracked bounding boxes using IoU as a distance metric. Args: @@ -149,7 +149,7 @@

    Source code for motrackers.centroid_kf_tracker

    [docs]class CentroidKF_Tracker(Tracker): - """ + """ Kalman filter based tracking of multiple detected objects. Args: diff --git a/docs/_modules/motrackers/detectors/caffe.html b/docs/_modules/motrackers/detectors/caffe.html index b139259..3615e62 100644 --- a/docs/_modules/motrackers/detectors/caffe.html +++ b/docs/_modules/motrackers/detectors/caffe.html @@ -83,7 +83,7 @@

    Source code for motrackers.detectors.caffe

     
     
     
    [docs]class Caffe_SSDMobileNet(Detector): - """ + """ Caffe SSD MobileNet model for Object Detection. Args: diff --git a/docs/_modules/motrackers/detectors/detector.html b/docs/_modules/motrackers/detectors/detector.html index 3fcc901..db8662d 100644 --- a/docs/_modules/motrackers/detectors/detector.html +++ b/docs/_modules/motrackers/detectors/detector.html @@ -83,7 +83,7 @@

    Source code for motrackers.detectors.detector

    [docs]class Detector: - """ + """ Abstract class for detector. Args: @@ -105,7 +105,7 @@

    Source code for motrackers.detectors.detector

    self.bbox_colors = {key: np.random.randint(0, 255, size=(3,)).tolist() for key in self.object_names.keys()}
    [docs] def forward(self, image): - """ + """ Forward pass for the detector with input image. Args: @@ -117,7 +117,7 @@

    Source code for motrackers.detectors.detector

    raise NotImplemented
    [docs] def detect(self, image): - """ + """ Detect objects in the input image. Args: @@ -157,7 +157,7 @@

    Source code for motrackers.detectors.detector

    return np.array([]), np.array([]), np.array([])
    [docs] def draw_bboxes(self, image, bboxes, confidences, class_ids): - """ + """ Draw the bounding boxes about detected objects in the image. Args: diff --git a/docs/_modules/motrackers/detectors/tf.html b/docs/_modules/motrackers/detectors/tf.html index c514ebf..957ff0d 100644 --- a/docs/_modules/motrackers/detectors/tf.html +++ b/docs/_modules/motrackers/detectors/tf.html @@ -83,7 +83,7 @@

    Source code for motrackers.detectors.tf

     
     
     
    [docs]class TF_SSDMobileNetV2(Detector): - """ + """ Tensorflow SSD MobileNetv2 model for Object Detection. Args: diff --git a/docs/_modules/motrackers/detectors/yolo.html b/docs/_modules/motrackers/detectors/yolo.html index a8487bf..477e818 100644 --- a/docs/_modules/motrackers/detectors/yolo.html +++ b/docs/_modules/motrackers/detectors/yolo.html @@ -84,7 +84,7 @@

    Source code for motrackers.detectors.yolo

     
     
     
    [docs]class YOLOv3(Detector): - """ + """ YOLOv3 Object Detector Module. Args: diff --git a/docs/_modules/motrackers/iou_tracker.html b/docs/_modules/motrackers/iou_tracker.html index 6947fb1..08e07fe 100644 --- a/docs/_modules/motrackers/iou_tracker.html +++ b/docs/_modules/motrackers/iou_tracker.html @@ -82,7 +82,7 @@

    Source code for motrackers.iou_tracker

     
     
     
    [docs]class IOUTracker(Tracker): - """ + """ Intersection over Union Tracker. References diff --git a/docs/_modules/motrackers/kalman_tracker.html b/docs/_modules/motrackers/kalman_tracker.html index 107e490..80e36b6 100644 --- a/docs/_modules/motrackers/kalman_tracker.html +++ b/docs/_modules/motrackers/kalman_tracker.html @@ -81,7 +81,7 @@

    Source code for motrackers.kalman_tracker

     
     
     
    [docs]class KalmanFilter: - """ + """ Kalman Filter Implementation. Args: @@ -124,7 +124,7 @@

    Source code for motrackers.kalman_tracker

             self.x = np.zeros((self.state_size, 1)) if initial_state is None else initial_state
     
     
    [docs] def predict(self, u=0): - """ + """ Prediction step of Kalman Filter. Args: @@ -143,7 +143,7 @@

    Source code for motrackers.kalman_tracker

             return self.x
    [docs] def update(self, z): - """ + """ Measurement update of Kalman Filter. Args: @@ -169,7 +169,7 @@

    Source code for motrackers.kalman_tracker

     
     
     def get_process_covariance_matrix(dt):
    -    """
    +    """
         Generates a process noise covariance matrix for constant acceleration motion.
     
         Args:
    @@ -193,7 +193,7 @@ 

    Source code for motrackers.kalman_tracker

     
     
     def get_transition_matrix(dt):
    -    """
    +    """
         Generate the transition matrix for constant acceleration motion.
     
         Args:
    @@ -207,7 +207,7 @@ 

    Source code for motrackers.kalman_tracker

     
     
     
    [docs]class KFTrackerConstantAcceleration(KalmanFilter): - """ + """ Kalman Filter with constant acceleration kinematic model. Args: @@ -279,7 +279,7 @@

    Source code for motrackers.kalman_tracker

     
     
     
    [docs]class KFTrackerSORT(KalmanFilter): - """ + """ Kalman filter for ``SORT``. Args: diff --git a/docs/_modules/motrackers/sort_tracker.html b/docs/_modules/motrackers/sort_tracker.html index 9609236..96fe385 100644 --- a/docs/_modules/motrackers/sort_tracker.html +++ b/docs/_modules/motrackers/sort_tracker.html @@ -85,7 +85,7 @@

    Source code for motrackers.sort_tracker

     
     
     
    [docs]def assign_tracks2detection_iou(bbox_tracks, bbox_detections, iou_threshold=0.3): - """ + """ Assigns detected bounding boxes to tracked bounding boxes using IoU as a distance metric. Args: @@ -142,7 +142,7 @@

    Source code for motrackers.sort_tracker

     
     
     
    [docs]class SORT(CentroidKF_Tracker): - """ + """ SORT - Multi object tracker. Args: diff --git a/docs/_modules/motrackers/track.html b/docs/_modules/motrackers/track.html index b6e6f3f..11c685d 100644 --- a/docs/_modules/motrackers/track.html +++ b/docs/_modules/motrackers/track.html @@ -82,7 +82,7 @@

    Source code for motrackers.track

     
     
     
    [docs]class Track: - """ + """ Track containing attributes to track various objects. Args: @@ -135,7 +135,7 @@

    Source code for motrackers.track

                 raise NotImplementedError
     
     
    [docs] def update(self, frame_id, bbox, detection_confidence, class_id=None, lost=0, iou_score=0., **kwargs): - """ + """ Update the track. Args: @@ -167,7 +167,7 @@

    Source code for motrackers.track

     
         @property
         def centroid(self):
    -        """
    +        """
             Return the centroid of the bounding box.
     
             Returns:
    @@ -177,7 +177,7 @@ 

    Source code for motrackers.track

             return np.array((self.bbox[0]+0.5*self.bbox[2], self.bbox[1]+0.5*self.bbox[3]))
     
     
    [docs] def get_mot_challenge_format(self): - """ + """ Get the tracker data in MOT challenge format as a tuple of elements containing `(frame, id, bb_left, bb_top, bb_width, bb_height, conf, x, y, z)` @@ -195,7 +195,7 @@

    Source code for motrackers.track

             return mot_tuple
    [docs] def get_vis_drone_format(self): - """ + """ Track data output in VISDRONE Challenge format with tuple as `(frame_index, target_id, bbox_left, bbox_top, bbox_width, bbox_height, score, object_category, truncation, occlusion)`. @@ -217,7 +217,7 @@

    Source code for motrackers.track

             return mot_tuple
    [docs] def predict(self): - """ + """ Implement to prediction the next estimate of track. """ raise NotImplemented
    @@ -228,7 +228,7 @@

    Source code for motrackers.track

     
     
     
    [docs]class KFTrackSORT(Track): - """ + """ Track based on Kalman filter tracker used for SORT MOT-Algorithm. Args: @@ -254,7 +254,7 @@

    Source code for motrackers.track

                              iou_score=iou_score, data_output_format=data_output_format, **kwargs)
     
     
    [docs] def predict(self): - """ + """ Predicts the next estimate of the bounding box of the track. Returns: @@ -282,7 +282,7 @@

    Source code for motrackers.track

     
     
     
    [docs]class KFTrack4DSORT(Track): - """ + """ Track based on Kalman filter tracker used for SORT MOT-Algorithm. Args: @@ -321,7 +321,7 @@

    Source code for motrackers.track

     
     
     
    [docs]class KFTrackCentroid(Track): - """ + """ Track based on Kalman filter used for Centroid Tracking of bounding box in MOT. Args: @@ -346,7 +346,7 @@

    Source code for motrackers.track

                              iou_score=iou_score, data_output_format=data_output_format, **kwargs)
     
     
    [docs] def predict(self): - """ + """ Predicts the next estimate of the bounding box of the track. Returns: diff --git a/docs/_modules/motrackers/tracker.html b/docs/_modules/motrackers/tracker.html index f39a119..78459d0 100644 --- a/docs/_modules/motrackers/tracker.html +++ b/docs/_modules/motrackers/tracker.html @@ -85,7 +85,7 @@

    Source code for motrackers.tracker

     
     
     
    [docs]class Tracker: - """ + """ Greedy Tracker with tracking based on ``centroid`` location of the bounding box of the object. This tracker is also referred as ``CentroidTracker`` in this repository. @@ -102,7 +102,7 @@

    Source code for motrackers.tracker

             self.tracker_output_format = tracker_output_format
     
         def _add_track(self, frame_id, bbox, detection_confidence, class_id, **kwargs):
    -        """
    +        """
             Add a newly detected object to the queue.
     
             Args:
    @@ -121,7 +121,7 @@ 

    Source code for motrackers.tracker

             self.next_track_id += 1
     
         def _remove_track(self, track_id):
    -        """
    +        """
             Remove tracker data after object is lost.
     
             Args:
    @@ -131,7 +131,7 @@ 

    Source code for motrackers.tracker

             del self.tracks[track_id]
     
         def _update_track(self, track_id, frame_id, bbox, detection_confidence, class_id, lost=0, iou_score=0., **kwargs):
    -        """
    +        """
             Update track state.
     
             Args:
    @@ -151,7 +151,7 @@ 

    Source code for motrackers.tracker

     
         @staticmethod
         def _get_tracks(tracks):
    -        """
    +        """
             Output the information of tracks.
     
             Args:
    @@ -169,7 +169,7 @@ 

    Source code for motrackers.tracker

     
     
    [docs] @staticmethod def preprocess_input(bboxes, class_ids, detection_scores): - """ + """ Preprocess the input data. Args: @@ -189,7 +189,7 @@

    Source code for motrackers.tracker

             return new_detections
    [docs] def update(self, bboxes, detection_scores, class_ids): - """ + """ Update the tracker based on the new bounding boxes. Args: diff --git a/docs/_modules/motrackers/utils/misc.html b/docs/_modules/motrackers/utils/misc.html index c2ad073..cffbab8 100644 --- a/docs/_modules/motrackers/utils/misc.html +++ b/docs/_modules/motrackers/utils/misc.html @@ -82,7 +82,7 @@

    Source code for motrackers.utils.misc

     
     
     
    [docs]def get_centroid(bboxes): - """ + """ Calculate centroids for multiple bounding boxes. Args: @@ -114,7 +114,7 @@

    Source code for motrackers.utils.misc

     
     
     
    [docs]def iou(bbox1, bbox2): - """ + """ Calculates the intersection-over-union of two bounding boxes. Source: https://github.com/bochinski/iou-tracker/blob/master/util.py @@ -155,7 +155,7 @@

    Source code for motrackers.utils.misc

     
     
     
    [docs]def iou_xywh(bbox1, bbox2): - """ + """ Calculates the intersection-over-union of two bounding boxes. Source: https://github.com/bochinski/iou-tracker/blob/master/util.py @@ -175,7 +175,7 @@

    Source code for motrackers.utils.misc

     
     
     
    [docs]def xyxy2xywh(xyxy): - """ + """ Convert bounding box coordinates from (xmin, ymin, xmax, ymax) format to (xmin, ymin, width, height). Args: @@ -200,7 +200,7 @@

    Source code for motrackers.utils.misc

     
     
     
    [docs]def xywh2xyxy(xywh): - """ + """ Convert bounding box coordinates from (xmin, ymin, width, height) to (xmin, ymin, xmax, ymax) format. Args: @@ -224,7 +224,7 @@

    Source code for motrackers.utils.misc

     
     
     
    [docs]def midwh2xywh(midwh): - """ + """ Convert bounding box coordinates from (xmid, ymid, width, height) to (xmin, ymin, width, height) format. Args: @@ -246,7 +246,7 @@

    Source code for motrackers.utils.misc

     
     
     
    [docs]def intersection_complement_indices(big_set_indices, small_set_indices): - """ + """ Get the complement of intersection of two sets of indices. Args: @@ -265,7 +265,7 @@

    Source code for motrackers.utils.misc

     
     
     
    [docs]def nms(boxes, scores, overlapThresh, classes=None): - """ + """ Non-maximum suppression. based on Malisiewicz et al. Args: @@ -323,7 +323,7 @@

    Source code for motrackers.utils.misc

     
     
     
    [docs]def draw_tracks(image, tracks): - """ + """ Draw on input image. Args: diff --git a/docs/_static/basic.css b/docs/_static/basic.css index 4e9a9f1..eeb0519 100644 --- a/docs/_static/basic.css +++ b/docs/_static/basic.css @@ -236,6 +236,16 @@ div.body p, div.body dd, div.body li, div.body blockquote { a.headerlink { visibility: hidden; } +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + h1:hover > a.headerlink, h2:hover > a.headerlink, @@ -324,15 +334,11 @@ aside.sidebar { p.sidebar-title { font-weight: bold; } -nav.contents, -aside.topic, div.admonition, div.topic, blockquote { clear: left; } /* -- topics ---------------------------------------------------------------- */ -nav.contents, -aside.topic, div.topic { border: 1px solid #ccc; padding: 7px; @@ -371,8 +377,6 @@ div.body p.centered { div.sidebar > :last-child, aside.sidebar > :last-child, -nav.contents > :last-child, -aside.topic > :last-child, div.topic > :last-child, div.admonition > :last-child { margin-bottom: 0; @@ -380,8 +384,6 @@ div.admonition > :last-child { div.sidebar::after, aside.sidebar::after, -nav.contents::after, -aside.topic::after, div.topic::after, div.admonition::after, blockquote::after { @@ -606,26 +608,19 @@ ol.simple p, ul.simple p { margin-bottom: 0; } -aside.footnote > span, -div.citation > span { +dl.footnote > dt, +dl.citation > dt { float: left; + margin-right: 0.5em; } -aside.footnote > span:last-of-type, -div.citation > span:last-of-type { - padding-right: 0.5em; -} -aside.footnote > p { - margin-left: 2em; -} -div.citation > p { - margin-left: 4em; -} -aside.footnote > p:last-of-type, -div.citation > p:last-of-type { + +dl.footnote > dd, +dl.citation > dd { margin-bottom: 0em; } -aside.footnote > p:last-of-type:after, -div.citation > p:last-of-type:after { + +dl.footnote > dd:after, +dl.citation > dd:after { content: ""; clear: both; } @@ -641,6 +636,10 @@ dl.field-list > dt { padding-left: 0.5em; padding-right: 5px; } +dl.field-list > dt:after { + content: ":"; +} + dl.field-list > dd { padding-left: 0.5em; diff --git a/docs/_static/doctools.js b/docs/_static/doctools.js index c3db08d..527b876 100644 --- a/docs/_static/doctools.js +++ b/docs/_static/doctools.js @@ -10,6 +10,13 @@ */ "use strict"; +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + const _ready = (callback) => { if (document.readyState !== "loading") { callback(); @@ -18,73 +25,11 @@ const _ready = (callback) => { } }; -/** - * highlight a given string on a node by wrapping it in - * span elements with the given class name. - */ -const _highlight = (node, addItems, text, className) => { - if (node.nodeType === Node.TEXT_NODE) { - const val = node.nodeValue; - const parent = node.parentNode; - const pos = val.toLowerCase().indexOf(text); - if ( - pos >= 0 && - !parent.classList.contains(className) && - !parent.classList.contains("nohighlight") - ) { - let span; - - const closestNode = parent.closest("body, svg, foreignObject"); - const isInSVG = closestNode && closestNode.matches("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.classList.add(className); - } - - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - parent.insertBefore( - span, - parent.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling - ) - ); - node.nodeValue = val.substr(0, pos); - - if (isInSVG) { - const rect = document.createElementNS( - "http://www.w3.org/2000/svg", - "rect" - ); - const bbox = parent.getBBox(); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute("class", className); - addItems.push({ parent: parent, target: rect }); - } - } - } else if (node.matches && !node.matches("button, select, textarea")) { - node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); - } -}; -const _highlightText = (thisNode, text, className) => { - let addItems = []; - _highlight(thisNode, addItems, text, className); - addItems.forEach((obj) => - obj.parent.insertAdjacentElement("beforebegin", obj.target) - ); -}; - /** * Small JavaScript module for the documentation. */ const Documentation = { init: () => { - Documentation.highlightSearchWords(); Documentation.initDomainIndexTable(); Documentation.initOnKeyListeners(); }, @@ -126,51 +71,6 @@ const Documentation = { Documentation.LOCALE = catalog.locale; }, - /** - * highlight the search words provided in the url in the text - */ - highlightSearchWords: () => { - const highlight = - new URLSearchParams(window.location.search).get("highlight") || ""; - const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); - if (terms.length === 0) return; // nothing to do - - // There should never be more than one element matching "div.body" - const divBody = document.querySelectorAll("div.body"); - const body = divBody.length ? divBody[0] : document.querySelector("body"); - window.setTimeout(() => { - terms.forEach((term) => _highlightText(body, term, "highlighted")); - }, 10); - - const searchBox = document.getElementById("searchbox"); - if (searchBox === null) return; - searchBox.appendChild( - document - .createRange() - .createContextualFragment( - '" - ) - ); - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords: () => { - document - .querySelectorAll("#searchbox .highlight-link") - .forEach((el) => el.remove()); - document - .querySelectorAll("span.highlighted") - .forEach((el) => el.classList.remove("highlighted")); - const url = new URL(window.location); - url.searchParams.delete("highlight"); - window.history.replaceState({}, "", url); - }, - /** * helper function to focus on search bar */ @@ -210,15 +110,11 @@ const Documentation = { ) return; - const blacklistedElements = new Set([ - "TEXTAREA", - "INPUT", - "SELECT", - "BUTTON", - ]); document.addEventListener("keydown", (event) => { - if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements - if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; if (!event.shiftKey) { switch (event.key) { @@ -240,10 +136,6 @@ const Documentation = { event.preventDefault(); } break; - case "Escape": - if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; - Documentation.hideSearchWords(); - event.preventDefault(); } } diff --git a/docs/_static/jquery-3.5.1.js b/docs/_static/jquery-3.5.1.js deleted file mode 100644 index 5093733..0000000 --- a/docs/_static/jquery-3.5.1.js +++ /dev/null @@ -1,10872 +0,0 @@ -/*! - * jQuery JavaScript Library v3.5.1 - * https://jquery.com/ - * - * Includes Sizzle.js - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2020-05-04T22:49Z - */ -( function( global, factory ) { - - "use strict"; - - if ( typeof module === "object" && typeof module.exports === "object" ) { - - // For CommonJS and CommonJS-like environments where a proper `window` - // is present, execute the factory and get jQuery. - // For environments that do not have a `window` with a `document` - // (such as Node.js), expose a factory as module.exports. - // This accentuates the need for the creation of a real `window`. - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info. - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 -// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode -// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common -// enough that all such attempts are guarded in a try block. -"use strict"; - -var arr = []; - -var getProto = Object.getPrototypeOf; - -var slice = arr.slice; - -var flat = arr.flat ? function( array ) { - return arr.flat.call( array ); -} : function( array ) { - return arr.concat.apply( [], array ); -}; - - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var fnToString = hasOwn.toString; - -var ObjectFunctionString = fnToString.call( Object ); - -var support = {}; - -var isFunction = function isFunction( obj ) { - - // Support: Chrome <=57, Firefox <=52 - // In some browsers, typeof returns "function" for HTML elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - return typeof obj === "function" && typeof obj.nodeType !== "number"; - }; - - -var isWindow = function isWindow( obj ) { - return obj != null && obj === obj.window; - }; - - -var document = window.document; - - - - var preservedScriptAttributes = { - type: true, - src: true, - nonce: true, - noModule: true - }; - - function DOMEval( code, node, doc ) { - doc = doc || document; - - var i, val, - script = doc.createElement( "script" ); - - script.text = code; - if ( node ) { - for ( i in preservedScriptAttributes ) { - - // Support: Firefox 64+, Edge 18+ - // Some browsers don't support the "nonce" property on scripts. - // On the other hand, just using `getAttribute` is not enough as - // the `nonce` attribute is reset to an empty string whenever it - // becomes browsing-context connected. - // See https://github.com/whatwg/html/issues/2369 - // See https://html.spec.whatwg.org/#nonce-attributes - // The `node.getAttribute` check was added for the sake of - // `jQuery.globalEval` so that it can fake a nonce-containing node - // via an object. - val = node[ i ] || node.getAttribute && node.getAttribute( i ); - if ( val ) { - script.setAttribute( i, val ); - } - } - } - doc.head.appendChild( script ).parentNode.removeChild( script ); - } - - -function toType( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; -} -/* global Symbol */ -// Defining this global in .eslintrc.json would create a danger of using the global -// unguarded in another place, it seems safer to define global only for this module - - - -var - version = "3.5.1", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }; - -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - - // Return all the elements in a clean array - if ( num == null ) { - return slice.call( this ); - } - - // Return just the one element from the set - return num < 0 ? this[ num + this.length ] : this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - even: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return ( i + 1 ) % 2; - } ) ); - }, - - odd: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return i % 2; - } ) ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // Skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !isFunction( target ) ) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { - - // Extend the base object - for ( name in options ) { - copy = options[ name ]; - - // Prevent Object.prototype pollution - // Prevent never-ending loop - if ( name === "__proto__" || target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = Array.isArray( copy ) ) ) ) { - src = target[ name ]; - - // Ensure proper type for the source value - if ( copyIsArray && !Array.isArray( src ) ) { - clone = []; - } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { - clone = {}; - } else { - clone = src; - } - copyIsArray = false; - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend( { - - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - isPlainObject: function( obj ) { - var proto, Ctor; - - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if ( !obj || toString.call( obj ) !== "[object Object]" ) { - return false; - } - - proto = getProto( obj ); - - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if ( !proto ) { - return true; - } - - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; - return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; - }, - - isEmptyObject: function( obj ) { - var name; - - for ( name in obj ) { - return false; - } - return true; - }, - - // Evaluates a script in a provided context; falls back to the global one - // if not specified. - globalEval: function( code, options, doc ) { - DOMEval( code, { nonce: options && options.nonce }, doc ); - }, - - each: function( obj, callback ) { - var length, i = 0; - - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return flat( ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -} ); - -if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; -} - -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( _i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -} ); - -function isArrayLike( obj ) { - - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = toType( obj ); - - if ( isFunction( obj ) || isWindow( obj ) ) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v2.3.5 - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://js.foundation/ - * - * Date: 2020-03-14 - */ -( function( window ) { -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - nonnativeSelectorCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // Instance methods - hasOwn = ( {} ).hasOwnProperty, - arr = [], - pop = arr.pop, - pushNative = arr.push, - push = arr.push, - slice = arr.slice, - - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[ i ] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + - "ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram - identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + - "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - - // "Attribute values must be CSS identifiers [capture 5] - // or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + - whitespace + "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + - whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + - "*" ), - rdescend = new RegExp( whitespace + "|>" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + identifier + ")" ), - "CLASS": new RegExp( "^\\.(" + identifier + ")" ), - "TAG": new RegExp( "^(" + identifier + "|[*])" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + - whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + - whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + - "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + - "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rhtml = /HTML$/i, - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - - // CSS escapes - // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), - funescape = function( escape, nonHex ) { - var high = "0x" + escape.slice( 1 ) - 0x10000; - - return nonHex ? - - // Strip the backslash prefix from a non-hex escape sequence - nonHex : - - // Replace a hexadecimal escape sequence with the encoded Unicode code point - // Support: IE <=11+ - // For values outside the Basic Multilingual Plane (BMP), manually construct a - // surrogate pair - high < 0 ? - String.fromCharCode( high + 0x10000 ) : - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, - fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + - ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }, - - inDisabledFieldset = addCombinator( - function( elem ) { - return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; - }, - { dir: "parentNode", next: "legend" } - ); - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - ( arr = slice.call( preferredDoc.childNodes ) ), - preferredDoc.childNodes - ); - - // Support: Android<4.0 - // Detect silently failing push.apply - // eslint-disable-next-line no-unused-expressions - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - pushNative.apply( target, slice.call( els ) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - - // Can't trust NodeList.length - while ( ( target[ j++ ] = els[ i++ ] ) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - setDocument( context ); - context = context || document; - - if ( documentIsHTML ) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { - - // ID selector - if ( ( m = match[ 1 ] ) ) { - - // Document context - if ( nodeType === 9 ) { - if ( ( elem = context.getElementById( m ) ) ) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( newContext && ( elem = newContext.getElementById( m ) ) && - contains( context, elem ) && - elem.id === m ) { - - results.push( elem ); - return results; - } - } - - // Type selector - } else if ( match[ 2 ] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Class selector - } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && - context.getElementsByClassName ) { - - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // Take advantage of querySelectorAll - if ( support.qsa && - !nonnativeSelectorCache[ selector + " " ] && - ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && - - // Support: IE 8 only - // Exclude object elements - ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { - - newSelector = selector; - newContext = context; - - // qSA considers elements outside a scoping root when evaluating child or - // descendant combinators, which is not what we want. - // In such cases, we work around the behavior by prefixing every selector in the - // list with an ID selector referencing the scope context. - // The technique has to be used as well when a leading combinator is used - // as such selectors are not recognized by querySelectorAll. - // Thanks to Andrew Dupont for this technique. - if ( nodeType === 1 && - ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - - // We can use :scope instead of the ID hack if the browser - // supports it & if we're not changing the context. - if ( newContext !== context || !support.scope ) { - - // Capture the context ID, setting it first if necessary - if ( ( nid = context.getAttribute( "id" ) ) ) { - nid = nid.replace( rcssescape, fcssescape ); - } else { - context.setAttribute( "id", ( nid = expando ) ); - } - } - - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - while ( i-- ) { - groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + - toSelector( groups[ i ] ); - } - newSelector = groups.join( "," ); - } - - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - nonnativeSelectorCache( selector, true ); - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return ( cache[ key + " " ] = value ); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ -function assert( fn ) { - var el = document.createElement( "fieldset" ); - - try { - return !!fn( el ); - } catch ( e ) { - return false; - } finally { - - // Remove from its parent by default - if ( el.parentNode ) { - el.parentNode.removeChild( el ); - } - - // release memory in IE - el = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split( "|" ), - i = arr.length; - - while ( i-- ) { - Expr.attrHandle[ arr[ i ] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - a.sourceIndex - b.sourceIndex; - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( ( cur = cur.nextSibling ) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return ( name === "input" || name === "button" ) && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ -function createDisabledPseudo( disabled ) { - - // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function( elem ) { - - // Only certain elements can match :enabled or :disabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled - if ( "form" in elem ) { - - // Check for inherited disabledness on relevant non-disabled elements: - // * listed form-associated elements in a disabled fieldset - // https://html.spec.whatwg.org/multipage/forms.html#category-listed - // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled - // * option elements in a disabled optgroup - // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled - // All such elements have a "form" property. - if ( elem.parentNode && elem.disabled === false ) { - - // Option elements defer to a parent optgroup if present - if ( "label" in elem ) { - if ( "label" in elem.parentNode ) { - return elem.parentNode.disabled === disabled; - } else { - return elem.disabled === disabled; - } - } - - // Support: IE 6 - 11 - // Use the isDisabled shortcut property to check for disabled fieldset ancestors - return elem.isDisabled === disabled || - - // Where there is no isDisabled, check manually - /* jshint -W018 */ - elem.isDisabled !== !disabled && - inDisabledFieldset( elem ) === disabled; - } - - return elem.disabled === disabled; - - // Try to winnow out elements that can't be disabled before trusting the disabled property. - // Some victims get caught in our net (label, legend, menu, track), but it shouldn't - // even exist on them, let alone have a boolean value. - } else if ( "label" in elem ) { - return elem.disabled === disabled; - } - - // Remaining elements are neither :enabled nor :disabled - return false; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction( function( argument ) { - argument = +argument; - return markFunction( function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ ( j = matchIndexes[ i ] ) ] ) { - seed[ j ] = !( matches[ j ] = seed[ j ] ); - } - } - } ); - } ); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - var namespace = elem.namespaceURI, - docElem = ( elem.ownerDocument || elem ).documentElement; - - // Support: IE <=8 - // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes - // https://bugs.jquery.com/ticket/4833 - return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, subWindow, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML( document ); - - // Support: IE 9 - 11+, Edge 12 - 18+ - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( preferredDoc != document && - ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { - - // Support: IE 11, Edge - if ( subWindow.addEventListener ) { - subWindow.addEventListener( "unload", unloadHandler, false ); - - // Support: IE 9 - 10 only - } else if ( subWindow.attachEvent ) { - subWindow.attachEvent( "onunload", unloadHandler ); - } - } - - // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, - // Safari 4 - 5 only, Opera <=11.6 - 12.x only - // IE/Edge & older browsers don't support the :scope pseudo-class. - // Support: Safari 6.0 only - // Safari 6.0 supports :scope but it's an alias of :root there. - support.scope = assert( function( el ) { - docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); - return typeof el.querySelectorAll !== "undefined" && - !el.querySelectorAll( ":scope fieldset div" ).length; - } ); - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert( function( el ) { - el.className = "i"; - return !el.getAttribute( "className" ); - } ); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert( function( el ) { - el.appendChild( document.createComment( "" ) ); - return !el.getElementsByTagName( "*" ).length; - } ); - - // Support: IE<9 - support.getElementsByClassName = rnative.test( document.getElementsByClassName ); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programmatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert( function( el ) { - docElem.appendChild( el ).id = expando; - return !document.getElementsByName || !document.getElementsByName( expando ).length; - } ); - - // ID filter and find - if ( support.getById ) { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute( "id" ) === attrId; - }; - }; - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var elem = context.getElementById( id ); - return elem ? [ elem ] : []; - } - }; - } else { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode( "id" ); - return node && node.value === attrId; - }; - }; - - // Support: IE 6 - 7 only - // getElementById is not reliable as a find shortcut - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var node, i, elems, - elem = context.getElementById( id ); - - if ( elem ) { - - // Verify the id attribute - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - - // Fall back on getElementsByName - elems = context.getElementsByName( id ); - i = 0; - while ( ( elem = elems[ i++ ] ) ) { - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - } - } - - return []; - } - }; - } - - // Tag - Expr.find[ "TAG" ] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); - } - } : - - function( tag, context ) { - var elem, - tmp = [], - i = 0, - - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See https://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { - - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert( function( el ) { - - var input; - - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // https://bugs.jquery.com/ticket/12359 - docElem.appendChild( el ).innerHTML = "" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !el.querySelectorAll( "[selected]" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push( "~=" ); - } - - // Support: IE 11+, Edge 15 - 18+ - // IE 11/Edge don't find elements on a `[name='']` query in some cases. - // Adding a temporary attribute to the document before the selection works - // around the issue. - // Interestingly, IE 10 & older don't seem to have the issue. - input = document.createElement( "input" ); - input.setAttribute( "name", "" ); - el.appendChild( input ); - if ( !el.querySelectorAll( "[name='']" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + - whitespace + "*(?:''|\"\")" ); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !el.querySelectorAll( ":checked" ).length ) { - rbuggyQSA.push( ":checked" ); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibling-combinator selector` fails - if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push( ".#.+[+~]" ); - } - - // Support: Firefox <=3.6 - 5 only - // Old Firefox doesn't throw on a badly-escaped identifier. - el.querySelectorAll( "\\\f" ); - rbuggyQSA.push( "[\\r\\n\\f]" ); - } ); - - assert( function( el ) { - el.innerHTML = "" + - ""; - - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement( "input" ); - input.setAttribute( "type", "hidden" ); - el.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( el.querySelectorAll( "[name=d]" ).length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: IE9-11+ - // IE's :disabled selector does not pick up the children of disabled fieldsets - docElem.appendChild( el ).disabled = true; - if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: Opera 10 - 11 only - // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll( "*,:x" ); - rbuggyQSA.push( ",.*:" ); - } ); - } - - if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector ) ) ) ) { - - assert( function( el ) { - - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( el, "*" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( el, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - } ); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - ) ); - } : - function( a, b ) { - if ( b ) { - while ( ( b = b.parentNode ) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { - - // Choose the first element that is related to our preferred document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( a == document || a.ownerDocument == preferredDoc && - contains( preferredDoc, a ) ) { - return -1; - } - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( b == document || b.ownerDocument == preferredDoc && - contains( preferredDoc, b ) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - /* eslint-disable eqeqeq */ - return a == document ? -1 : - b == document ? 1 : - /* eslint-enable eqeqeq */ - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( ( cur = cur.parentNode ) ) { - ap.unshift( cur ); - } - cur = b; - while ( ( cur = cur.parentNode ) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[ i ] === bp[ i ] ) { - i++; - } - - return i ? - - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[ i ], bp[ i ] ) : - - // Otherwise nodes in our document sort first - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - /* eslint-disable eqeqeq */ - ap[ i ] == preferredDoc ? -1 : - bp[ i ] == preferredDoc ? 1 : - /* eslint-enable eqeqeq */ - 0; - }; - - return document; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - setDocument( elem ); - - if ( support.matchesSelector && documentIsHTML && - !nonnativeSelectorCache[ expr + " " ] && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch ( e ) { - nonnativeSelectorCache( expr, true ); - } - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( context.ownerDocument || context ) != document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( elem.ownerDocument || elem ) != document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - ( val = elem.getAttributeNode( name ) ) && val.specified ? - val.value : - null; -}; - -Sizzle.escape = function( sel ) { - return ( sel + "" ).replace( rcssescape, fcssescape ); -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - - // If no nodeType, this is expected to be an array - while ( ( node = elem[ i++ ] ) ) { - - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[ 1 ] = match[ 1 ].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[ 3 ] = ( match[ 3 ] || match[ 4 ] || - match[ 5 ] || "" ).replace( runescape, funescape ); - - if ( match[ 2 ] === "~=" ) { - match[ 3 ] = " " + match[ 3 ] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[ 1 ] = match[ 1 ].toLowerCase(); - - if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { - - // nth-* requires argument - if ( !match[ 3 ] ) { - Sizzle.error( match[ 0 ] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[ 4 ] = +( match[ 4 ] ? - match[ 5 ] + ( match[ 6 ] || 1 ) : - 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); - match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); - - // other types prohibit arguments - } else if ( match[ 3 ] ) { - Sizzle.error( match[ 0 ] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[ 6 ] && match[ 2 ]; - - if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[ 3 ] ) { - match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - - // Get excess from tokenize (recursively) - ( excess = tokenize( unquoted, true ) ) && - - // advance to the next closing parenthesis - ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { - - // excess is a negative index - match[ 0 ] = match[ 0 ].slice( 0, excess ); - match[ 2 ] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { - return true; - } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - ( pattern = new RegExp( "(^|" + whitespace + - ")" + className + "(" + whitespace + "|$)" ) ) && classCache( - className, function( elem ) { - return pattern.test( - typeof elem.className === "string" && elem.className || - typeof elem.getAttribute !== "undefined" && - elem.getAttribute( "class" ) || - "" - ); - } ); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - /* eslint-disable max-len */ - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - /* eslint-enable max-len */ - - }; - }, - - "CHILD": function( type, what, _argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, _context, xml ) { - var cache, uniqueCache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( ( node = node[ dir ] ) ) { - if ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) { - - return false; - } - } - - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - - // Seek `elem` from a previously-cached index - - // ...in a gzip-friendly way - node = parent; - outerCache = node[ expando ] || ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex && cache[ 2 ]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( ( node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - ( diff = nodeIndex = 0 ) || start.pop() ) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - } else { - - // Use previously-cached element index if available - if ( useCache ) { - - // ...in a gzip-friendly way - node = elem; - outerCache = node[ expando ] || ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex; - } - - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if ( diff === false ) { - - // Use the same loop as above to seek `elem` from the start - while ( ( node = ++nodeIndex && node && node[ dir ] || - ( diff = nodeIndex = 0 ) || start.pop() ) ) { - - if ( ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) && - ++diff ) { - - // Cache the index of each encountered element - if ( useCache ) { - outerCache = node[ expando ] || - ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - uniqueCache[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction( function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf( seed, matched[ i ] ); - seed[ idx ] = !( matches[ idx ] = matched[ i ] ); - } - } ) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - - // Potentially complex pseudos - "not": markFunction( function( selector ) { - - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction( function( seed, matches, _context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( ( elem = unmatched[ i ] ) ) { - seed[ i ] = !( matches[ i ] = elem ); - } - } - } ) : - function( elem, _context, xml ) { - input[ 0 ] = elem; - matcher( input, null, xml, results ); - - // Don't keep the element (issue #299) - input[ 0 ] = null; - return !results.pop(); - }; - } ), - - "has": markFunction( function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - } ), - - "contains": markFunction( function( text ) { - text = text.replace( runescape, funescape ); - return function( elem ) { - return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; - }; - } ), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - - // lang value must be a valid identifier - if ( !ridentifier.test( lang || "" ) ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( ( elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); - return false; - }; - } ), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && - ( !document.hasFocus || document.hasFocus() ) && - !!( elem.type || elem.href || ~elem.tabIndex ); - }, - - // Boolean properties - "enabled": createDisabledPseudo( false ), - "disabled": createDisabledPseudo( true ), - - "checked": function( elem ) { - - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return ( nodeName === "input" && !!elem.checked ) || - ( nodeName === "option" && !!elem.selected ); - }, - - "selected": function( elem ) { - - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - // eslint-disable-next-line no-unused-expressions - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos[ "empty" ]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( ( attr = elem.getAttribute( "type" ) ) == null || - attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo( function() { - return [ 0 ]; - } ), - - "last": createPositionalPseudo( function( _matchIndexes, length ) { - return [ length - 1 ]; - } ), - - "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - } ), - - "even": createPositionalPseudo( function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "odd": createPositionalPseudo( function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { - var i = argument < 0 ? - argument + length : - argument > length ? - length : - argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ) - } -}; - -Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || ( match = rcomma.exec( soFar ) ) ) { - if ( match ) { - - // Don't consume trailing commas as valid - soFar = soFar.slice( match[ 0 ].length ) || soFar; - } - groups.push( ( tokens = [] ) ); - } - - matched = false; - - // Combinators - if ( ( match = rcombinators.exec( soFar ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - - // Cast descendant combinators to space - type: match[ 0 ].replace( rtrim, " " ) - } ); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || - ( match = preFilters[ type ]( match ) ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - type: type, - matches: match - } ); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[ i ].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - skip = combinator.next, - key = skip || dir, - checkNonElements = base && key === "parentNode", - doneName = done++; - - return combinator.first ? - - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - return false; - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, uniqueCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if ( xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || ( elem[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ elem.uniqueID ] || - ( outerCache[ elem.uniqueID ] = {} ); - - if ( skip && skip === elem.nodeName.toLowerCase() ) { - elem = elem[ dir ] || elem; - } else if ( ( oldCache = uniqueCache[ key ] ) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return ( newCache[ 2 ] = oldCache[ 2 ] ); - } else { - - // Reuse newcache so results back-propagate to previous elements - uniqueCache[ key ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { - return true; - } - } - } - } - } - return false; - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[ i ]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[ 0 ]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[ i ], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( ( elem = unmatched[ i ] ) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction( function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( - selector || "*", - context.nodeType ? [ context ] : context, - [] - ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( ( elem = temp[ i ] ) ) { - matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) ) { - - // Restore matcherIn since elem is not yet a final match - temp.push( ( matcherIn[ i ] = elem ) ); - } - } - postFinder( null, ( matcherOut = [] ), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) && - ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { - - seed[ temp ] = !( results[ temp ] = elem ); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - } ); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[ 0 ].type ], - implicitRelative = leadingRelative || Expr.relative[ " " ], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - ( checkContext = context ).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - } ]; - - for ( ; i < len; i++ ) { - if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { - matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; - } else { - matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[ j ].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens - .slice( 0, i - 1 ) - .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), - - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), - len = elems.length; - - if ( outermost ) { - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - outermostContext = context == document || context || outermost; - } - - // Add elements passing elementMatchers directly to results - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( !context && elem.ownerDocument != document ) { - setDocument( elem ); - xml = !documentIsHTML; - } - while ( ( matcher = elementMatchers[ j++ ] ) ) { - if ( matcher( elem, context || document, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - - // They will have gone through all possible matchers - if ( ( elem = !matcher && elem ) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; - - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if ( bySet && i !== matchedCount ) { - j = 0; - while ( ( matcher = setMatchers[ j++ ] ) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !( unmatched[ i ] || setMatched[ i ] ) ) { - setMatched[ i ] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[ i ] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( - selector, - matcherFromGroupMatchers( elementMatchers, setMatchers ) - ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( ( selector = compiled.selector || selector ) ); - - results = results || []; - - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if ( match.length === 1 ) { - - // Reduce context if the leading compound selector is an ID - tokens = match[ 0 ] = match[ 0 ].slice( 0 ); - if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { - - context = ( Expr.find[ "ID" ]( token.matches[ 0 ] - .replace( runescape, funescape ), context ) || [] )[ 0 ]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[ i ]; - - // Abort if we hit a combinator - if ( Expr.relative[ ( type = token.type ) ] ) { - break; - } - if ( ( find = Expr.find[ type ] ) ) { - - // Search, expanding context for leading sibling combinators - if ( ( seed = find( - token.matches[ 0 ].replace( runescape, funescape ), - rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || - context - ) ) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - -// One-time assignments - -// Sort stability -support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; - -// Support: Chrome 14-35+ -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert( function( el ) { - - // Should return 1, but returns 4 (following) - return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; -} ); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert( function( el ) { - el.innerHTML = ""; - return el.firstChild.getAttribute( "href" ) === "#"; -} ) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - } ); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert( function( el ) { - el.innerHTML = ""; - el.firstChild.setAttribute( "value", "" ); - return el.firstChild.getAttribute( "value" ) === ""; -} ) ) { - addHandle( "value", function( elem, _name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - } ); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert( function( el ) { - return el.getAttribute( "disabled" ) == null; -} ) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - ( val = elem.getAttributeNode( name ) ) && val.specified ? - val.value : - null; - } - } ); -} - -return Sizzle; - -} )( window ); - - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; - -// Deprecated -jQuery.expr[ ":" ] = jQuery.expr.pseudos; -jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; -jQuery.escapeSelector = Sizzle.escape; - - - - -var dir = function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; -}; - - -var siblings = function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; -}; - - -var rneedsContext = jQuery.expr.match.needsContext; - - - -function nodeName( elem, name ) { - - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - -}; -var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); - - - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - return !!qualifier.call( elem, i, elem ) !== not; - } ); - } - - // Single element - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - } ); - } - - // Arraylike of elements (jQuery, arguments, Array) - if ( typeof qualifier !== "string" ) { - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) > -1 ) !== not; - } ); - } - - // Filtered directly for both simple and complex selectors - return jQuery.filter( qualifier, elements, not ); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - if ( elems.length === 1 && elem.nodeType === 1 ) { - return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; - } - - return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - } ) ); -}; - -jQuery.fn.extend( { - find: function( selector ) { - var i, ret, - len = this.length, - self = this; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter( function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - } ) ); - } - - ret = this.pushStack( [] ); - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - return len > 1 ? jQuery.uniqueSort( ret ) : ret; - }, - filter: function( selector ) { - return this.pushStack( winnow( this, selector || [], false ) ); - }, - not: function( selector ) { - return this.pushStack( winnow( this, selector || [], true ) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -} ); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - // Shortcut simple #id case for speed - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, - - init = jQuery.fn.init = function( selector, context, root ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Method init() accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[ 0 ] === "<" && - selector[ selector.length - 1 ] === ">" && - selector.length >= 3 ) { - - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && ( match[ 1 ] || !context ) ) { - - // HANDLE: $(html) -> $(array) - if ( match[ 1 ] ) { - context = context instanceof jQuery ? context[ 0 ] : context; - - // Option to run scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[ 1 ], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - - // Properties of context are called as methods if possible - if ( isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[ 2 ] ); - - if ( elem ) { - - // Inject the element directly into the jQuery object - this[ 0 ] = elem; - this.length = 1; - } - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || root ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this[ 0 ] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( isFunction( selector ) ) { - return root.ready !== undefined ? - root.ready( selector ) : - - // Execute immediately if ready is not present - selector( jQuery ); - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - - // Methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend( { - has: function( target ) { - var targets = jQuery( target, this ), - l = targets.length; - - return this.filter( function() { - var i = 0; - for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[ i ] ) ) { - return true; - } - } - } ); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - targets = typeof selectors !== "string" && jQuery( selectors ); - - // Positional selectors never match, since there's no _selection_ context - if ( !rneedsContext.test( selectors ) ) { - for ( ; i < l; i++ ) { - for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { - - // Always skip document fragments - if ( cur.nodeType < 11 && ( targets ? - targets.index( cur ) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector( cur, selectors ) ) ) { - - matched.push( cur ); - break; - } - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); - }, - - // Determine the position of an element within the set - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; - } - - // Index in selector - if ( typeof elem === "string" ) { - return indexOf.call( jQuery( elem ), this[ 0 ] ); - } - - // Locate the position of the desired element - return indexOf.call( this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem - ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - } -} ); - -function sibling( cur, dir ) { - while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} - return cur; -} - -jQuery.each( { - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, _i, until ) { - return dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, _i, until ) { - return dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, _i, until ) { - return dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return siblings( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return siblings( elem.firstChild ); - }, - contents: function( elem ) { - if ( elem.contentDocument != null && - - // Support: IE 11+ - // elements with no `data` attribute has an object - // `contentDocument` with a `null` prototype. - getProto( elem.contentDocument ) ) { - - return elem.contentDocument; - } - - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only - // Treat the template element as a regular one in browsers that - // don't support it. - if ( nodeName( elem, "template" ) ) { - elem = elem.content || elem; - } - - return jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var matched = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - matched = jQuery.filter( selector, matched ); - } - - if ( this.length > 1 ) { - - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - jQuery.uniqueSort( matched ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - matched.reverse(); - } - } - - return this.pushStack( matched ); - }; -} ); -var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); - - - -// Convert String-formatted options into Object-formatted ones -function createOptions( options ) { - var object = {}; - jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { - object[ flag ] = true; - } ); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions( options ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - - // Last fire value for non-forgettable lists - memory, - - // Flag to know if list was already fired - fired, - - // Flag to prevent firing - locked, - - // Actual callback list - list = [], - - // Queue of execution data for repeatable lists - queue = [], - - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, - - // Fire callbacks - fire = function() { - - // Enforce single-firing - locked = locked || options.once; - - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for ( ; queue.length; firingIndex = -1 ) { - memory = queue.shift(); - while ( ++firingIndex < list.length ) { - - // Run callback and check for early termination - if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && - options.stopOnFalse ) { - - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; - } - } - } - - // Forget the data if we're done with it - if ( !options.memory ) { - memory = false; - } - - firing = false; - - // Clean up if we're done firing for good - if ( locked ) { - - // Keep an empty list if we have data for future add calls - if ( memory ) { - list = []; - - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, - - // Actual Callbacks object - self = { - - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - - // If we have memory from a past run, we should fire after adding - if ( memory && !firing ) { - firingIndex = list.length - 1; - queue.push( memory ); - } - - ( function add( args ) { - jQuery.each( args, function( _, arg ) { - if ( isFunction( arg ) ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && toType( arg ) !== "string" ) { - - // Inspect recursively - add( arg ); - } - } ); - } )( arguments ); - - if ( memory && !firing ) { - fire(); - } - } - return this; - }, - - // Remove a callback from the list - remove: function() { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - - // Handle firing indexes - if ( index <= firingIndex ) { - firingIndex--; - } - } - } ); - return this; - }, - - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? - jQuery.inArray( fn, list ) > -1 : - list.length > 0; - }, - - // Remove all callbacks from the list - empty: function() { - if ( list ) { - list = []; - } - return this; - }, - - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function() { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function() { - return !list; - }, - - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function() { - locked = queue = []; - if ( !memory && !firing ) { - list = memory = ""; - } - return this; - }, - locked: function() { - return !!locked; - }, - - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( !locked ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - queue.push( args ); - if ( !firing ) { - fire(); - } - } - return this; - }, - - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -function Identity( v ) { - return v; -} -function Thrower( ex ) { - throw ex; -} - -function adoptValue( value, resolve, reject, noValue ) { - var method; - - try { - - // Check for promise aspect first to privilege synchronous behavior - if ( value && isFunction( ( method = value.promise ) ) ) { - method.call( value ).done( resolve ).fail( reject ); - - // Other thenables - } else if ( value && isFunction( ( method = value.then ) ) ) { - method.call( value, resolve, reject ); - - // Other non-thenables - } else { - - // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: - // * false: [ value ].slice( 0 ) => resolve( value ) - // * true: [ value ].slice( 1 ) => resolve() - resolve.apply( undefined, [ value ].slice( noValue ) ); - } - - // For Promises/A+, convert exceptions into rejections - // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in - // Deferred#then to conditionally suppress rejection. - } catch ( value ) { - - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - reject.apply( undefined, [ value ] ); - } -} - -jQuery.extend( { - - Deferred: function( func ) { - var tuples = [ - - // action, add listener, callbacks, - // ... .then handlers, argument index, [final state] - [ "notify", "progress", jQuery.Callbacks( "memory" ), - jQuery.Callbacks( "memory" ), 2 ], - [ "resolve", "done", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 0, "resolved" ], - [ "reject", "fail", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 1, "rejected" ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - "catch": function( fn ) { - return promise.then( null, fn ); - }, - - // Keep pipe for back-compat - pipe: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - - return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( _i, tuple ) { - - // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; - - // deferred.progress(function() { bind to newDefer or newDefer.notify }) - // deferred.done(function() { bind to newDefer or newDefer.resolve }) - // deferred.fail(function() { bind to newDefer or newDefer.reject }) - deferred[ tuple[ 1 ] ]( function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && isFunction( returned.promise ) ) { - returned.promise() - .progress( newDefer.notify ) - .done( newDefer.resolve ) - .fail( newDefer.reject ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( - this, - fn ? [ returned ] : arguments - ); - } - } ); - } ); - fns = null; - } ).promise(); - }, - then: function( onFulfilled, onRejected, onProgress ) { - var maxDepth = 0; - function resolve( depth, deferred, handler, special ) { - return function() { - var that = this, - args = arguments, - mightThrow = function() { - var returned, then; - - // Support: Promises/A+ section 2.3.3.3.3 - // https://promisesaplus.com/#point-59 - // Ignore double-resolution attempts - if ( depth < maxDepth ) { - return; - } - - returned = handler.apply( that, args ); - - // Support: Promises/A+ section 2.3.1 - // https://promisesaplus.com/#point-48 - if ( returned === deferred.promise() ) { - throw new TypeError( "Thenable self-resolution" ); - } - - // Support: Promises/A+ sections 2.3.3.1, 3.5 - // https://promisesaplus.com/#point-54 - // https://promisesaplus.com/#point-75 - // Retrieve `then` only once - then = returned && - - // Support: Promises/A+ section 2.3.4 - // https://promisesaplus.com/#point-64 - // Only check objects and functions for thenability - ( typeof returned === "object" || - typeof returned === "function" ) && - returned.then; - - // Handle a returned thenable - if ( isFunction( then ) ) { - - // Special processors (notify) just wait for resolution - if ( special ) { - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ) - ); - - // Normal processors (resolve) also hook into progress - } else { - - // ...and disregard older resolution values - maxDepth++; - - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ), - resolve( maxDepth, deferred, Identity, - deferred.notifyWith ) - ); - } - - // Handle all other returned values - } else { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Identity ) { - that = undefined; - args = [ returned ]; - } - - // Process the value(s) - // Default process is resolve - ( special || deferred.resolveWith )( that, args ); - } - }, - - // Only normal processors (resolve) catch and reject exceptions - process = special ? - mightThrow : - function() { - try { - mightThrow(); - } catch ( e ) { - - if ( jQuery.Deferred.exceptionHook ) { - jQuery.Deferred.exceptionHook( e, - process.stackTrace ); - } - - // Support: Promises/A+ section 2.3.3.3.4.1 - // https://promisesaplus.com/#point-61 - // Ignore post-resolution exceptions - if ( depth + 1 >= maxDepth ) { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Thrower ) { - that = undefined; - args = [ e ]; - } - - deferred.rejectWith( that, args ); - } - } - }; - - // Support: Promises/A+ section 2.3.3.3.1 - // https://promisesaplus.com/#point-57 - // Re-resolve promises immediately to dodge false rejection from - // subsequent errors - if ( depth ) { - process(); - } else { - - // Call an optional hook to record the stack, in case of exception - // since it's otherwise lost when execution goes async - if ( jQuery.Deferred.getStackHook ) { - process.stackTrace = jQuery.Deferred.getStackHook(); - } - window.setTimeout( process ); - } - }; - } - - return jQuery.Deferred( function( newDefer ) { - - // progress_handlers.add( ... ) - tuples[ 0 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onProgress ) ? - onProgress : - Identity, - newDefer.notifyWith - ) - ); - - // fulfilled_handlers.add( ... ) - tuples[ 1 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onFulfilled ) ? - onFulfilled : - Identity - ) - ); - - // rejected_handlers.add( ... ) - tuples[ 2 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onRejected ) ? - onRejected : - Thrower - ) - ); - } ).promise(); - }, - - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 5 ]; - - // promise.progress = list.add - // promise.done = list.add - // promise.fail = list.add - promise[ tuple[ 1 ] ] = list.add; - - // Handle state - if ( stateString ) { - list.add( - function() { - - // state = "resolved" (i.e., fulfilled) - // state = "rejected" - state = stateString; - }, - - // rejected_callbacks.disable - // fulfilled_callbacks.disable - tuples[ 3 - i ][ 2 ].disable, - - // rejected_handlers.disable - // fulfilled_handlers.disable - tuples[ 3 - i ][ 3 ].disable, - - // progress_callbacks.lock - tuples[ 0 ][ 2 ].lock, - - // progress_handlers.lock - tuples[ 0 ][ 3 ].lock - ); - } - - // progress_handlers.fire - // fulfilled_handlers.fire - // rejected_handlers.fire - list.add( tuple[ 3 ].fire ); - - // deferred.notify = function() { deferred.notifyWith(...) } - // deferred.resolve = function() { deferred.resolveWith(...) } - // deferred.reject = function() { deferred.rejectWith(...) } - deferred[ tuple[ 0 ] ] = function() { - deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); - return this; - }; - - // deferred.notifyWith = list.fireWith - // deferred.resolveWith = list.fireWith - // deferred.rejectWith = list.fireWith - deferred[ tuple[ 0 ] + "With" ] = list.fireWith; - } ); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( singleValue ) { - var - - // count of uncompleted subordinates - remaining = arguments.length, - - // count of unprocessed arguments - i = remaining, - - // subordinate fulfillment data - resolveContexts = Array( i ), - resolveValues = slice.call( arguments ), - - // the master Deferred - master = jQuery.Deferred(), - - // subordinate callback factory - updateFunc = function( i ) { - return function( value ) { - resolveContexts[ i ] = this; - resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( !( --remaining ) ) { - master.resolveWith( resolveContexts, resolveValues ); - } - }; - }; - - // Single- and empty arguments are adopted like Promise.resolve - if ( remaining <= 1 ) { - adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, - !remaining ); - - // Use .then() to unwrap secondary thenables (cf. gh-3000) - if ( master.state() === "pending" || - isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { - - return master.then(); - } - } - - // Multiple arguments are aggregated like Promise.all array elements - while ( i-- ) { - adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); - } - - return master.promise(); - } -} ); - - -// These usually indicate a programmer mistake during development, -// warn about them ASAP rather than swallowing them by default. -var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; - -jQuery.Deferred.exceptionHook = function( error, stack ) { - - // Support: IE 8 - 9 only - // Console exists when dev tools are open, which can happen at any time - if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { - window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); - } -}; - - - - -jQuery.readyException = function( error ) { - window.setTimeout( function() { - throw error; - } ); -}; - - - - -// The deferred used on DOM ready -var readyList = jQuery.Deferred(); - -jQuery.fn.ready = function( fn ) { - - readyList - .then( fn ) - - // Wrap jQuery.readyException in a function so that the lookup - // happens at the time of error handling instead of callback - // registration. - .catch( function( error ) { - jQuery.readyException( error ); - } ); - - return this; -}; - -jQuery.extend( { - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - } -} ); - -jQuery.ready.then = readyList.then; - -// The ready event handler and self cleanup method -function completed() { - document.removeEventListener( "DOMContentLoaded", completed ); - window.removeEventListener( "load", completed ); - jQuery.ready(); -} - -// Catch cases where $(document).ready() is called -// after the browser event has already occurred. -// Support: IE <=9 - 10 only -// Older IE sometimes signals "interactive" too soon -if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { - - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout( jQuery.ready ); - -} else { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed ); -} - - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if ( toType( key ) === "object" ) { - chainable = true; - for ( i in key ) { - access( elems, fn, i, key[ i ], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, _key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < len; i++ ) { - fn( - elems[ i ], key, raw ? - value : - value.call( elems[ i ], i, fn( elems[ i ], key ) ) - ); - } - } - } - - if ( chainable ) { - return elems; - } - - // Gets - if ( bulk ) { - return fn.call( elems ); - } - - return len ? fn( elems[ 0 ], key ) : emptyGet; -}; - - -// Matches dashed string for camelizing -var rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g; - -// Used by camelCase as callback to replace() -function fcamelCase( _all, letter ) { - return letter.toUpperCase(); -} - -// Convert dashed to camelCase; used by the css and data modules -// Support: IE <=9 - 11, Edge 12 - 15 -// Microsoft forgot to hump their vendor prefix (#9572) -function camelCase( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); -} -var acceptData = function( owner ) { - - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); -}; - - - - -function Data() { - this.expando = jQuery.expando + Data.uid++; -} - -Data.uid = 1; - -Data.prototype = { - - cache: function( owner ) { - - // Check if the owner object already has a cache - var value = owner[ this.expando ]; - - // If not, create one - if ( !value ) { - value = {}; - - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return an empty object. - if ( acceptData( owner ) ) { - - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if ( owner.nodeType ) { - owner[ this.expando ] = value; - - // Otherwise secure it in a non-enumerable property - // configurable must be true to allow the property to be - // deleted when data is removed - } else { - Object.defineProperty( owner, this.expando, { - value: value, - configurable: true - } ); - } - } - } - - return value; - }, - set: function( owner, data, value ) { - var prop, - cache = this.cache( owner ); - - // Handle: [ owner, key, value ] args - // Always use camelCase key (gh-2257) - if ( typeof data === "string" ) { - cache[ camelCase( data ) ] = value; - - // Handle: [ owner, { properties } ] args - } else { - - // Copy the properties one-by-one to the cache object - for ( prop in data ) { - cache[ camelCase( prop ) ] = data[ prop ]; - } - } - return cache; - }, - get: function( owner, key ) { - return key === undefined ? - this.cache( owner ) : - - // Always use camelCase key (gh-2257) - owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; - }, - access: function( owner, key, value ) { - - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ( ( key && typeof key === "string" ) && value === undefined ) ) { - - return this.get( owner, key ); - } - - // When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, - cache = owner[ this.expando ]; - - if ( cache === undefined ) { - return; - } - - if ( key !== undefined ) { - - // Support array or space separated string of keys - if ( Array.isArray( key ) ) { - - // If key is an array of keys... - // We always set camelCase keys, so remove that. - key = key.map( camelCase ); - } else { - key = camelCase( key ); - - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - key = key in cache ? - [ key ] : - ( key.match( rnothtmlwhite ) || [] ); - } - - i = key.length; - - while ( i-- ) { - delete cache[ key[ i ] ]; - } - } - - // Remove the expando if there's no more data - if ( key === undefined || jQuery.isEmptyObject( cache ) ) { - - // Support: Chrome <=35 - 45 - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) - if ( owner.nodeType ) { - owner[ this.expando ] = undefined; - } else { - delete owner[ this.expando ]; - } - } - }, - hasData: function( owner ) { - var cache = owner[ this.expando ]; - return cache !== undefined && !jQuery.isEmptyObject( cache ); - } -}; -var dataPriv = new Data(); - -var dataUser = new Data(); - - - -// Implementation Summary -// -// 1. Enforce API surface and semantic compatibility with 1.9.x branch -// 2. Improve the module's maintainability by reducing the storage -// paths to a single mechanism. -// 3. Use the same single mechanism to support "private" and "user" data. -// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) -// 5. Avoid exposing implementation details on user objects (eg. expando properties) -// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 - -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /[A-Z]/g; - -function getData( data ) { - if ( data === "true" ) { - return true; - } - - if ( data === "false" ) { - return false; - } - - if ( data === "null" ) { - return null; - } - - // Only convert to a number if it doesn't change the string - if ( data === +data + "" ) { - return +data; - } - - if ( rbrace.test( data ) ) { - return JSON.parse( data ); - } - - return data; -} - -function dataAttr( elem, key, data ) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = getData( data ); - } catch ( e ) {} - - // Make sure we set the data so it isn't changed later - dataUser.set( elem, key, data ); - } else { - data = undefined; - } - } - return data; -} - -jQuery.extend( { - hasData: function( elem ) { - return dataUser.hasData( elem ) || dataPriv.hasData( elem ); - }, - - data: function( elem, name, data ) { - return dataUser.access( elem, name, data ); - }, - - removeData: function( elem, name ) { - dataUser.remove( elem, name ); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to dataPriv methods, these can be deprecated. - _data: function( elem, name, data ) { - return dataPriv.access( elem, name, data ); - }, - - _removeData: function( elem, name ) { - dataPriv.remove( elem, name ); - } -} ); - -jQuery.fn.extend( { - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = dataUser.get( elem ); - - if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE 11 only - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = camelCase( name.slice( 5 ) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - dataPriv.set( elem, "hasDataAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each( function() { - dataUser.set( this, key ); - } ); - } - - return access( this, function( value ) { - var data; - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { - - // Attempt to get data from the cache - // The key will always be camelCased in Data - data = dataUser.get( elem, key ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, key ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each( function() { - - // We always store the camelCased key - dataUser.set( this, key, value ); - } ); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each( function() { - dataUser.remove( this, key ); - } ); - } -} ); - - -jQuery.extend( { - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = dataPriv.get( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || Array.isArray( data ) ) { - queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // Clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // Not public - generate a queueHooks object, or return the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { - empty: jQuery.Callbacks( "once memory" ).add( function() { - dataPriv.remove( elem, [ type + "queue", key ] ); - } ) - } ); - } -} ); - -jQuery.fn.extend( { - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[ 0 ], type ); - } - - return data === undefined ? - this : - this.each( function() { - var queue = jQuery.queue( this, type, data ); - - // Ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - } ); - }, - dequeue: function( type ) { - return this.each( function() { - jQuery.dequeue( this, type ); - } ); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -} ); -var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; - -var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); - - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var documentElement = document.documentElement; - - - - var isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ); - }, - composed = { composed: true }; - - // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only - // Check attachment across shadow DOM boundaries when possible (gh-3504) - // Support: iOS 10.0-10.2 only - // Early iOS 10 versions support `attachShadow` but not `getRootNode`, - // leading to errors. We need to check for `getRootNode`. - if ( documentElement.getRootNode ) { - isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ) || - elem.getRootNode( composed ) === elem.ownerDocument; - }; - } -var isHiddenWithinTree = function( elem, el ) { - - // isHiddenWithinTree might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - - // Inline style trumps all - return elem.style.display === "none" || - elem.style.display === "" && - - // Otherwise, check computed style - // Support: Firefox <=43 - 45 - // Disconnected elements can have computed display: none, so first confirm that elem is - // in the document. - isAttached( elem ) && - - jQuery.css( elem, "display" ) === "none"; - }; - - - -function adjustCSS( elem, prop, valueParts, tween ) { - var adjusted, scale, - maxIterations = 20, - currentValue = tween ? - function() { - return tween.cur(); - } : - function() { - return jQuery.css( elem, prop, "" ); - }, - initial = currentValue(), - unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - - // Starting value computation is required for potential unit mismatches - initialInUnit = elem.nodeType && - ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && - rcssNum.exec( jQuery.css( elem, prop ) ); - - if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { - - // Support: Firefox <=54 - // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) - initial = initial / 2; - - // Trust units reported by jQuery.css - unit = unit || initialInUnit[ 3 ]; - - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; - - while ( maxIterations-- ) { - - // Evaluate and update our best guess (doubling guesses that zero out). - // Finish if the scale equals or crosses 1 (making the old*new product non-positive). - jQuery.style( elem, prop, initialInUnit + unit ); - if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { - maxIterations = 0; - } - initialInUnit = initialInUnit / scale; - - } - - initialInUnit = initialInUnit * 2; - jQuery.style( elem, prop, initialInUnit + unit ); - - // Make sure we update the tween properties later on - valueParts = valueParts || []; - } - - if ( valueParts ) { - initialInUnit = +initialInUnit || +initial || 0; - - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[ 1 ] ? - initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : - +valueParts[ 2 ]; - if ( tween ) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; -} - - -var defaultDisplayMap = {}; - -function getDefaultDisplay( elem ) { - var temp, - doc = elem.ownerDocument, - nodeName = elem.nodeName, - display = defaultDisplayMap[ nodeName ]; - - if ( display ) { - return display; - } - - temp = doc.body.appendChild( doc.createElement( nodeName ) ); - display = jQuery.css( temp, "display" ); - - temp.parentNode.removeChild( temp ); - - if ( display === "none" ) { - display = "block"; - } - defaultDisplayMap[ nodeName ] = display; - - return display; -} - -function showHide( elements, show ) { - var display, elem, - values = [], - index = 0, - length = elements.length; - - // Determine new display value for elements that need to change - for ( ; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; - } - - display = elem.style.display; - if ( show ) { - - // Since we force visibility upon cascade-hidden elements, an immediate (and slow) - // check is required in this first loop unless we have a nonempty display value (either - // inline or about-to-be-restored) - if ( display === "none" ) { - values[ index ] = dataPriv.get( elem, "display" ) || null; - if ( !values[ index ] ) { - elem.style.display = ""; - } - } - if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { - values[ index ] = getDefaultDisplay( elem ); - } - } else { - if ( display !== "none" ) { - values[ index ] = "none"; - - // Remember what we're overwriting - dataPriv.set( elem, "display", display ); - } - } - } - - // Set the display of the elements in a second loop to avoid constant reflow - for ( index = 0; index < length; index++ ) { - if ( values[ index ] != null ) { - elements[ index ].style.display = values[ index ]; - } - } - - return elements; -} - -jQuery.fn.extend( { - show: function() { - return showHide( this, true ); - }, - hide: function() { - return showHide( this ); - }, - toggle: function( state ) { - if ( typeof state === "boolean" ) { - return state ? this.show() : this.hide(); - } - - return this.each( function() { - if ( isHiddenWithinTree( this ) ) { - jQuery( this ).show(); - } else { - jQuery( this ).hide(); - } - } ); - } -} ); -var rcheckableType = ( /^(?:checkbox|radio)$/i ); - -var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); - -var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); - - - -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; - - // Support: IE <=9 only - // IE <=9 replaces "; - support.option = !!div.lastChild; -} )(); - - -// We have to close these tags to support XHTML (#13200) -var wrapMap = { - - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [ 1, "", "
    " ], - col: [ 2, "", "
    " ], - tr: [ 2, "", "
    " ], - td: [ 3, "", "
    " ], - - _default: [ 0, "", "" ] -}; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// Support: IE <=9 only -if ( !support.option ) { - wrapMap.optgroup = wrapMap.option = [ 1, "" ]; -} - - -function getAll( context, tag ) { - - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (#15151) - var ret; - - if ( typeof context.getElementsByTagName !== "undefined" ) { - ret = context.getElementsByTagName( tag || "*" ); - - } else if ( typeof context.querySelectorAll !== "undefined" ) { - ret = context.querySelectorAll( tag || "*" ); - - } else { - ret = []; - } - - if ( tag === undefined || tag && nodeName( context, tag ) ) { - return jQuery.merge( [ context ], ret ); - } - - return ret; -} - - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - dataPriv.set( - elems[ i ], - "globalEval", - !refElements || dataPriv.get( refElements[ i ], "globalEval" ) - ); - } -} - - -var rhtml = /<|&#?\w+;/; - -function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, attached, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( toType( elem ) === "object" ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { - - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); - } - continue; - } - - attached = isAttached( elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( attached ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; -} - - -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -// Support: IE <=9 - 11+ -// focus() and blur() are asynchronous, except when they are no-op. -// So expect focus to be synchronous when the element is already active, -// and blur to be synchronous when the element is not already active. -// (focus and blur are always synchronous in other supported browsers, -// this just defines when we can count on it). -function expectSync( elem, type ) { - return ( elem === safeActiveElement() ) === ( type === "focus" ); -} - -// Support: IE <=9 only -// Accessing document.activeElement can throw unexpectedly -// https://bugs.jquery.com/ticket/13393 -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -function on( elem, types, selector, data, fn, one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); - } - return elem; - } - - if ( data == null && fn == null ) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return elem; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get( elem ); - - // Only attach events to objects that accept data - if ( !acceptData( elem ) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if ( selector ) { - jQuery.find.matchesSelector( documentElement, selector ); - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = Object.create( null ); - } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - - if ( !elemData || !( events = elemData.events ) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove data and the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - dataPriv.remove( elem, "handle events" ); - } - }, - - dispatch: function( nativeEvent ) { - - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array( arguments.length ), - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( nativeEvent ), - - handlers = ( - dataPriv.get( this, "events" ) || Object.create( null ) - )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; - - for ( i = 1; i < arguments.length; i++ ) { - args[ i ] = arguments[ i ]; - } - - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { - - // If the event is namespaced, then each handler is only invoked if it is - // specially universal or its namespaces are a superset of the event's. - if ( !event.rnamespace || handleObj.namespace === false || - event.rnamespace.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - if ( delegateCount && - - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !( event.type === "click" && event.button >= 1 ) ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { - matchedHandlers = []; - matchedSelectors = {}; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matchedSelectors[ sel ] === undefined ) { - matchedSelectors[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matchedSelectors[ sel ] ) { - matchedHandlers.push( handleObj ); - } - } - if ( matchedHandlers.length ) { - handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); - } - } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, - - addProp: function( name, hook ) { - Object.defineProperty( jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, - - get: isFunction( hook ) ? - function() { - if ( this.originalEvent ) { - return hook( this.originalEvent ); - } - } : - function() { - if ( this.originalEvent ) { - return this.originalEvent[ name ]; - } - }, - - set: function( value ) { - Object.defineProperty( this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value - } ); - } - } ); - }, - - fix: function( originalEvent ) { - return originalEvent[ jQuery.expando ] ? - originalEvent : - new jQuery.Event( originalEvent ); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - click: { - - // Utilize native event to ensure correct state for checkable inputs - setup: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Claim the first handler - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - // dataPriv.set( el, "click", ... ) - leverageNative( el, "click", returnTrue ); - } - - // Return false to allow normal processing in the caller - return false; - }, - trigger: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Force setup before triggering a click - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - leverageNative( el, "click" ); - } - - // Return non-false to allow normal event-path propagation - return true; - }, - - // For cross-browser consistency, suppress native .click() on links - // Also prevent it if we're currently inside a leveraged native-event stack - _default: function( event ) { - var target = event.target; - return rcheckableType.test( target.type ) && - target.click && nodeName( target, "input" ) && - dataPriv.get( target, "click" ) || - nodeName( target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - } -}; - -// Ensure the presence of an event listener that handles manually-triggered -// synthetic events by interrupting progress until reinvoked in response to -// *native* events that it fires directly, ensuring that state changes have -// already occurred before other listeners are invoked. -function leverageNative( el, type, expectSync ) { - - // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add - if ( !expectSync ) { - if ( dataPriv.get( el, type ) === undefined ) { - jQuery.event.add( el, type, returnTrue ); - } - return; - } - - // Register the controller as a special universal handler for all event namespaces - dataPriv.set( el, type, false ); - jQuery.event.add( el, type, { - namespace: false, - handler: function( event ) { - var notAsync, result, - saved = dataPriv.get( this, type ); - - if ( ( event.isTrigger & 1 ) && this[ type ] ) { - - // Interrupt processing of the outer synthetic .trigger()ed event - // Saved data should be false in such cases, but might be a leftover capture object - // from an async native handler (gh-4350) - if ( !saved.length ) { - - // Store arguments for use when handling the inner native event - // There will always be at least one argument (an event object), so this array - // will not be confused with a leftover capture object. - saved = slice.call( arguments ); - dataPriv.set( this, type, saved ); - - // Trigger the native event and capture its result - // Support: IE <=9 - 11+ - // focus() and blur() are asynchronous - notAsync = expectSync( this, type ); - this[ type ](); - result = dataPriv.get( this, type ); - if ( saved !== result || notAsync ) { - dataPriv.set( this, type, false ); - } else { - result = {}; - } - if ( saved !== result ) { - - // Cancel the outer synthetic event - event.stopImmediatePropagation(); - event.preventDefault(); - return result.value; - } - - // If this is an inner synthetic event for an event with a bubbling surrogate - // (focus or blur), assume that the surrogate already propagated from triggering the - // native event and prevent that from happening again here. - // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the - // bubbling surrogate propagates *after* the non-bubbling base), but that seems - // less bad than duplication. - } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { - event.stopPropagation(); - } - - // If this is a native event triggered above, everything is now in order - // Fire an inner synthetic event with the original arguments - } else if ( saved.length ) { - - // ...and capture the result - dataPriv.set( this, type, { - value: jQuery.event.trigger( - - // Support: IE <=9 - 11+ - // Extend with the prototype to reset the above stopImmediatePropagation() - jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), - saved.slice( 1 ), - this - ) - } ); - - // Abort handling of the native event - event.stopImmediatePropagation(); - } - } - } ); -} - -jQuery.removeEvent = function( elem, type, handle ) { - - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } -}; - -jQuery.Event = function( src, props ) { - - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; - - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (#504, #13143) - this.target = ( src.target && src.target.nodeType === 3 ) ? - src.target.parentNode : - src.target; - - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || Date.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && !this.isSimulated ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Includes all common event props including KeyEvent and MouseEvent specific props -jQuery.each( { - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - code: true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - - which: function( event ) { - var button = event.button; - - // Add which for key events - if ( event.which == null && rkeyEvent.test( event.type ) ) { - return event.charCode != null ? event.charCode : event.keyCode; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { - if ( button & 1 ) { - return 1; - } - - if ( button & 2 ) { - return 3; - } - - if ( button & 4 ) { - return 2; - } - - return 0; - } - - return event.which; - } -}, jQuery.event.addProp ); - -jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { - jQuery.event.special[ type ] = { - - // Utilize native event if possible so blur/focus sequence is correct - setup: function() { - - // Claim the first handler - // dataPriv.set( this, "focus", ... ) - // dataPriv.set( this, "blur", ... ) - leverageNative( this, type, expectSync ); - - // Return false to allow normal processing in the caller - return false; - }, - trigger: function() { - - // Force setup before trigger - leverageNative( this, type ); - - // Return non-false to allow normal event-path propagation - return true; - }, - - delegateType: delegateType - }; -} ); - -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -} ); - -jQuery.fn.extend( { - - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); - } ); - } -} ); - - -var - - // Support: IE <=10 - 11, Edge 12 - 13 only - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; - -// Prefer a tbody over its parent table for containing new rows -function manipulationTarget( elem, content ) { - if ( nodeName( elem, "table" ) && - nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - - return jQuery( elem ).children( "tbody" )[ 0 ] || elem; - } - - return elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { - elem.type = elem.type.slice( 5 ); - } else { - elem.removeAttribute( "type" ); - } - - return elem; -} - -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.get( src ); - events = pdataOld.events; - - if ( events ) { - dataPriv.remove( dest, "handle events" ); - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( dataUser.hasData( src ) ) { - udataOld = dataUser.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - dataUser.set( dest, udataCur ); - } -} - -// Fix IE bugs, see support tests -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -function domManip( collection, args, callback, ignored ) { - - // Flatten any nested arrays - args = flat( args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - valueIsFunction = isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( valueIsFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( valueIsFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } - - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( collection[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !dataPriv.access( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { - - if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { - - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl && !node.noModule ) { - jQuery._evalUrl( node.src, { - nonce: node.nonce || node.getAttribute( "nonce" ) - }, doc ); - } - } else { - DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); - } - } - } - } - } - } - - return collection; -} - -function remove( elem, selector, keepData ) { - var node, - nodes = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; - - for ( ; ( node = nodes[ i ] ) != null; i++ ) { - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); - } - - if ( node.parentNode ) { - if ( keepData && isAttached( node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } - } - - return elem; -} - -jQuery.extend( { - htmlPrefilter: function( html ) { - return html; - }, - - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = isAttached( elem ); - - // Fix IE cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - cleanData: function( elems ) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { - if ( acceptData( elem ) ) { - if ( ( data = elem[ dataPriv.expando ] ) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataPriv.expando ] = undefined; - } - if ( elem[ dataUser.expando ] ) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataUser.expando ] = undefined; - } - } - } - } -} ); - -jQuery.fn.extend( { - detach: function( selector ) { - return remove( this, selector, true ); - }, - - remove: function( selector ) { - return remove( this, selector ); - }, - - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each( function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - } ); - }, null, value, arguments.length ); - }, - - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, - - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - } ); - }, - - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - } ); - }, - - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, - - empty: function() { - var elem, - i = 0; - - for ( ; ( elem = this[ i ] ) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = jQuery.htmlPrefilter( value ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; - - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); - } - } - - // Force callback invocation - }, ignored ); - } -} ); - -jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -} ); -var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); - -var getStyles = function( elem ) { - - // Support: IE <=11 only, Firefox <=30 (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; - - if ( !view || !view.opener ) { - view = window; - } - - return view.getComputedStyle( elem ); - }; - -var swap = function( elem, options, callback ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.call( elem ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - - -var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); - - - -( function() { - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { - - // This is a singleton, we need to execute it only once - if ( !div ) { - return; - } - - container.style.cssText = "position:absolute;left:-11111px;width:60px;" + - "margin-top:1px;padding:0;border:0"; - div.style.cssText = - "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + - "margin:auto;border:1px;padding:1px;" + - "width:60%;top:1%"; - documentElement.appendChild( container ).appendChild( div ); - - var divStyle = window.getComputedStyle( div ); - pixelPositionVal = divStyle.top !== "1%"; - - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; - - // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 - // Some styles come back with percentage values, even though they shouldn't - div.style.right = "60%"; - pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; - - // Support: IE 9 - 11 only - // Detect misreporting of content dimensions for box-sizing:border-box elements - boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; - - // Support: IE 9 only - // Detect overflow:scroll screwiness (gh-3699) - // Support: Chrome <=64 - // Don't get tricked when zoom affects offsetWidth (gh-4029) - div.style.position = "absolute"; - scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; - - documentElement.removeChild( container ); - - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; - } - - function roundPixelMeasures( measure ) { - return Math.round( parseFloat( measure ) ); - } - - var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, - reliableTrDimensionsVal, reliableMarginLeftVal, - container = document.createElement( "div" ), - div = document.createElement( "div" ); - - // Finish early in limited (non-browser) environments - if ( !div.style ) { - return; - } - - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (#8908) - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - jQuery.extend( support, { - boxSizingReliable: function() { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelBoxStyles: function() { - computeStyleTests(); - return pixelBoxStylesVal; - }, - pixelPosition: function() { - computeStyleTests(); - return pixelPositionVal; - }, - reliableMarginLeft: function() { - computeStyleTests(); - return reliableMarginLeftVal; - }, - scrollboxSize: function() { - computeStyleTests(); - return scrollboxSizeVal; - }, - - // Support: IE 9 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Behavior in IE 9 is more subtle than in newer versions & it passes - // some versions of this test; make sure not to make it pass there! - reliableTrDimensions: function() { - var table, tr, trChild, trStyle; - if ( reliableTrDimensionsVal == null ) { - table = document.createElement( "table" ); - tr = document.createElement( "tr" ); - trChild = document.createElement( "div" ); - - table.style.cssText = "position:absolute;left:-11111px"; - tr.style.height = "1px"; - trChild.style.height = "9px"; - - documentElement - .appendChild( table ) - .appendChild( tr ) - .appendChild( trChild ); - - trStyle = window.getComputedStyle( tr ); - reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; - - documentElement.removeChild( table ); - } - return reliableTrDimensionsVal; - } - } ); -} )(); - - -function curCSS( elem, name, computed ) { - var width, minWidth, maxWidth, ret, - - // Support: Firefox 51+ - // Retrieving style before computed somehow - // fixes an issue with getting wrong values - // on detached elements - style = elem.style; - - computed = computed || getStyles( elem ); - - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, #12537) - // .css('--customProperty) (#3144) - if ( computed ) { - ret = computed.getPropertyValue( name ) || computed[ name ]; - - if ( ret === "" && !isAttached( elem ) ) { - ret = jQuery.style( elem, name ); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret !== undefined ? - - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; -} - - -function addGetHookIf( conditionFn, hookFn ) { - - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function() { - if ( conditionFn() ) { - - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; - return; - } - - // Hook needed; redefine it so that the support test is not executed again. - return ( this.get = hookFn ).apply( this, arguments ); - } - }; -} - - -var cssPrefixes = [ "Webkit", "Moz", "ms" ], - emptyStyle = document.createElement( "div" ).style, - vendorProps = {}; - -// Return a vendor-prefixed property or undefined -function vendorPropName( name ) { - - // Check for vendor prefixed names - var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in emptyStyle ) { - return name; - } - } -} - -// Return a potentially-mapped jQuery.cssProps or vendor prefixed property -function finalPropName( name ) { - var final = jQuery.cssProps[ name ] || vendorProps[ name ]; - - if ( final ) { - return final; - } - if ( name in emptyStyle ) { - return name; - } - return vendorProps[ name ] = vendorPropName( name ) || name; -} - - -var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rcustomProp = /^--/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }; - -function setPositiveNumber( _elem, value, subtract ) { - - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec( value ); - return matches ? - - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : - value; -} - -function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { - var i = dimension === "width" ? 1 : 0, - extra = 0, - delta = 0; - - // Adjustment may not be necessary - if ( box === ( isBorderBox ? "border" : "content" ) ) { - return 0; - } - - for ( ; i < 4; i += 2 ) { - - // Both box models exclude margin - if ( box === "margin" ) { - delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); - } - - // If we get here with a content-box, we're seeking "padding" or "border" or "margin" - if ( !isBorderBox ) { - - // Add padding - delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - - // For "border" or "margin", add border - if ( box !== "padding" ) { - delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - - // But still keep track of it otherwise - } else { - extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - - // If we get here with a border-box (content + padding + border), we're seeking "content" or - // "padding" or "margin" - } else { - - // For "content", subtract padding - if ( box === "content" ) { - delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - } - - // For "content" or "padding", subtract border - if ( box !== "margin" ) { - delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } - } - - // Account for positive content-box scroll gutter when requested by providing computedVal - if ( !isBorderBox && computedVal >= 0 ) { - - // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border - // Assuming integer scroll gutter, subtract the rest and round down - delta += Math.max( 0, Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - computedVal - - delta - - extra - - 0.5 - - // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter - // Use an explicit zero to avoid NaN (gh-3964) - ) ) || 0; - } - - return delta; -} - -function getWidthOrHeight( elem, dimension, extra ) { - - // Start with computed style - var styles = getStyles( elem ), - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). - // Fake content-box until we know it's needed to know the true value. - boxSizingNeeded = !support.boxSizingReliable() || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - valueIsBorderBox = isBorderBox, - - val = curCSS( elem, dimension, styles ), - offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); - - // Support: Firefox <=54 - // Return a confounding non-pixel value or feign ignorance, as appropriate. - if ( rnumnonpx.test( val ) ) { - if ( !extra ) { - return val; - } - val = "auto"; - } - - - // Support: IE 9 - 11 only - // Use offsetWidth/offsetHeight for when box sizing is unreliable. - // In those cases, the computed value can be trusted to be border-box. - if ( ( !support.boxSizingReliable() && isBorderBox || - - // Support: IE 10 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Interestingly, in some cases IE 9 doesn't suffer from this issue. - !support.reliableTrDimensions() && nodeName( elem, "tr" ) || - - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - val === "auto" || - - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && - - // Make sure the element is visible & connected - elem.getClientRects().length ) { - - isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - - // Where available, offsetWidth/offsetHeight approximate border box dimensions. - // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the - // retrieved value as a content box dimension. - valueIsBorderBox = offsetProp in elem; - if ( valueIsBorderBox ) { - val = elem[ offsetProp ]; - } - } - - // Normalize "" and auto - val = parseFloat( val ) || 0; - - // Adjust for the element's box model - return ( val + - boxModelAdjustment( - elem, - dimension, - extra || ( isBorderBox ? "border" : "content" ), - valueIsBorderBox, - styles, - - // Provide the current computed size to request scroll gutter calculation (gh-3589) - val - ) - ) + "px"; -} - -jQuery.extend( { - - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function( elem, computed ) { - if ( computed ) { - - // We should always get a number back from opacity - var ret = curCSS( elem, "opacity" ); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "animationIterationCount": true, - "columnCount": true, - "fillOpacity": true, - "flexGrow": true, - "flexShrink": true, - "fontWeight": true, - "gridArea": true, - "gridColumn": true, - "gridColumnEnd": true, - "gridColumnStart": true, - "gridRow": true, - "gridRowEnd": true, - "gridRowStart": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: {}, - - // Get and set the style property on a DOM Node - style: function( elem, name, value, extra ) { - - // Don't set styles on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ), - style = elem.style; - - // Make sure that we're working with the right name. We don't - // want to query the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; - - // Convert "+=" or "-=" to relative numbers (#7345) - if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { - value = adjustCSS( elem, name, ret ); - - // Fixes bug #9237 - type = "number"; - } - - // Make sure that null and NaN values aren't set (#7116) - if ( value == null || value !== value ) { - return; - } - - // If a number was passed in, add the unit (except for certain CSS properties) - // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append - // "px" to a few hardcoded values. - if ( type === "number" && !isCustomProp ) { - value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); - } - - // background-* props affect original clone's values - if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { - style[ name ] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !( "set" in hooks ) || - ( value = hooks.set( elem, value, extra ) ) !== undefined ) { - - if ( isCustomProp ) { - style.setProperty( name, value ); - } else { - style[ name ] = value; - } - } - - } else { - - // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && - ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { - - return ret; - } - - // Otherwise just get the value from the style object - return style[ name ]; - } - }, - - css: function( elem, name, extra, styles ) { - var val, num, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ); - - // Make sure that we're working with the right name. We don't - // want to modify the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); - } - - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); - } - - // Convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - - // Make numeric if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || isFinite( num ) ? num || 0 : val; - } - - return val; - } -} ); - -jQuery.each( [ "height", "width" ], function( _i, dimension ) { - jQuery.cssHooks[ dimension ] = { - get: function( elem, computed, extra ) { - if ( computed ) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? - swap( elem, cssShow, function() { - return getWidthOrHeight( elem, dimension, extra ); - } ) : - getWidthOrHeight( elem, dimension, extra ); - } - }, - - set: function( elem, value, extra ) { - var matches, - styles = getStyles( elem ), - - // Only read styles.position if the test has a chance to fail - // to avoid forcing a reflow. - scrollboxSizeBuggy = !support.scrollboxSize() && - styles.position === "absolute", - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) - boxSizingNeeded = scrollboxSizeBuggy || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - subtract = extra ? - boxModelAdjustment( - elem, - dimension, - extra, - isBorderBox, - styles - ) : - 0; - - // Account for unreliable border-box dimensions by comparing offset* to computed and - // faking a content-box to get border and padding (gh-3699) - if ( isBorderBox && scrollboxSizeBuggy ) { - subtract -= Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - parseFloat( styles[ dimension ] ) - - boxModelAdjustment( elem, dimension, "border", false, styles ) - - 0.5 - ); - } - - // Convert to pixels if value adjustment is needed - if ( subtract && ( matches = rcssNum.exec( value ) ) && - ( matches[ 3 ] || "px" ) !== "px" ) { - - elem.style[ dimension ] = value; - value = jQuery.css( elem, dimension ); - } - - return setPositiveNumber( elem, value, subtract ); - } - }; -} ); - -jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, - function( elem, computed ) { - if ( computed ) { - return ( parseFloat( curCSS( elem, "marginLeft" ) ) || - elem.getBoundingClientRect().left - - swap( elem, { marginLeft: 0 }, function() { - return elem.getBoundingClientRect().left; - } ) - ) + "px"; - } - } -); - -// These hooks are used by animate to expand properties -jQuery.each( { - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i = 0, - expanded = {}, - - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split( " " ) : [ value ]; - - for ( ; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } - - return expanded; - } - }; - - if ( prefix !== "margin" ) { - jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; - } -} ); - -jQuery.fn.extend( { - css: function( name, value ) { - return access( this, function( elem, name, value ) { - var styles, len, - map = {}, - i = 0; - - if ( Array.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; - - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - - return map; - } - - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); - } -} ); - - -function Tween( elem, options, prop, end, easing ) { - return new Tween.prototype.init( elem, options, prop, end, easing ); -} -jQuery.Tween = Tween; - -Tween.prototype = { - constructor: Tween, - init: function( elem, options, prop, end, easing, unit ) { - this.elem = elem; - this.prop = prop; - this.easing = easing || jQuery.easing._default; - this.options = options; - this.start = this.now = this.cur(); - this.end = end; - this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); - }, - cur: function() { - var hooks = Tween.propHooks[ this.prop ]; - - return hooks && hooks.get ? - hooks.get( this ) : - Tween.propHooks._default.get( this ); - }, - run: function( percent ) { - var eased, - hooks = Tween.propHooks[ this.prop ]; - - if ( this.options.duration ) { - this.pos = eased = jQuery.easing[ this.easing ]( - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } else { - this.pos = eased = percent; - } - this.now = ( this.end - this.start ) * eased + this.start; - - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); - } - - if ( hooks && hooks.set ) { - hooks.set( this ); - } else { - Tween.propHooks._default.set( this ); - } - return this; - } -}; - -Tween.prototype.init.prototype = Tween.prototype; - -Tween.propHooks = { - _default: { - get: function( tween ) { - var result; - - // Use a property on the element directly when it is not a DOM element, - // or when there is no matching style property that exists. - if ( tween.elem.nodeType !== 1 || - tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { - return tween.elem[ tween.prop ]; - } - - // Passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails. - // Simple values such as "10px" are parsed to Float; - // complex values such as "rotate(1rad)" are returned as-is. - result = jQuery.css( tween.elem, tween.prop, "" ); - - // Empty strings, null, undefined and "auto" are converted to 0. - return !result || result === "auto" ? 0 : result; - }, - set: function( tween ) { - - // Use step hook for back compat. - // Use cssHook if its there. - // Use .style if available and use plain properties where available. - if ( jQuery.fx.step[ tween.prop ] ) { - jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.nodeType === 1 && ( - jQuery.cssHooks[ tween.prop ] || - tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { - jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); - } else { - tween.elem[ tween.prop ] = tween.now; - } - } - } -}; - -// Support: IE <=9 only -// Panic based approach to setting things on disconnected nodes -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; - -jQuery.easing = { - linear: function( p ) { - return p; - }, - swing: function( p ) { - return 0.5 - Math.cos( p * Math.PI ) / 2; - }, - _default: "swing" -}; - -jQuery.fx = Tween.prototype.init; - -// Back compat <1.8 extension point -jQuery.fx.step = {}; - - - - -var - fxNow, inProgress, - rfxtypes = /^(?:toggle|show|hide)$/, - rrun = /queueHooks$/; - -function schedule() { - if ( inProgress ) { - if ( document.hidden === false && window.requestAnimationFrame ) { - window.requestAnimationFrame( schedule ); - } else { - window.setTimeout( schedule, jQuery.fx.interval ); - } - - jQuery.fx.tick(); - } -} - -// Animations created synchronously will run synchronously -function createFxNow() { - window.setTimeout( function() { - fxNow = undefined; - } ); - return ( fxNow = Date.now() ); -} - -// Generate parameters to create a standard animation -function genFx( type, includeWidth ) { - var which, - i = 0, - attrs = { height: type }; - - // If we include width, step value is 1 to do all cssExpand values, - // otherwise step value is 2 to skip over Left and Right - includeWidth = includeWidth ? 1 : 0; - for ( ; i < 4; i += 2 - includeWidth ) { - which = cssExpand[ i ]; - attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; - } - - if ( includeWidth ) { - attrs.opacity = attrs.width = type; - } - - return attrs; -} - -function createTween( value, prop, animation ) { - var tween, - collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), - index = 0, - length = collection.length; - for ( ; index < length; index++ ) { - if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { - - // We're done with this property - return tween; - } - } -} - -function defaultPrefilter( elem, props, opts ) { - var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, - isBox = "width" in props || "height" in props, - anim = this, - orig = {}, - style = elem.style, - hidden = elem.nodeType && isHiddenWithinTree( elem ), - dataShow = dataPriv.get( elem, "fxshow" ); - - // Queue-skipping animations hijack the fx hooks - if ( !opts.queue ) { - hooks = jQuery._queueHooks( elem, "fx" ); - if ( hooks.unqueued == null ) { - hooks.unqueued = 0; - oldfire = hooks.empty.fire; - hooks.empty.fire = function() { - if ( !hooks.unqueued ) { - oldfire(); - } - }; - } - hooks.unqueued++; - - anim.always( function() { - - // Ensure the complete handler is called before this completes - anim.always( function() { - hooks.unqueued--; - if ( !jQuery.queue( elem, "fx" ).length ) { - hooks.empty.fire(); - } - } ); - } ); - } - - // Detect show/hide animations - for ( prop in props ) { - value = props[ prop ]; - if ( rfxtypes.test( value ) ) { - delete props[ prop ]; - toggle = toggle || value === "toggle"; - if ( value === ( hidden ? "hide" : "show" ) ) { - - // Pretend to be hidden if this is a "show" and - // there is still data from a stopped show/hide - if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { - hidden = true; - - // Ignore all other no-op show/hide data - } else { - continue; - } - } - orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); - } - } - - // Bail out if this is a no-op like .hide().hide() - propTween = !jQuery.isEmptyObject( props ); - if ( !propTween && jQuery.isEmptyObject( orig ) ) { - return; - } - - // Restrict "overflow" and "display" styles during box animations - if ( isBox && elem.nodeType === 1 ) { - - // Support: IE <=9 - 11, Edge 12 - 15 - // Record all 3 overflow attributes because IE does not infer the shorthand - // from identically-valued overflowX and overflowY and Edge just mirrors - // the overflowX value there. - opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; - - // Identify a display type, preferring old show/hide data over the CSS cascade - restoreDisplay = dataShow && dataShow.display; - if ( restoreDisplay == null ) { - restoreDisplay = dataPriv.get( elem, "display" ); - } - display = jQuery.css( elem, "display" ); - if ( display === "none" ) { - if ( restoreDisplay ) { - display = restoreDisplay; - } else { - - // Get nonempty value(s) by temporarily forcing visibility - showHide( [ elem ], true ); - restoreDisplay = elem.style.display || restoreDisplay; - display = jQuery.css( elem, "display" ); - showHide( [ elem ] ); - } - } - - // Animate inline elements as inline-block - if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { - if ( jQuery.css( elem, "float" ) === "none" ) { - - // Restore the original display value at the end of pure show/hide animations - if ( !propTween ) { - anim.done( function() { - style.display = restoreDisplay; - } ); - if ( restoreDisplay == null ) { - display = style.display; - restoreDisplay = display === "none" ? "" : display; - } - } - style.display = "inline-block"; - } - } - } - - if ( opts.overflow ) { - style.overflow = "hidden"; - anim.always( function() { - style.overflow = opts.overflow[ 0 ]; - style.overflowX = opts.overflow[ 1 ]; - style.overflowY = opts.overflow[ 2 ]; - } ); - } - - // Implement show/hide animations - propTween = false; - for ( prop in orig ) { - - // General show/hide setup for this element animation - if ( !propTween ) { - if ( dataShow ) { - if ( "hidden" in dataShow ) { - hidden = dataShow.hidden; - } - } else { - dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); - } - - // Store hidden/visible for toggle so `.stop().toggle()` "reverses" - if ( toggle ) { - dataShow.hidden = !hidden; - } - - // Show elements before animating them - if ( hidden ) { - showHide( [ elem ], true ); - } - - /* eslint-disable no-loop-func */ - - anim.done( function() { - - /* eslint-enable no-loop-func */ - - // The final step of a "hide" animation is actually hiding the element - if ( !hidden ) { - showHide( [ elem ] ); - } - dataPriv.remove( elem, "fxshow" ); - for ( prop in orig ) { - jQuery.style( elem, prop, orig[ prop ] ); - } - } ); - } - - // Per-property setup - propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); - if ( !( prop in dataShow ) ) { - dataShow[ prop ] = propTween.start; - if ( hidden ) { - propTween.end = propTween.start; - propTween.start = 0; - } - } - } -} - -function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; - - // camelCase, specialEasing and expand cssHook pass - for ( index in props ) { - name = camelCase( index ); - easing = specialEasing[ name ]; - value = props[ index ]; - if ( Array.isArray( value ) ) { - easing = value[ 1 ]; - value = props[ index ] = value[ 0 ]; - } - - if ( index !== name ) { - props[ name ] = value; - delete props[ index ]; - } - - hooks = jQuery.cssHooks[ name ]; - if ( hooks && "expand" in hooks ) { - value = hooks.expand( value ); - delete props[ name ]; - - // Not quite $.extend, this won't overwrite existing keys. - // Reusing 'index' because we have the correct "name" - for ( index in value ) { - if ( !( index in props ) ) { - props[ index ] = value[ index ]; - specialEasing[ index ] = easing; - } - } - } else { - specialEasing[ name ] = easing; - } - } -} - -function Animation( elem, properties, options ) { - var result, - stopped, - index = 0, - length = Animation.prefilters.length, - deferred = jQuery.Deferred().always( function() { - - // Don't match elem in the :animated selector - delete tick.elem; - } ), - tick = function() { - if ( stopped ) { - return false; - } - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - - // Support: Android 2.3 only - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, - index = 0, - length = animation.tweens.length; - - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( percent ); - } - - deferred.notifyWith( elem, [ animation, percent, remaining ] ); - - // If there's more to do, yield - if ( percent < 1 && length ) { - return remaining; - } - - // If this was an empty animation, synthesize a final progress notification - if ( !length ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - } - - // Resolve the animation and report its conclusion - deferred.resolveWith( elem, [ animation ] ); - return false; - }, - animation = deferred.promise( { - elem: elem, - props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { - specialEasing: {}, - easing: jQuery.easing._default - }, options ), - originalProperties: properties, - originalOptions: options, - startTime: fxNow || createFxNow(), - duration: options.duration, - tweens: [], - createTween: function( prop, end ) { - var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); - animation.tweens.push( tween ); - return tween; - }, - stop: function( gotoEnd ) { - var index = 0, - - // If we are going to the end, we want to run all the tweens - // otherwise we skip this part - length = gotoEnd ? animation.tweens.length : 0; - if ( stopped ) { - return this; - } - stopped = true; - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( 1 ); - } - - // Resolve when we played the last frame; otherwise, reject - if ( gotoEnd ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - deferred.resolveWith( elem, [ animation, gotoEnd ] ); - } else { - deferred.rejectWith( elem, [ animation, gotoEnd ] ); - } - return this; - } - } ), - props = animation.props; - - propFilter( props, animation.opts.specialEasing ); - - for ( ; index < length; index++ ) { - result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); - if ( result ) { - if ( isFunction( result.stop ) ) { - jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = - result.stop.bind( result ); - } - return result; - } - } - - jQuery.map( props, createTween, animation ); - - if ( isFunction( animation.opts.start ) ) { - animation.opts.start.call( elem, animation ); - } - - // Attach callbacks from options - animation - .progress( animation.opts.progress ) - .done( animation.opts.done, animation.opts.complete ) - .fail( animation.opts.fail ) - .always( animation.opts.always ); - - jQuery.fx.timer( - jQuery.extend( tick, { - elem: elem, - anim: animation, - queue: animation.opts.queue - } ) - ); - - return animation; -} - -jQuery.Animation = jQuery.extend( Animation, { - - tweeners: { - "*": [ function( prop, value ) { - var tween = this.createTween( prop, value ); - adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); - return tween; - } ] - }, - - tweener: function( props, callback ) { - if ( isFunction( props ) ) { - callback = props; - props = [ "*" ]; - } else { - props = props.match( rnothtmlwhite ); - } - - var prop, - index = 0, - length = props.length; - - for ( ; index < length; index++ ) { - prop = props[ index ]; - Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; - Animation.tweeners[ prop ].unshift( callback ); - } - }, - - prefilters: [ defaultPrefilter ], - - prefilter: function( callback, prepend ) { - if ( prepend ) { - Animation.prefilters.unshift( callback ); - } else { - Animation.prefilters.push( callback ); - } - } -} ); - -jQuery.speed = function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { - complete: fn || !fn && easing || - isFunction( speed ) && speed, - duration: speed, - easing: fn && easing || easing && !isFunction( easing ) && easing - }; - - // Go to the end state if fx are off - if ( jQuery.fx.off ) { - opt.duration = 0; - - } else { - if ( typeof opt.duration !== "number" ) { - if ( opt.duration in jQuery.fx.speeds ) { - opt.duration = jQuery.fx.speeds[ opt.duration ]; - - } else { - opt.duration = jQuery.fx.speeds._default; - } - } - } - - // Normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { - opt.queue = "fx"; - } - - // Queueing - opt.old = opt.complete; - - opt.complete = function() { - if ( isFunction( opt.old ) ) { - opt.old.call( this ); - } - - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); - } - }; - - return opt; -}; - -jQuery.fn.extend( { - fadeTo: function( speed, to, easing, callback ) { - - // Show any hidden elements after setting opacity to 0 - return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() - - // Animate to the value specified - .end().animate( { opacity: to }, speed, easing, callback ); - }, - animate: function( prop, speed, easing, callback ) { - var empty = jQuery.isEmptyObject( prop ), - optall = jQuery.speed( speed, easing, callback ), - doAnimation = function() { - - // Operate on a copy of prop so per-property easing won't be lost - var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations, or finishing resolves immediately - if ( empty || dataPriv.get( this, "finish" ) ) { - anim.stop( true ); - } - }; - doAnimation.finish = doAnimation; - - return empty || optall.queue === false ? - this.each( doAnimation ) : - this.queue( optall.queue, doAnimation ); - }, - stop: function( type, clearQueue, gotoEnd ) { - var stopQueue = function( hooks ) { - var stop = hooks.stop; - delete hooks.stop; - stop( gotoEnd ); - }; - - if ( typeof type !== "string" ) { - gotoEnd = clearQueue; - clearQueue = type; - type = undefined; - } - if ( clearQueue ) { - this.queue( type || "fx", [] ); - } - - return this.each( function() { - var dequeue = true, - index = type != null && type + "queueHooks", - timers = jQuery.timers, - data = dataPriv.get( this ); - - if ( index ) { - if ( data[ index ] && data[ index ].stop ) { - stopQueue( data[ index ] ); - } - } else { - for ( index in data ) { - if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { - stopQueue( data[ index ] ); - } - } - } - - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && - ( type == null || timers[ index ].queue === type ) ) { - - timers[ index ].anim.stop( gotoEnd ); - dequeue = false; - timers.splice( index, 1 ); - } - } - - // Start the next in the queue if the last step wasn't forced. - // Timers currently will call their complete callbacks, which - // will dequeue but only if they were gotoEnd. - if ( dequeue || !gotoEnd ) { - jQuery.dequeue( this, type ); - } - } ); - }, - finish: function( type ) { - if ( type !== false ) { - type = type || "fx"; - } - return this.each( function() { - var index, - data = dataPriv.get( this ), - queue = data[ type + "queue" ], - hooks = data[ type + "queueHooks" ], - timers = jQuery.timers, - length = queue ? queue.length : 0; - - // Enable finishing flag on private data - data.finish = true; - - // Empty the queue first - jQuery.queue( this, type, [] ); - - if ( hooks && hooks.stop ) { - hooks.stop.call( this, true ); - } - - // Look for any active animations, and finish them - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && timers[ index ].queue === type ) { - timers[ index ].anim.stop( true ); - timers.splice( index, 1 ); - } - } - - // Look for any animations in the old queue and finish them - for ( index = 0; index < length; index++ ) { - if ( queue[ index ] && queue[ index ].finish ) { - queue[ index ].finish.call( this ); - } - } - - // Turn off finishing flag - delete data.finish; - } ); - } -} ); - -jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { - var cssFn = jQuery.fn[ name ]; - jQuery.fn[ name ] = function( speed, easing, callback ) { - return speed == null || typeof speed === "boolean" ? - cssFn.apply( this, arguments ) : - this.animate( genFx( name, true ), speed, easing, callback ); - }; -} ); - -// Generate shortcuts for custom animations -jQuery.each( { - slideDown: genFx( "show" ), - slideUp: genFx( "hide" ), - slideToggle: genFx( "toggle" ), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" } -}, function( name, props ) { - jQuery.fn[ name ] = function( speed, easing, callback ) { - return this.animate( props, speed, easing, callback ); - }; -} ); - -jQuery.timers = []; -jQuery.fx.tick = function() { - var timer, - i = 0, - timers = jQuery.timers; - - fxNow = Date.now(); - - for ( ; i < timers.length; i++ ) { - timer = timers[ i ]; - - // Run the timer and safely remove it when done (allowing for external removal) - if ( !timer() && timers[ i ] === timer ) { - timers.splice( i--, 1 ); - } - } - - if ( !timers.length ) { - jQuery.fx.stop(); - } - fxNow = undefined; -}; - -jQuery.fx.timer = function( timer ) { - jQuery.timers.push( timer ); - jQuery.fx.start(); -}; - -jQuery.fx.interval = 13; -jQuery.fx.start = function() { - if ( inProgress ) { - return; - } - - inProgress = true; - schedule(); -}; - -jQuery.fx.stop = function() { - inProgress = null; -}; - -jQuery.fx.speeds = { - slow: 600, - fast: 200, - - // Default speed - _default: 400 -}; - - -// Based off of the plugin by Clint Helfers, with permission. -// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ -jQuery.fn.delay = function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = window.setTimeout( next, time ); - hooks.stop = function() { - window.clearTimeout( timeout ); - }; - } ); -}; - - -( function() { - var input = document.createElement( "input" ), - select = document.createElement( "select" ), - opt = select.appendChild( document.createElement( "option" ) ); - - input.type = "checkbox"; - - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; - - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document.createElement( "input" ); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; -} )(); - - -var boolHook, - attrHandle = jQuery.expr.attrHandle; - -jQuery.fn.extend( { - attr: function( name, value ) { - return access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each( function() { - jQuery.removeAttr( this, name ); - } ); - } -} ); - -jQuery.extend( { - attr: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set attributes on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - hooks = jQuery.attrHooks[ name.toLowerCase() ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); - } - - if ( value !== undefined ) { - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - } - - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - elem.setAttribute( name, value + "" ); - return value; - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - ret = jQuery.find.attr( elem, name ); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, - - attrHooks: { - type: { - set: function( elem, value ) { - if ( !support.radioValue && value === "radio" && - nodeName( elem, "input" ) ) { - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } - }, - - removeAttr: function( elem, value ) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match( rnothtmlwhite ); - - if ( attrNames && elem.nodeType === 1 ) { - while ( ( name = attrNames[ i++ ] ) ) { - elem.removeAttribute( name ); - } - } - } -} ); - -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { - - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - elem.setAttribute( name, name ); - } - return name; - } -}; - -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { - var getter = attrHandle[ name ] || jQuery.find.attr; - - attrHandle[ name ] = function( elem, name, isXML ) { - var ret, handle, - lowercaseName = name.toLowerCase(); - - if ( !isXML ) { - - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[ lowercaseName ]; - attrHandle[ lowercaseName ] = ret; - ret = getter( elem, name, isXML ) != null ? - lowercaseName : - null; - attrHandle[ lowercaseName ] = handle; - } - return ret; - }; -} ); - - - - -var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; - -jQuery.fn.extend( { - prop: function( name, value ) { - return access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - removeProp: function( name ) { - return this.each( function() { - delete this[ jQuery.propFix[ name ] || name ]; - } ); - } -} ); - -jQuery.extend( { - prop: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set properties on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - return ( elem[ name ] = value ); - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - return elem[ name ]; - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); - - if ( tabindex ) { - return parseInt( tabindex, 10 ); - } - - if ( - rfocusable.test( elem.nodeName ) || - rclickable.test( elem.nodeName ) && - elem.href - ) { - return 0; - } - - return -1; - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } -} ); - -// Support: IE <=11 only -// Accessing the selectedIndex property -// forces the browser to respect setting selected -// on the option -// The getter ensures a default option is selected -// when in an optgroup -// eslint rule "no-unused-expressions" is disabled for this code -// since it considers such accessions noop -if ( !support.optSelected ) { - jQuery.propHooks.selected = { - get: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent && parent.parentNode ) { - parent.parentNode.selectedIndex; - } - return null; - }, - set: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - }; -} - -jQuery.each( [ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; -} ); - - - - - // Strip and collapse whitespace according to HTML spec - // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace - function stripAndCollapse( value ) { - var tokens = value.match( rnothtmlwhite ) || []; - return tokens.join( " " ); - } - - -function getClass( elem ) { - return elem.getAttribute && elem.getAttribute( "class" ) || ""; -} - -function classesToArray( value ) { - if ( Array.isArray( value ) ) { - return value; - } - if ( typeof value === "string" ) { - return value.match( rnothtmlwhite ) || []; - } - return []; -} - -jQuery.fn.extend( { - addClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - classes = classesToArray( value ); - - if ( classes.length ) { - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - if ( cur.indexOf( " " + clazz + " " ) < 0 ) { - cur += clazz + " "; - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - if ( !arguments.length ) { - return this.attr( "class", "" ); - } - - classes = classesToArray( value ); - - if ( classes.length ) { - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - - // Remove *all* instances - while ( cur.indexOf( " " + clazz + " " ) > -1 ) { - cur = cur.replace( " " + clazz + " ", " " ); - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, - isValidValue = type === "string" || Array.isArray( value ); - - if ( typeof stateVal === "boolean" && isValidValue ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); - } - - if ( isFunction( value ) ) { - return this.each( function( i ) { - jQuery( this ).toggleClass( - value.call( this, i, getClass( this ), stateVal ), - stateVal - ); - } ); - } - - return this.each( function() { - var className, i, self, classNames; - - if ( isValidValue ) { - - // Toggle individual class names - i = 0; - self = jQuery( this ); - classNames = classesToArray( value ); - - while ( ( className = classNames[ i++ ] ) ) { - - // Check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); - } - } - - // Toggle whole class name - } else if ( value === undefined || type === "boolean" ) { - className = getClass( this ); - if ( className ) { - - // Store className if set - dataPriv.set( this, "__className__", className ); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if ( this.setAttribute ) { - this.setAttribute( "class", - className || value === false ? - "" : - dataPriv.get( this, "__className__" ) || "" - ); - } - } - } ); - }, - - hasClass: function( selector ) { - var className, elem, - i = 0; - - className = " " + selector + " "; - while ( ( elem = this[ i++ ] ) ) { - if ( elem.nodeType === 1 && - ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { - return true; - } - } - - return false; - } -} ); - - - - -var rreturn = /\r/g; - -jQuery.fn.extend( { - val: function( value ) { - var hooks, ret, valueIsFunction, - elem = this[ 0 ]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || - jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && - "get" in hooks && - ( ret = hooks.get( elem, "value" ) ) !== undefined - ) { - return ret; - } - - ret = elem.value; - - // Handle most common string cases - if ( typeof ret === "string" ) { - return ret.replace( rreturn, "" ); - } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; - } - - return; - } - - valueIsFunction = isFunction( value ); - - return this.each( function( i ) { - var val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( valueIsFunction ) { - val = value.call( this, i, jQuery( this ).val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - - } else if ( typeof val === "number" ) { - val += ""; - - } else if ( Array.isArray( val ) ) { - val = jQuery.map( val, function( value ) { - return value == null ? "" : value + ""; - } ); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - } ); - } -} ); - -jQuery.extend( { - valHooks: { - option: { - get: function( elem ) { - - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - - // Support: IE <=10 - 11 only - // option.text throws exceptions (#14686, #14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse( jQuery.text( elem ) ); - } - }, - select: { - get: function( elem ) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; - - if ( index < 0 ) { - i = max; - - } else { - i = one ? index : 0; - } - - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (#2551) - if ( ( option.selected || i === index ) && - - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - ( !option.parentNode.disabled || - !nodeName( option.parentNode, "optgroup" ) ) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - }, - - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; - - while ( i-- ) { - option = options[ i ]; - - /* eslint-disable no-cond-assign */ - - if ( option.selected = - jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 - ) { - optionSet = true; - } - - /* eslint-enable no-cond-assign */ - } - - // Force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; - } - return values; - } - } - } -} ); - -// Radios and checkboxes getter/setter -jQuery.each( [ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( Array.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); - } - } - }; - if ( !support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute( "value" ) === null ? "on" : elem.value; - }; - } -} ); - - - - -// Return jQuery for attributes-only inclusion - - -support.focusin = "onfocusin" in window; - - -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - stopPropagationCallback = function( e ) { - e.stopPropagation(); - }; - -jQuery.extend( jQuery.event, { - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; - - cur = lastElement = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "." ) > -1 ) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split( "." ); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf( ":" ) < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join( "." ); - event.rnamespace = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === ( elem.ownerDocument || document ) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - lastElement = cur; - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( - dataPriv.get( cur, "events" ) || Object.create( null ) - )[ event.type ] && - dataPriv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( ( !special._default || - special._default.apply( eventPath.pop(), data ) === false ) && - acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - - if ( event.isPropagationStopped() ) { - lastElement.addEventListener( type, stopPropagationCallback ); - } - - elem[ type ](); - - if ( event.isPropagationStopped() ) { - lastElement.removeEventListener( type, stopPropagationCallback ); - } - - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function( type, elem, event ) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); - - jQuery.event.trigger( e, null, elem ); - } - -} ); - -jQuery.fn.extend( { - - trigger: function( type, data ) { - return this.each( function() { - jQuery.event.trigger( type, data, this ); - } ); - }, - triggerHandler: function( type, data ) { - var elem = this[ 0 ]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -} ); - - -// Support: Firefox <=44 -// Firefox doesn't have focus(in | out) events -// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -// -// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 -// focus(in | out) events fire after focus & blur events, -// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order -// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 -if ( !support.focusin ) { - jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - - // Handle: regular nodes (via `this.ownerDocument`), window - // (via `this.document`) & document (via `this`). - var doc = this.ownerDocument || this.document || this, - attaches = dataPriv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this.document || this, - attaches = dataPriv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - dataPriv.remove( doc, fix ); - - } else { - dataPriv.access( doc, fix, attaches ); - } - } - }; - } ); -} -var location = window.location; - -var nonce = { guid: Date.now() }; - -var rquery = ( /\?/ ); - - - -// Cross-browser xml parsing -jQuery.parseXML = function( data ) { - var xml; - if ( !data || typeof data !== "string" ) { - return null; - } - - // Support: IE 9 - 11 only - // IE throws on parseFromString with invalid input. - try { - xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); - } catch ( e ) { - xml = undefined; - } - - if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; -}; - - -var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -function buildParams( prefix, obj, traditional, add ) { - var name; - - if ( Array.isArray( obj ) ) { - - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional || rbracket.test( prefix ) ) { - - // Treat each array item as a scalar. - add( prefix, v ); - - } else { - - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", - v, - traditional, - add - ); - } - } ); - - } else if ( !traditional && toType( obj ) === "object" ) { - - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } - - } else { - - // Serialize scalar item. - add( prefix, obj ); - } -} - -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, valueOrFunction ) { - - // If value is a function, invoke it and use its return value - var value = isFunction( valueOrFunction ) ? - valueOrFunction() : - valueOrFunction; - - s[ s.length ] = encodeURIComponent( key ) + "=" + - encodeURIComponent( value == null ? "" : value ); - }; - - if ( a == null ) { - return ""; - } - - // If an array was passed in, assume that it is an array of form elements. - if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { - - // Serialize the form elements - jQuery.each( a, function() { - add( this.name, this.value ); - } ); - - } else { - - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } - } - - // Return the resulting serialization - return s.join( "&" ); -}; - -jQuery.fn.extend( { - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map( function() { - - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - } ) - .filter( function() { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !rcheckableType.test( type ) ); - } ) - .map( function( _i, elem ) { - var val = jQuery( this ).val(); - - if ( val == null ) { - return null; - } - - if ( Array.isArray( val ) ) { - return jQuery.map( val, function( val ) { - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ); - } - - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ).get(); - } -} ); - - -var - r20 = /%20/g, - rhash = /#.*$/, - rantiCache = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, - - // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, - - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, - - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = "*/".concat( "*" ), - - // Anchor tag for parsing the document origin - originAnchor = document.createElement( "a" ); - originAnchor.href = location.href; - -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { - - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { - - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; - } - - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - - if ( isFunction( func ) ) { - - // For each dataType in the dataTypeExpression - while ( ( dataType = dataTypes[ i++ ] ) ) { - - // Prepend if requested - if ( dataType[ 0 ] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); - - // Otherwise append - } else { - ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); - } - } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); - - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && - !seekingTransport && !inspected[ dataTypeOrTransport ] ) { - - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - } ); - return selected; - } - - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes #9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } - - return target; -} - -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, - contents = s.contents, - dataTypes = s.dataTypes; - - // Remove auto dataType and get content-type in the process - while ( dataTypes[ 0 ] === "*" ) { - dataTypes.shift(); - if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); - } - } - - // Check if we're dealing with a known content-type - if ( ct ) { - for ( type in contents ) { - if ( contents[ type ] && contents[ type ].test( ct ) ) { - dataTypes.unshift( type ); - break; - } - } - } - - // Check to see if we have a response for the expected dataType - if ( dataTypes[ 0 ] in responses ) { - finalDataType = dataTypes[ 0 ]; - } else { - - // Try convertible dataTypes - for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { - finalDataType = type; - break; - } - if ( !firstDataType ) { - firstDataType = type; - } - } - - // Or just use first one - finalDataType = finalDataType || firstDataType; - } - - // If we found a dataType - // We add the dataType to the list if needed - // and return the corresponding response - if ( finalDataType ) { - if ( finalDataType !== dataTypes[ 0 ] ) { - dataTypes.unshift( finalDataType ); - } - return responses[ finalDataType ]; - } -} - -/* Chain conversions given the request and the original response - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); - - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; - } - } - - current = dataTypes.shift(); - - // Convert to each sequential dataType - while ( current ) { - - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } - - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } - - prev = current; - current = dataTypes.shift(); - - if ( current ) { - - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { - - current = prev; - - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { - - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; - - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { - - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { - - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { - - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; - - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } - - // Apply converter (if not an equivalence) - if ( conv !== true ) { - - // Unless errors are allowed to bubble, catch and return them - if ( conv && s.throws ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { - state: "parsererror", - error: conv ? e : "No conversion from " + prev + " to " + current - }; - } - } - } - } - } - } - - return { state: "success", data: response }; -} - -jQuery.extend( { - - // Counter for holding the number of active queries - active: 0, - - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, - - ajaxSettings: { - url: location.href, - type: "GET", - isLocal: rlocalProtocol.test( location.protocol ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ - - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - - contents: { - xml: /\bxml\b/, - html: /\bhtml/, - json: /\bjson\b/ - }, - - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, - - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { - - // Convert anything to text - "* text": String, - - // Text to html (true = no transformation) - "text html": true, - - // Evaluate text as a json expression - "text json": JSON.parse, - - // Parse text as xml - "text xml": jQuery.parseXML - }, - - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true - } - }, - - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - return settings ? - - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : - - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, - - ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), - ajaxTransport: addToPrefiltersOrTransports( transports ), - - // Main method - ajax: function( url, options ) { - - // If url is an object, simulate pre-1.5 signature - if ( typeof url === "object" ) { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - var transport, - - // URL without anti-cache param - cacheURL, - - // Response headers - responseHeadersString, - responseHeaders, - - // timeout handle - timeoutTimer, - - // Url cleanup var - urlAnchor, - - // Request state (becomes false upon send and true upon completion) - completed, - - // To know if global events are to be dispatched - fireGlobals, - - // Loop variable - i, - - // uncached part of the url - uncached, - - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), - - // Callbacks context - callbackContext = s.context || s, - - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && - ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, - - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks( "once memory" ), - - // Status-dependent callbacks - statusCode = s.statusCode || {}, - - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, - - // Default abort message - strAbort = "canceled", - - // Fake xhr - jqXHR = { - readyState: 0, - - // Builds headers hashtable if needed - getResponseHeader: function( key ) { - var match; - if ( completed ) { - if ( !responseHeaders ) { - responseHeaders = {}; - while ( ( match = rheaders.exec( responseHeadersString ) ) ) { - responseHeaders[ match[ 1 ].toLowerCase() + " " ] = - ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) - .concat( match[ 2 ] ); - } - } - match = responseHeaders[ key.toLowerCase() + " " ]; - } - return match == null ? null : match.join( ", " ); - }, - - // Raw string - getAllResponseHeaders: function() { - return completed ? responseHeadersString : null; - }, - - // Caches the header - setRequestHeader: function( name, value ) { - if ( completed == null ) { - name = requestHeadersNames[ name.toLowerCase() ] = - requestHeadersNames[ name.toLowerCase() ] || name; - requestHeaders[ name ] = value; - } - return this; - }, - - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( completed == null ) { - s.mimeType = type; - } - return this; - }, - - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( completed ) { - - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } else { - - // Lazy-add the new callbacks in a way that preserves old ones - for ( code in map ) { - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } - } - return this; - }, - - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; - - // Attach deferreds - deferred.promise( jqXHR ); - - // Add protocol if not provided (prefilters might expect it) - // Handle falsy url in the settings object (#10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || location.href ) + "" ) - .replace( rprotocol, location.protocol + "//" ); - - // Alias method option to type as per ticket #12004 - s.type = options.method || options.type || s.method || s.type; - - // Extract dataTypes list - s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; - - // A cross-domain request is in order when the origin doesn't match the current origin. - if ( s.crossDomain == null ) { - urlAnchor = document.createElement( "a" ); - - // Support: IE <=8 - 11, Edge 12 - 15 - // IE throws exception on accessing the href property if url is malformed, - // e.g. http://example.com:80x/ - try { - urlAnchor.href = s.url; - - // Support: IE <=8 - 11 only - // Anchor's host property isn't correctly set when s.url is relative - urlAnchor.href = urlAnchor.href; - s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== - urlAnchor.protocol + "//" + urlAnchor.host; - } catch ( e ) { - - // If there is an error parsing the URL, assume it is crossDomain, - // it can be rejected by the transport if it is invalid - s.crossDomain = true; - } - } - - // Convert data if not already a string - if ( s.data && s.processData && typeof s.data !== "string" ) { - s.data = jQuery.param( s.data, s.traditional ); - } - - // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); - - // If request was aborted inside a prefilter, stop there - if ( completed ) { - return jqXHR; - } - - // We can fire global events as of now if asked to - // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) - fireGlobals = jQuery.event && s.global; - - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger( "ajaxStart" ); - } - - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); - - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - // Remove hash to simplify url manipulation - cacheURL = s.url.replace( rhash, "" ); - - // More options handling for requests with no content - if ( !s.hasContent ) { - - // Remember the hash so we can put it back - uncached = s.url.slice( cacheURL.length ); - - // If data is available and should be processed, append data to url - if ( s.data && ( s.processData || typeof s.data === "string" ) ) { - cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; - - // #9682: remove data so that it's not used in an eventual retry - delete s.data; - } - - // Add or update anti-cache param if needed - if ( s.cache === false ) { - cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + - uncached; - } - - // Put hash and anti-cache on the URL that will be requested (gh-1732) - s.url = cacheURL + uncached; - - // Change '%20' to '+' if this is encoded form body content (gh-2658) - } else if ( s.data && s.processData && - ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { - s.data = s.data.replace( r20, "+" ); - } - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } - - // Set the correct header, if data is being sent - if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - jqXHR.setRequestHeader( "Content-Type", s.contentType ); - } - - // Set the Accepts header for the server, depending on the dataType - jqXHR.setRequestHeader( - "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? - s.accepts[ s.dataTypes[ 0 ] ] + - ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : - s.accepts[ "*" ] - ); - - // Check for headers option - for ( i in s.headers ) { - jqXHR.setRequestHeader( i, s.headers[ i ] ); - } - - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && - ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { - - // Abort if not done already and return - return jqXHR.abort(); - } - - // Aborting is no longer a cancellation - strAbort = "abort"; - - // Install callbacks on deferreds - completeDeferred.add( s.complete ); - jqXHR.done( s.success ); - jqXHR.fail( s.error ); - - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - jqXHR.readyState = 1; - - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); - } - - // If request was aborted inside ajaxSend, stop there - if ( completed ) { - return jqXHR; - } - - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = window.setTimeout( function() { - jqXHR.abort( "timeout" ); - }, s.timeout ); - } - - try { - completed = false; - transport.send( requestHeaders, done ); - } catch ( e ) { - - // Rethrow post-completion exceptions - if ( completed ) { - throw e; - } - - // Propagate others as results - done( -1, e ); - } - } - - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; - - // Ignore repeat invocations - if ( completed ) { - return; - } - - completed = true; - - // Clear timeout if it exists - if ( timeoutTimer ) { - window.clearTimeout( timeoutTimer ); - } - - // Dereference transport for early garbage collection - // (no matter how long the jqXHR object will be used) - transport = undefined; - - // Cache response headers - responseHeadersString = headers || ""; - - // Set readyState - jqXHR.readyState = status > 0 ? 4 : 0; - - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; - - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); - } - - // Use a noop converter for missing script - if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { - s.converters[ "text script" ] = function() {}; - } - - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); - - // If successful, handle type chaining - if ( isSuccess ) { - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader( "Last-Modified" ); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader( "etag" ); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } - - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; - - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; - - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; - } - } else { - - // Extract error from statusText and normalize for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } - } - } - - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || statusText ) + ""; - - // Success/Error - if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); - } else { - deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); - } - - // Status-dependent callbacks - jqXHR.statusCode( statusCode ); - statusCode = undefined; - - if ( fireGlobals ) { - globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } - - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); - - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); - - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger( "ajaxStop" ); - } - } - } - - return jqXHR; - }, - - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, - - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - } -} ); - -jQuery.each( [ "get", "post" ], function( _i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { - - // Shift arguments if data argument was omitted - if ( isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } - - // The url can be an options object (which then must have .url) - return jQuery.ajax( jQuery.extend( { - url: url, - type: method, - dataType: type, - data: data, - success: callback - }, jQuery.isPlainObject( url ) && url ) ); - }; -} ); - -jQuery.ajaxPrefilter( function( s ) { - var i; - for ( i in s.headers ) { - if ( i.toLowerCase() === "content-type" ) { - s.contentType = s.headers[ i ] || ""; - } - } -} ); - - -jQuery._evalUrl = function( url, options, doc ) { - return jQuery.ajax( { - url: url, - - // Make this explicit, since user can override this through ajaxSetup (#11264) - type: "GET", - dataType: "script", - cache: true, - async: false, - global: false, - - // Only evaluate the response if it is successful (gh-4126) - // dataFilter is not invoked for failure responses, so using it instead - // of the default converter is kludgy but it works. - converters: { - "text script": function() {} - }, - dataFilter: function( response ) { - jQuery.globalEval( response, options, doc ); - } - } ); -}; - - -jQuery.fn.extend( { - wrapAll: function( html ) { - var wrap; - - if ( this[ 0 ] ) { - if ( isFunction( html ) ) { - html = html.call( this[ 0 ] ); - } - - // The elements to wrap the target around - wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); - - if ( this[ 0 ].parentNode ) { - wrap.insertBefore( this[ 0 ] ); - } - - wrap.map( function() { - var elem = this; - - while ( elem.firstElementChild ) { - elem = elem.firstElementChild; - } - - return elem; - } ).append( this ); - } - - return this; - }, - - wrapInner: function( html ) { - if ( isFunction( html ) ) { - return this.each( function( i ) { - jQuery( this ).wrapInner( html.call( this, i ) ); - } ); - } - - return this.each( function() { - var self = jQuery( this ), - contents = self.contents(); - - if ( contents.length ) { - contents.wrapAll( html ); - - } else { - self.append( html ); - } - } ); - }, - - wrap: function( html ) { - var htmlIsFunction = isFunction( html ); - - return this.each( function( i ) { - jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); - } ); - }, - - unwrap: function( selector ) { - this.parent( selector ).not( "body" ).each( function() { - jQuery( this ).replaceWith( this.childNodes ); - } ); - return this; - } -} ); - - -jQuery.expr.pseudos.hidden = function( elem ) { - return !jQuery.expr.pseudos.visible( elem ); -}; -jQuery.expr.pseudos.visible = function( elem ) { - return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); -}; - - - - -jQuery.ajaxSettings.xhr = function() { - try { - return new window.XMLHttpRequest(); - } catch ( e ) {} -}; - -var xhrSuccessStatus = { - - // File protocol always yields status code 0, assume 200 - 0: 200, - - // Support: IE <=9 only - // #1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); - -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; - -jQuery.ajaxTransport( function( options ) { - var callback, errorCallback; - - // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(); - - xhr.open( - options.type, - options.url, - options.async, - options.username, - options.password - ); - - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } - } - - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.mimeType ); - } - - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { - headers[ "X-Requested-With" ] = "XMLHttpRequest"; - } - - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } - - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.ontimeout = - xhr.onreadystatechange = null; - - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { - - // Support: IE <=9 only - // On a manual native abort, IE9 throws - // errors on any property access that is not readyState - if ( typeof xhr.status !== "number" ) { - complete( 0, "error" ); - } else { - complete( - - // File: protocol always yields status 0; see #8605, #14207 - xhr.status, - xhr.statusText - ); - } - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, - - // Support: IE <=9 only - // IE9 has no XHR2 but throws on binary (trac-11426) - // For XHR2 non-text, let the caller handle it (gh-2498) - ( xhr.responseType || "text" ) !== "text" || - typeof xhr.responseText !== "string" ? - { binary: xhr.response } : - { text: xhr.responseText }, - xhr.getAllResponseHeaders() - ); - } - } - }; - }; - - // Listen to events - xhr.onload = callback(); - errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); - - // Support: IE 9 only - // Use onreadystatechange to replace onabort - // to handle uncaught aborts - if ( xhr.onabort !== undefined ) { - xhr.onabort = errorCallback; - } else { - xhr.onreadystatechange = function() { - - // Check readyState before timeout as it changes - if ( xhr.readyState === 4 ) { - - // Allow onerror to be called first, - // but that will not handle a native abort - // Also, save errorCallback to a variable - // as xhr.onerror cannot be accessed - window.setTimeout( function() { - if ( callback ) { - errorCallback(); - } - } ); - } - }; - } - - // Create the abort callback - callback = callback( "abort" ); - - try { - - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { - - // #14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, - - abort: function() { - if ( callback ) { - callback(); - } - } - }; - } -} ); - - - - -// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) -jQuery.ajaxPrefilter( function( s ) { - if ( s.crossDomain ) { - s.contents.script = false; - } -} ); - -// Install script dataType -jQuery.ajaxSetup( { - accepts: { - script: "text/javascript, application/javascript, " + - "application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /\b(?:java|ecma)script\b/ - }, - converters: { - "text script": function( text ) { - jQuery.globalEval( text ); - return text; - } - } -} ); - -// Handle cache's special case and crossDomain -jQuery.ajaxPrefilter( "script", function( s ) { - if ( s.cache === undefined ) { - s.cache = false; - } - if ( s.crossDomain ) { - s.type = "GET"; - } -} ); - -// Bind script tag hack transport -jQuery.ajaxTransport( "script", function( s ) { - - // This transport only deals with cross domain or forced-by-attrs requests - if ( s.crossDomain || s.scriptAttrs ) { - var script, callback; - return { - send: function( _, complete ) { - script = jQuery( " + @@ -78,8 +79,284 @@

    Index

    + A + | C + | D + | F + | G + | I + | K + | L + | M + | N + | P + | S + | T + | U + | X + | Y
    +

    A

    + + + +
    + +

    C

    + + + +
    + +

    D

    + + + +
    + +

    F

    + + +
    + +

    G

    + + + +
    + +

    I

    + + + +
    + +

    K

    + + + +
    + +

    L

    + + +
    + +

    M

    + + +
    + +

    N

    + + +
    + +

    P

    + + + +
    + +

    S

    + + + +
    + +

    T

    + + + +
    + +

    U

    + + +
    + +

    X

    + + + +
    + +

    Y

    + + +
    + diff --git a/docs/includeme/apidocuments.html b/docs/includeme/apidocuments.html index abdb2d8..5e7435f 100644 --- a/docs/includeme/apidocuments.html +++ b/docs/includeme/apidocuments.html @@ -1,7 +1,7 @@ - + Tracker — Multi-object trackers in Python 1.0.0 documentation @@ -16,6 +16,7 @@ + @@ -41,14 +42,122 @@
  1. Multi-object trackers in Python
  2. Example: TF-MobileNetSSD + CentroidTracker
  3. Example: YOLOv3 + CentroidTracker
  4. -
  5. Tracker
  6. -
  7. SORT
  8. -
  9. IOU Tracker
  10. -
  11. Kalman Filter based Centroid Tracker
  12. -
  13. Tracks
  14. -
  15. Kalman Filters
  16. -
  17. Object Detection
  18. +
  19. Tracker +
  20. +
  21. SORT +
  22. +
  23. IOU Tracker +
  24. +
  25. Kalman Filter based Centroid Tracker +
  26. +
  27. Tracks +
  28. +
  29. Kalman Filters +
  30. +
  31. Object Detection +
  32. Utilities
      +
    • get_centroid()
    • +
    • iou()
    • +
    • iou_xywh()
    • +
    • xyxy2xywh()
    • +
    • xywh2xyxy()
    • +
    • midwh2xywh()
    • +
    • intersection_complement_indices()
    • +
    • nms()
    • +
    • draw_tracks()
    • +
    • load_labelsjson()
    • +
    • dict2jsonfile()
    • +
    • create_filechooser()
    • +
    • select_caffemodel_prototxt()
    • +
    • select_caffemodel_weights()
    • +
    • select_caffemodel()
    • +
    • select_videofile()
    • +
    • select_yolo_weights()
    • +
    • select_coco_labels()
    • +
    • select_yolo_config()
    • +
    • select_yolo_model()
    • +
    • select_pbtxt()
    • +
    • select_tfmobilenet_weights()
    • +
    • select_tfmobilenet()
    • Download pretrained neural-network weights.
      • YOLOv3
      • TensorFlow - MobileNetSSDv2
      • @@ -95,27 +204,1101 @@

        Tracker

        +
        +
        +class motrackers.tracker.Tracker(max_lost=5, tracker_output_format='mot_challenge')[source]
        +

        Greedy Tracker with tracking based on centroid location of the bounding box of the object. +This tracker is also referred as CentroidTracker in this repository.

        +
        +
        Parameters
        +
          +
        • max_lost (int) – Maximum number of consecutive frames object was not detected.

        • +
        • tracker_output_format (str) – Output format of the tracker.

        • +
        +
        +
        +
        +
        +static preprocess_input(bboxes, class_ids, detection_scores)[source]
        +

        Preprocess the input data.

        +
        +
        Parameters
        +
          +
        • bboxes (list or numpy.ndarray) – Array of bounding boxes with each bbox as a tuple containing (xmin, ymin, width, height).

        • +
        • class_ids (list or numpy.ndarray) – Array of Class ID or label ID.

        • +
        • detection_scores (list or numpy.ndarray) – Array of detection scores (a.k.a. detection probabilities).

        • +
        +
        +
        Returns
        +

        Data for detections as list of tuples containing (bbox, class_id, detection_score).

        +
        +
        Return type
        +

        detections (list[Tuple])

        +
        +
        +
        + +
        +
        +update(bboxes, detection_scores, class_ids)[source]
        +

        Update the tracker based on the new bounding boxes.

        +
        +
        Parameters
        +
          +
        • bboxes (numpy.ndarray or list) – List of bounding boxes detected in the current frame. Each element of the list represent +coordinates of bounding box as tuple (top-left-x, top-left-y, width, height).

        • +
        • detection_scores (numpy.ndarray or list) – List of detection scores (probability) of each detected object.

        • +
        • class_ids (numpy.ndarray or list) – List of class_ids (int) corresponding to labels of the detected object. Default is None.

        • +
        +
        +
        Returns
        +

        List of tracks being currently tracked by the tracker. Each track is represented by the tuple with elements (frame_id, track_id, bb_left, bb_top, bb_width, bb_height, conf, x, y, z).

        +
        +
        Return type
        +

        list

        +
        +
        +
        + +
        +

        SORT

        +
        +
        +motrackers.sort_tracker.assign_tracks2detection_iou(bbox_tracks, bbox_detections, iou_threshold=0.3)[source]
        +

        Assigns detected bounding boxes to tracked bounding boxes using IoU as a distance metric.

        +
        +
        Parameters
        +
          +
        • bbox_tracks (numpy.ndarray) – Bounding boxes of shape (N, 4) where N is number of objects already being tracked.

        • +
        • bbox_detections (numpy.ndarray) – Bounding boxes of shape (M, 4) where M is number of objects that are newly detected.

        • +
        • iou_threshold (float) – IOU threashold.

        • +
        +
        +
        Returns
        +

        +
        Tuple contains the following elements in the given order:
          +
        • matches (numpy.ndarray): Array of shape (n, 2) where n is number of pairs formed after matching tracks to detections. This is an array of tuples with each element as matched pair of indices`(track_index, detection_index)`.

        • +
        • unmatched_detections (numpy.ndarray): Array of shape (m,) where m is number of unmatched detections.

        • +
        • unmatched_tracks (numpy.ndarray): Array of shape (k,) where k is the number of unmatched tracks.

        • +
        +
        +
        +

        +
        +
        Return type
        +

        tuple

        +
        +
        +
        + +
        +
        +class motrackers.sort_tracker.SORT(max_lost=0, tracker_output_format='mot_challenge', iou_threshold=0.3, process_noise_scale=1.0, measurement_noise_scale=1.0, time_step=1)[source]
        +

        SORT - Multi object tracker.

        +
        +
        Parameters
        +
          +
        • max_lost (int) – Max. number of times a object is lost while tracking.

        • +
        • tracker_output_format (str) – Output format of the tracker.

        • +
        • iou_threshold (float) – Intersection over union minimum value.

        • +
        • process_noise_scale (float or numpy.ndarray) – Process noise covariance matrix of shape (3, 3) +or covariance magnitude as scalar value.

        • +
        • measurement_noise_scale (float or numpy.ndarray) – Measurement noise covariance matrix of shape (1,) +or covariance magnitude as scalar value.

        • +
        • time_step (int or float) – Time step for Kalman Filter.

        • +
        +
        +
        +
        +
        +update(bboxes, detection_scores, class_ids)[source]
        +

        Update the tracker based on the new bounding boxes.

        +
        +
        Parameters
        +
          +
        • bboxes (numpy.ndarray or list) – List of bounding boxes detected in the current frame. Each element of the list represent +coordinates of bounding box as tuple (top-left-x, top-left-y, width, height).

        • +
        • detection_scores (numpy.ndarray or list) – List of detection scores (probability) of each detected object.

        • +
        • class_ids (numpy.ndarray or list) – List of class_ids (int) corresponding to labels of the detected object. Default is None.

        • +
        +
        +
        Returns
        +

        List of tracks being currently tracked by the tracker. Each track is represented by the tuple with elements (frame_id, track_id, bb_left, bb_top, bb_width, bb_height, conf, x, y, z).

        +
        +
        Return type
        +

        list

        +
        +
        +
        + +
        +

        IOU Tracker

        +
        +
        +class motrackers.iou_tracker.IOUTracker(max_lost=2, iou_threshold=0.5, min_detection_confidence=0.4, max_detection_confidence=0.7, tracker_output_format='mot_challenge')[source]
        +

        Intersection over Union Tracker.

        +

        References

        + +
        +
        Parameters
        +
          +
        • max_lost (int) – Maximum number of consecutive frames object was not detected.

        • +
        • tracker_output_format (str) – Output format of the tracker.

        • +
        • min_detection_confidence (float) – Threshold for minimum detection confidence.

        • +
        • max_detection_confidence (float) – Threshold for max. detection confidence.

        • +
        • iou_threshold (float) – Intersection over union minimum value.

        • +
        +
        +
        +
        +
        +update(bboxes, detection_scores, class_ids)[source]
        +

        Update the tracker based on the new bounding boxes.

        +
        +
        Parameters
        +
          +
        • bboxes (numpy.ndarray or list) – List of bounding boxes detected in the current frame. Each element of the list represent +coordinates of bounding box as tuple (top-left-x, top-left-y, width, height).

        • +
        • detection_scores (numpy.ndarray or list) – List of detection scores (probability) of each detected object.

        • +
        • class_ids (numpy.ndarray or list) – List of class_ids (int) corresponding to labels of the detected object. Default is None.

        • +
        +
        +
        Returns
        +

        List of tracks being currently tracked by the tracker. Each track is represented by the tuple with elements (frame_id, track_id, bb_left, bb_top, bb_width, bb_height, conf, x, y, z).

        +
        +
        Return type
        +

        list

        +
        +
        +
        + +
        +

        Kalman Filter based Centroid Tracker

        +
        +
        +motrackers.centroid_kf_tracker.assign_tracks2detection_centroid_distances(bbox_tracks, bbox_detections, distance_threshold=10.0)[source]
        +

        Assigns detected bounding boxes to tracked bounding boxes using IoU as a distance metric.

        +
        +
        Parameters
        +
          +
        • bbox_tracks (numpy.ndarray) – Tracked bounding boxes with shape (n, 4) +and each row as (xmin, ymin, width, height).

        • +
        • bbox_detections (numpy.ndarray) – detection bounding boxes with shape (m, 4) and +each row as (xmin, ymin, width, height).

        • +
        • distance_threshold (float) – Minimum distance between the tracked object +and new detection to consider for assignment.

        • +
        +
        +
        Returns
        +

        +
        Tuple containing the following elements:
          +
        • matches (numpy.ndarray): Array of shape (n, 2) where n is number of pairs formed after matching tracks to detections. This is an array of tuples with each element as matched pair of indices`(track_index, detection_index)`.

        • +
        • unmatched_detections (numpy.ndarray): Array of shape (m,) where m is number of unmatched detections.

        • +
        • unmatched_tracks (numpy.ndarray): Array of shape (k,) where k is the number of unmatched tracks.

        • +
        +
        +
        +

        +
        +
        Return type
        +

        tuple

        +
        +
        +
        + +
        +
        +class motrackers.centroid_kf_tracker.CentroidKF_Tracker(max_lost=1, centroid_distance_threshold=30.0, tracker_output_format='mot_challenge', process_noise_scale=1.0, measurement_noise_scale=1.0, time_step=1)[source]
        +

        Kalman filter based tracking of multiple detected objects.

        +
        +
        Parameters
        +
          +
        • max_lost (int) – Maximum number of consecutive frames object was not detected.

        • +
        • tracker_output_format (str) – Output format of the tracker.

        • +
        • process_noise_scale (float or numpy.ndarray) – Process noise covariance matrix of shape (3, 3) or +covariance magnitude as scalar value.

        • +
        • measurement_noise_scale (float or numpy.ndarray) – Measurement noise covariance matrix of shape (1,) +or covariance magnitude as scalar value.

        • +
        • time_step (int or float) – Time step for Kalman Filter.

        • +
        +
        +
        +
        +
        +update(bboxes, detection_scores, class_ids)[source]
        +

        Update the tracker based on the new bounding boxes.

        +
        +
        Parameters
        +
          +
        • bboxes (numpy.ndarray or list) – List of bounding boxes detected in the current frame. Each element of the list represent +coordinates of bounding box as tuple (top-left-x, top-left-y, width, height).

        • +
        • detection_scores (numpy.ndarray or list) – List of detection scores (probability) of each detected object.

        • +
        • class_ids (numpy.ndarray or list) – List of class_ids (int) corresponding to labels of the detected object. Default is None.

        • +
        +
        +
        Returns
        +

        List of tracks being currently tracked by the tracker. Each track is represented by the tuple with elements (frame_id, track_id, bb_left, bb_top, bb_width, bb_height, conf, x, y, z).

        +
        +
        Return type
        +

        list

        +
        +
        +
        + +
        +

        Tracks

        +
        +
        +class motrackers.track.Track(track_id, frame_id, bbox, detection_confidence, class_id=None, lost=0, iou_score=0.0, data_output_format='mot_challenge', **kwargs)[source]
        +

        Track containing attributes to track various objects.

        +
        +
        Parameters
        +
          +
        • frame_id (int) – Camera frame id.

        • +
        • track_id (int) – Track Id

        • +
        • bbox (numpy.ndarray) – Bounding box pixel coordinates as (xmin, ymin, width, height) of the track.

        • +
        • detection_confidence (float) – Detection confidence of the object (probability).

        • +
        • class_id (str or int) – Class label id.

        • +
        • lost (int) – Number of times the object or track was not tracked by tracker in consecutive frames.

        • +
        • iou_score (float) – Intersection over union score.

        • +
        • data_output_format (str) – Output format for data in tracker. +Options include ['mot_challenge', 'visdrone_challenge']. Default is mot_challenge.

        • +
        • kwargs (dict) – Additional key word arguments.

        • +
        +
        +
        +
        +
        +property centroid
        +

        Return the centroid of the bounding box.

        +
        +
        Returns
        +

        Centroid (x, y) of bounding box.

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +get_mot_challenge_format()[source]
        +

        Get the tracker data in MOT challenge format as a tuple of elements containing +(frame, id, bb_left, bb_top, bb_width, bb_height, conf, x, y, z)

        +

        References

        + +
        +
        Returns
        +

        Tuple of 10 elements representing (frame, id, bb_left, bb_top, bb_width, bb_height, conf, x, y, z).

        +
        +
        Return type
        +

        tuple

        +
        +
        +
        + +
        +
        +get_vis_drone_format()[source]
        +

        Track data output in VISDRONE Challenge format with tuple as +(frame_index, target_id, bbox_left, bbox_top, bbox_width, bbox_height, score, object_category, +truncation, occlusion).

        +

        References

        + +
        +
        Returns
        +

        Tuple containing the elements as (frame_index, target_id, bbox_left, bbox_top, bbox_width, bbox_height, +score, object_category, truncation, occlusion).

        +
        +
        Return type
        +

        tuple

        +
        +
        +
        + +
        +
        +predict()[source]
        +

        Implement to prediction the next estimate of track.

        +
        + +
        +
        +update(frame_id, bbox, detection_confidence, class_id=None, lost=0, iou_score=0.0, **kwargs)[source]
        +

        Update the track.

        +
        +
        Parameters
        +
          +
        • frame_id (int) – Camera frame id.

        • +
        • bbox (numpy.ndarray) – Bounding box pixel coordinates as (xmin, ymin, width, height) of the track.

        • +
        • detection_confidence (float) – Detection confidence of the object (probability).

        • +
        • class_id (int or str) – Class label id.

        • +
        • lost (int) – Number of times the object or track was not tracked by tracker in consecutive frames.

        • +
        • iou_score (float) – Intersection over union score.

        • +
        • kwargs (dict) – Additional key word arguments.

        • +
        +
        +
        +
        + +
        + +
        +
        +class motrackers.track.KFTrackSORT(track_id, frame_id, bbox, detection_confidence, class_id=None, lost=0, iou_score=0.0, data_output_format='mot_challenge', process_noise_scale=1.0, measurement_noise_scale=1.0, **kwargs)[source]
        +

        Track based on Kalman filter tracker used for SORT MOT-Algorithm.

        +
        +
        Parameters
        +
          +
        • track_id (int) – Track Id

        • +
        • frame_id (int) – Camera frame id.

        • +
        • bbox (numpy.ndarray) – Bounding box pixel coordinates as (xmin, ymin, width, height) of the track.

        • +
        • detection_confidence (float) – Detection confidence of the object (probability).

        • +
        • class_id (str or int) – Class label id.

        • +
        • lost (int) – Number of times the object or track was not tracked by tracker in consecutive frames.

        • +
        • iou_score (float) – Intersection over union score.

        • +
        • data_output_format (str) – Output format for data in tracker. +Options ['mot_challenge', 'visdrone_challenge']. Default is mot_challenge.

        • +
        • process_noise_scale (float) – Process noise covariance scale or covariance magnitude as scalar value.

        • +
        • measurement_noise_scale (float) – Measurement noise covariance scale or covariance magnitude as scalar value.

        • +
        • kwargs (dict) – Additional key word arguments.

        • +
        +
        +
        +
        +
        +predict()[source]
        +

        Predicts the next estimate of the bounding box of the track.

        +
        +
        Returns
        +

        Bounding box pixel coordinates as (xmin, ymin, width, height) of the track.

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +update(frame_id, bbox, detection_confidence, class_id=None, lost=0, iou_score=0.0, **kwargs)[source]
        +

        Update the track.

        +
        +
        Parameters
        +
          +
        • frame_id (int) – Camera frame id.

        • +
        • bbox (numpy.ndarray) – Bounding box pixel coordinates as (xmin, ymin, width, height) of the track.

        • +
        • detection_confidence (float) – Detection confidence of the object (probability).

        • +
        • class_id (int or str) – Class label id.

        • +
        • lost (int) – Number of times the object or track was not tracked by tracker in consecutive frames.

        • +
        • iou_score (float) – Intersection over union score.

        • +
        • kwargs (dict) – Additional key word arguments.

        • +
        +
        +
        +
        + +
        + +
        +
        +class motrackers.track.KFTrack4DSORT(track_id, frame_id, bbox, detection_confidence, class_id=None, lost=0, iou_score=0.0, data_output_format='mot_challenge', process_noise_scale=1.0, measurement_noise_scale=1.0, kf_time_step=1, **kwargs)[source]
        +

        Track based on Kalman filter tracker used for SORT MOT-Algorithm.

        +
        +
        Parameters
        +
          +
        • track_id (int) – Track Id

        • +
        • frame_id (int) – Camera frame id.

        • +
        • bbox (numpy.ndarray) – Bounding box pixel coordinates as (xmin, ymin, width, height) of the track.

        • +
        • detection_confidence (float) – Detection confidence of the object (probability).

        • +
        • class_id (str or int) – Class label id.

        • +
        • lost (int) – Number of times the object or track was not tracked by tracker in consecutive frames.

        • +
        • iou_score (float) – Intersection over union score.

        • +
        • data_output_format (str) – Output format for data in tracker. +Options ['mot_challenge', 'visdrone_challenge']. Default is mot_challenge.

        • +
        • process_noise_scale (float) – Process noise covariance scale or covariance magnitude as scalar value.

        • +
        • measurement_noise_scale (float) – Measurement noise covariance scale or covariance magnitude as scalar value.

        • +
        • kwargs (dict) – Additional key word arguments.

        • +
        +
        +
        +
        +
        +predict()[source]
        +

        Implement to prediction the next estimate of track.

        +
        + +
        +
        +update(frame_id, bbox, detection_confidence, class_id=None, lost=0, iou_score=0.0, **kwargs)[source]
        +

        Update the track.

        +
        +
        Parameters
        +
          +
        • frame_id (int) – Camera frame id.

        • +
        • bbox (numpy.ndarray) – Bounding box pixel coordinates as (xmin, ymin, width, height) of the track.

        • +
        • detection_confidence (float) – Detection confidence of the object (probability).

        • +
        • class_id (int or str) – Class label id.

        • +
        • lost (int) – Number of times the object or track was not tracked by tracker in consecutive frames.

        • +
        • iou_score (float) – Intersection over union score.

        • +
        • kwargs (dict) – Additional key word arguments.

        • +
        +
        +
        +
        + +
        + +
        +
        +class motrackers.track.KFTrackCentroid(track_id, frame_id, bbox, detection_confidence, class_id=None, lost=0, iou_score=0.0, data_output_format='mot_challenge', process_noise_scale=1.0, measurement_noise_scale=1.0, **kwargs)[source]
        +

        Track based on Kalman filter used for Centroid Tracking of bounding box in MOT.

        +
        +
        Parameters
        +
          +
        • track_id (int) – Track Id

        • +
        • frame_id (int) – Camera frame id.

        • +
        • bbox (numpy.ndarray) – Bounding box pixel coordinates as (xmin, ymin, width, height) of the track.

        • +
        • detection_confidence (float) – Detection confidence of the object (probability).

        • +
        • class_id (str or int) – Class label id.

        • +
        • lost (int) – Number of times the object or track was not tracked by tracker in consecutive frames.

        • +
        • iou_score (float) – Intersection over union score.

        • +
        • data_output_format (str) – Output format for data in tracker. +Options ['mot_challenge', 'visdrone_challenge']. Default is mot_challenge.

        • +
        • process_noise_scale (float) – Process noise covariance scale or covariance magnitude as scalar value.

        • +
        • measurement_noise_scale (float) – Measurement noise covariance scale or covariance magnitude as scalar value.

        • +
        • kwargs (dict) – Additional key word arguments.

        • +
        +
        +
        +
        +
        +predict()[source]
        +

        Predicts the next estimate of the bounding box of the track.

        +
        +
        Returns
        +

        Bounding box pixel coordinates as (xmin, ymin, width, height) of the track.

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +update(frame_id, bbox, detection_confidence, class_id=None, lost=0, iou_score=0.0, **kwargs)[source]
        +

        Update the track.

        +
        +
        Parameters
        +
          +
        • frame_id (int) – Camera frame id.

        • +
        • bbox (numpy.ndarray) – Bounding box pixel coordinates as (xmin, ymin, width, height) of the track.

        • +
        • detection_confidence (float) – Detection confidence of the object (probability).

        • +
        • class_id (int or str) – Class label id.

        • +
        • lost (int) – Number of times the object or track was not tracked by tracker in consecutive frames.

        • +
        • iou_score (float) – Intersection over union score.

        • +
        • kwargs (dict) – Additional key word arguments.

        • +
        +
        +
        +
        + +
        +

        Kalman Filters

        +
        +
        +class motrackers.kalman_tracker.KalmanFilter(transition_matrix, measurement_matrix, control_matrix=None, process_noise_covariance=None, measurement_noise_covariance=None, prediction_covariance=None, initial_state=None)[source]
        +

        Kalman Filter Implementation.

        +
        +
        Parameters
        +
          +
        • transition_matrix (numpy.ndarray) – Transition matrix of shape (n, n).

        • +
        • measurement_matrix (numpy.ndarray) – Measurement matrix of shape (m, n).

        • +
        • control_matrix (numpy.ndarray) – Control matrix of shape (m, n).

        • +
        • process_noise_covariance (numpy.ndarray) – Covariance matrix of shape (n, n).

        • +
        • measurement_noise_covariance (numpy.ndarray) – Covariance matrix of shape (m, m).

        • +
        • prediction_covariance (numpy.ndarray) – Predicted (a priori) estimate covariance of shape (n, n).

        • +
        • initial_state (numpy.ndarray) – Initial state of shape (n,).

        • +
        +
        +
        +
        +
        +predict(u=0)[source]
        +

        Prediction step of Kalman Filter.

        +
        +
        Parameters
        +

        u (float or int or numpy.ndarray) – Control input. Default is 0.

        +
        +
        Returns
        +

        State vector of shape (n,).

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +update(z)[source]
        +

        Measurement update of Kalman Filter.

        +
        +
        Parameters
        +

        z (numpy.ndarray) – Measurement vector of the system with shape (m,).

        +
        +
        +
        + +
        + +
        +
        +class motrackers.kalman_tracker.KFTrackerConstantAcceleration(initial_measurement, time_step=1, process_noise_scale=1.0, measurement_noise_scale=1.0)[source]
        +

        Kalman Filter with constant acceleration kinematic model.

        +
        +
        Parameters
        +
          +
        • initial_measurement (numpy.ndarray) – Initial state of the tracker.

        • +
        • time_step (float) – Time step.

        • +
        • process_noise_scale (float) – Process noise covariance scale. +or covariance magnitude as scalar value.

        • +
        • measurement_noise_scale (float) – Measurement noise covariance scale. +or covariance magnitude as scalar value.

        • +
        +
        +
        +
        + +
        +
        +class motrackers.kalman_tracker.KFTracker1D(initial_measurement=array([0.0]), time_step=1, process_noise_scale=1.0, measurement_noise_scale=1.0)[source]
        +
        + +
        +
        +class motrackers.kalman_tracker.KFTracker2D(initial_measurement=array([0.0, 0.0]), time_step=1, process_noise_scale=1.0, measurement_noise_scale=1.0)[source]
        +
        + +
        +
        +class motrackers.kalman_tracker.KFTracker4D(initial_measurement=array([0.0, 0.0, 0.0, 0.0]), time_step=1, process_noise_scale=1.0, measurement_noise_scale=1.0)[source]
        +
        + +
        +
        +class motrackers.kalman_tracker.KFTrackerSORT(bbox, process_noise_scale=1.0, measurement_noise_scale=1.0, time_step=1)[source]
        +

        Kalman filter for SORT.

        +
        +
        Parameters
        +
          +
        • bbox (numpy.ndarray) – Bounding box coordinates as (xmid, ymid, area, aspect_ratio).

        • +
        • time_step (float or int) – Time step.

        • +
        • process_noise_scale (float) – Scale (a.k.a covariance) of the process noise.

        • +
        • measurement_noise_scale (float) – Scale (a.k.a. covariance) of the measurement noise.

        • +
        +
        +
        +
        +

        Object Detection

        +
        +
        +class motrackers.detectors.detector.Detector(object_names, confidence_threshold, nms_threshold, draw_bboxes=True)[source]
        +

        Abstract class for detector.

        +
        +
        Parameters
        +
          +
        • object_names (dict) – Dictionary containing (key, value) as (class_id, class_name) for object detector.

        • +
        • confidence_threshold (float) – Confidence threshold for object detection.

        • +
        • nms_threshold (float) – Threshold for non-maximal suppression.

        • +
        • draw_bboxes (bool) – If true, draw bounding boxes on the image is possible.

        • +
        +
        +
        +
        +
        +detect(image)[source]
        +

        Detect objects in the input image.

        +
        +
        Parameters
        +

        image (numpy.ndarray) – Input image.

        +
        +
        Returns
        +

        +
        Tuple containing the following elements:
          +
        • bboxes (numpy.ndarray): Bounding boxes with shape (n, 4) containing detected objects with each row as (xmin, ymin, width, height).

        • +
        • confidences (numpy.ndarray): Confidence or detection probabilities if the detected objects with shape (n,).

        • +
        • class_ids (numpy.ndarray): Class_ids or label_ids of detected objects with shape (n, 4)

        • +
        +
        +
        +

        +
        +
        Return type
        +

        tuple

        +
        +
        +
        + +
        +
        +draw_bboxes(image, bboxes, confidences, class_ids)[source]
        +

        Draw the bounding boxes about detected objects in the image.

        +
        +
        Parameters
        +
          +
        • image (numpy.ndarray) – Image or video frame.

        • +
        • bboxes (numpy.ndarray) – Bounding boxes pixel coordinates as (xmin, ymin, width, height)

        • +
        • confidences (numpy.ndarray) – Detection confidence or detection probability.

        • +
        • class_ids (numpy.ndarray) – Array containing class ids (aka label ids) of each detected object.

        • +
        +
        +
        Returns
        +

        image with the bounding boxes drawn on it.

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +forward(image)[source]
        +

        Forward pass for the detector with input image.

        +
        +
        Parameters
        +

        image (numpy.ndarray) – Input image.

        +
        +
        Returns
        +

        detections

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        + +
        +
        +class motrackers.detectors.caffe.Caffe_SSDMobileNet(weights_path, configfile_path, labels_path, confidence_threshold=0.5, nms_threshold=0.2, draw_bboxes=True, use_gpu=False)[source]
        +

        Caffe SSD MobileNet model for Object Detection.

        +
        +
        Parameters
        +
          +
        • weights_path (str) – path to network weights file.

        • +
        • configfile_path (str) – path to network configuration file.

        • +
        • labels_path (str) – path to data labels json file.

        • +
        • confidence_threshold (float) – confidence threshold to select the detected object.

        • +
        • nms_threshold (float) – Non-maximum suppression threshold.

        • +
        • draw_bboxes (bool) – If True, assign colors for drawing bounding boxes on the image.

        • +
        • use_gpu (bool) – If True, try to load the model on GPU.

        • +
        +
        +
        +
        +
        +forward(image)[source]
        +

        Forward pass for the detector with input image.

        +
        +
        Parameters
        +

        image (numpy.ndarray) – Input image.

        +
        +
        Returns
        +

        detections

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        + +
        +
        +class motrackers.detectors.tf.TF_SSDMobileNetV2(weights_path, configfile_path, labels_path, confidence_threshold=0.5, nms_threshold=0.4, draw_bboxes=True, use_gpu=False)[source]
        +

        Tensorflow SSD MobileNetv2 model for Object Detection.

        +
        +
        Parameters
        +
          +
        • weights_path (str) – path to network weights file.

        • +
        • configfile_path (str) – path to network configuration file.

        • +
        • labels_path (str) – path to data labels json file.

        • +
        • confidence_threshold (float) – confidence threshold to select the detected object.

        • +
        • nms_threshold (float) – Non-maximum suppression threshold.

        • +
        • draw_bboxes (bool) – If True, assign colors for drawing bounding boxes on the image.

        • +
        • use_gpu (bool) – If True, try to load the model on GPU.

        • +
        +
        +
        +
        +
        +forward(image)[source]
        +

        Forward pass for the detector with input image.

        +
        +
        Parameters
        +

        image (numpy.ndarray) – Input image.

        +
        +
        Returns
        +

        detections

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        + +
        +
        +class motrackers.detectors.yolo.YOLOv3(weights_path, configfile_path, labels_path, confidence_threshold=0.5, nms_threshold=0.2, draw_bboxes=True, use_gpu=False)[source]
        +

        YOLOv3 Object Detector Module.

        +
        +
        Parameters
        +
          +
        • weights_path (str) – path to network weights file.

        • +
        • configfile_path (str) – path to network configuration file.

        • +
        • labels_path (str) – path to data labels json file.

        • +
        • confidence_threshold (float) – confidence threshold to select the detected object.

        • +
        • nms_threshold (float) – Non-maximum suppression threshold.

        • +
        • draw_bboxes (bool) – If True, assign colors for drawing bounding boxes on the image.

        • +
        • use_gpu (bool) – If True, try to load the model on GPU.

        • +
        +
        +
        +
        +
        +detect(image)[source]
        +

        Detect objects in the input image.

        +
        +
        Parameters
        +

        image (numpy.ndarray) – Input image.

        +
        +
        Returns
        +

        +
        Tuple containing the following elements:
          +
        • bboxes (numpy.ndarray): Bounding boxes with shape (n, 4) containing detected objects with each row as (xmin, ymin, width, height).

        • +
        • confidences (numpy.ndarray): Confidence or detection probabilities if the detected objects with shape (n,).

        • +
        • class_ids (numpy.ndarray): Class_ids or label_ids of detected objects with shape (n, 4)

        • +
        +
        +
        +

        +
        +
        Return type
        +

        tuple

        +
        +
        +
        + +
        +
        +forward(image)[source]
        +

        Forward pass for the detector with input image.

        +
        +
        Parameters
        +

        image (numpy.ndarray) – Input image.

        +
        +
        Returns
        +

        detections

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +

        Utilities

        +
        +
        +motrackers.utils.misc.get_centroid(bboxes)[source]
        +

        Calculate centroids for multiple bounding boxes.

        +
        +
        Parameters
        +

        bboxes (numpy.ndarray) – Array of shape (n, 4) or of shape (4,) where +each row contains (xmin, ymin, width, height).

        +
        +
        Returns
        +

        Centroid (x, y) coordinates of shape (n, 2) or (2,).

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +motrackers.utils.misc.iou(bbox1, bbox2)[source]
        +

        Calculates the intersection-over-union of two bounding boxes. +Source: https://github.com/bochinski/iou-tracker/blob/master/util.py

        +
        +
        Parameters
        +
          +
        • bbox1 (numpy.array or list[floats]) – Bounding box of length 4 containing +(x-top-left, y-top-left, x-bottom-right, y-bottom-right).

        • +
        • bbox2 (numpy.array or list[floats]) – Bounding box of length 4 containing +(x-top-left, y-top-left, x-bottom-right, y-bottom-right).

        • +
        +
        +
        Returns
        +

        intersection-over-onion of bbox1, bbox2.

        +
        +
        Return type
        +

        float

        +
        +
        +
        + +
        +
        +motrackers.utils.misc.iou_xywh(bbox1, bbox2)[source]
        +

        Calculates the intersection-over-union of two bounding boxes. +Source: https://github.com/bochinski/iou-tracker/blob/master/util.py

        +
        +
        Parameters
        +
          +
        • bbox1 (numpy.array or list[floats]) – bounding box of length 4 containing (x-top-left, y-top-left, width, height).

        • +
        • bbox2 (numpy.array or list[floats]) – bounding box of length 4 containing (x-top-left, y-top-left, width, height).

        • +
        +
        +
        Returns
        +

        intersection-over-onion of bbox1, bbox2.

        +
        +
        Return type
        +

        float

        +
        +
        +
        + +
        +
        +motrackers.utils.misc.xyxy2xywh(xyxy)[source]
        +

        Convert bounding box coordinates from (xmin, ymin, xmax, ymax) format to (xmin, ymin, width, height).

        +
        +
        Parameters
        +

        xyxy (numpy.ndarray) –

        +
        +
        Returns
        +

        Bounding box coordinates (xmin, ymin, width, height).

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +motrackers.utils.misc.xywh2xyxy(xywh)[source]
        +

        Convert bounding box coordinates from (xmin, ymin, width, height) to (xmin, ymin, xmax, ymax) format.

        +
        +
        Parameters
        +

        xywh (numpy.ndarray) – Bounding box coordinates as (xmin, ymin, width, height).

        +
        +
        Returns
        +

        Bounding box coordinates as (xmin, ymin, xmax, ymax).

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +motrackers.utils.misc.midwh2xywh(midwh)[source]
        +

        Convert bounding box coordinates from (xmid, ymid, width, height) to (xmin, ymin, width, height) format.

        +
        +
        Parameters
        +

        midwh (numpy.ndarray) – Bounding box coordinates (xmid, ymid, width, height).

        +
        +
        Returns
        +

        Bounding box coordinates (xmin, ymin, width, height).

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +motrackers.utils.misc.intersection_complement_indices(big_set_indices, small_set_indices)[source]
        +

        Get the complement of intersection of two sets of indices.

        +
        +
        Parameters
        +
          +
        • big_set_indices (numpy.ndarray) – Indices of big set.

        • +
        • small_set_indices (numpy.ndarray) – Indices of small set.

        • +
        +
        +
        Returns
        +

        Indices of set which is complementary to intersection of two input sets.

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +motrackers.utils.misc.nms(boxes, scores, overlapThresh, classes=None)[source]
        +

        Non-maximum suppression. based on Malisiewicz et al.

        +
        +
        Parameters
        +
          +
        • boxes (numpy.ndarray) – Boxes to process (xmin, ymin, xmax, ymax)

        • +
        • scores (numpy.ndarray) – Corresponding scores for each box

        • +
        • overlapThresh (float) – Overlap threshold for boxes to merge

        • +
        • classes (numpy.ndarray, optional) – Class ids for each box.

        • +
        +
        +
        Returns
        +

        +
        a tuple containing:
          +
        • boxes (list): nms boxes

        • +
        • scores (list): nms scores

        • +
        • classes (list, optional): nms classes if specified

        • +
        +
        +
        +

        +
        +
        Return type
        +

        tuple

        +
        +
        +
        + +
        +
        +motrackers.utils.misc.draw_tracks(image, tracks)[source]
        +

        Draw on input image.

        +
        +
        Parameters
        +
          +
        • image (numpy.ndarray) – image

        • +
        • tracks (list) – list of tracks to be drawn on the image.

        • +
        +
        +
        Returns
        +

        image with the track-ids drawn on it.

        +
        +
        Return type
        +

        numpy.ndarray

        +
        +
        +
        + +
        +
        +motrackers.utils.misc.load_labelsjson(json_file)[source]
        +
        + +
        +
        +motrackers.utils.misc.dict2jsonfile(dict_data, json_file_path)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.create_filechooser(default_path='~/', html_title='Select File', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_caffemodel_prototxt(default_path='~/', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_caffemodel_weights(default_path='~/', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_caffemodel(default_path='~/', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_videofile(default_path='~/', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_yolo_weights(default_path='~/', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_coco_labels(default_path='~/', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_yolo_config(default_path='~/', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_yolo_model(default_path='~/', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_pbtxt(default_path='~/', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_tfmobilenet_weights(default_path='~/', use_dir_icons=True)[source]
        +
        + +
        +
        +motrackers.utils.filechooser_utils.select_tfmobilenet(default_path='~/', use_dir_icons=True)[source]
        +
        +

        Download pretrained neural-network weights.

        [Webpage] diff --git a/docs/includeme/readmefile.html b/docs/includeme/readmefile.html index 08176a8..e58c3cd 100644 --- a/docs/includeme/readmefile.html +++ b/docs/includeme/readmefile.html @@ -1,7 +1,7 @@ - + Multi-object trackers in Python — Multi-object trackers in Python 1.0.0 documentation @@ -16,6 +16,7 @@ + @@ -94,22 +95,24 @@

        Multi-object trackers in Python

        Easy to use implementation of various multi-object tracking algorithms.

        DOI +


        +Upload motrackers to PyPI

        Available Multi Object Trackers

        -
        CentroidTracker
        -IOUTracker
        -CentroidKF_Tracker
        -SORT
        -
        -
        +
          +
        • CentroidTracker

        • +
        • IOUTracker

        • +
        • CentroidKF_Tracker

        • +
        • SORT

        • +

        Available OpenCV-based object detectors:

        -
        detector.TF_SSDMobileNetV2
        -detector.Caffe_SSDMobileNet
        -detector.YOLOv3
        -
        -
        +
          +
        • detector.TF_SSDMobileNetV2

        • +
        • detector.Caffe_SSDMobileNet

        • +
        • detector.YOLOv3

        • +

        Installation

        diff --git a/docs/index.html b/docs/index.html index f8077cd..5d9d42f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,7 +1,7 @@ - + Welcome to Multi-object trackers in Python’s documentation! — Multi-object trackers in Python 1.0.0 documentation @@ -16,6 +16,7 @@ + @@ -93,14 +94,71 @@

        Welcome to Multi-object trackers in Python’s documentation!Example: TF-MobileNetSSD + CentroidTracker
      • Example: YOLOv3 + CentroidTracker
      • -
      • Tracker
      • -
      • SORT
      • -
      • IOU Tracker
      • -
      • Kalman Filter based Centroid Tracker
      • -
      • Tracks
      • -
      • Kalman Filters
      • -
      • Object Detection
      • +
      • Tracker +
      • +
      • SORT +
      • +
      • IOU Tracker +
      • +
      • Kalman Filter based Centroid Tracker +
      • +
      • Tracks +
      • +
      • Kalman Filters +
      • +
      • Object Detection +
      • Utilities
      • diff --git a/docs/objects.inv b/docs/objects.inv index c99bf18ad4f80687c5f31a9d4dc269476868c97c..fb1e2e630ff1042e647cffd2e08f91fb52c8e933 100644 GIT binary patch delta 817 zcmV-11J3-<0jeotE-EP|;6vyxL6rQ%*cxu+G-c5}nRb7{A={D^O5jc)%`LF;t z@!eiyueT=|_^Zj9wyMFsv1~BE|M>uXuuxWGatGR^1fWpw~OmdPiNq9*?z(-s#sz@o^>n6>u;O{>q(}{R3JS_`~Eq{0o0XA1OT*O(*HnMp% zGYS@nWlEy{UCNBbl7R85St;x8*XcG?Sbxzb!#*?6X{O44`F}YFF+n^#O)@^}d zrOtm8@1D!6J5w3NWKr5k)&=@nTE_DI0Lt)#7K_9(6lp#thPeU$Og z-w>`!ZrN0=Z~bqyE(GrV}F5>h^ vj4Fz1+I6%BDq1>cnrQ9yzA&uOJsfQSYmy%hY}%SJtET@NZ(#BdYFskg83Ub9 delta 202 zcmV;*05$)y2hReKjemuZO%B2!5QX=g0uNA)TW{dPq=_c3DU2-&jDaDsJFnsOJc+IJ zH)+xx%$xVkyeYwHr{Ki{se=&(7@qBU*;Tg{S;LR*lW8YSRA6Bzo?4-d7954YulcpE z<&MO-cp)F)Cln7tS-5Ef%ZyP^gi|!6Gc4{PiBrObrl03ERYU057-K*U39euyTHu6h znD6@&c)z#P^L1yRK&OuE)YU9qLPb9VsYWi>aZTJoHeo{JLL53)a_ E_zq@ZsQ>@~ diff --git a/docs/search.html b/docs/search.html index fcb2965..165fbf6 100644 --- a/docs/search.html +++ b/docs/search.html @@ -16,6 +16,7 @@ + diff --git a/docs/searchindex.js b/docs/searchindex.js index 5e37ab0..4e244bb 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["includeme/apidocuments", "includeme/readmefile", "index"], "filenames": ["includeme/apidocuments.rst", "includeme/readmefile.rst", "index.rst"], "titles": ["Tracker", "Multi-object trackers in Python", "Welcome to Multi-object trackers in Python\u2019s documentation!"], "terms": {"webpag": 0, "github": [0, 1], "cd": [0, 1], "multi": 0, "exampl": [0, 2], "pretrained_model": 0, "yolo_weight": 0, "sudo": 0, "chmod": 0, "x": [0, 1], "get_yolo": 0, "sh": 0, "tensorflow_weight": 0, "get_ssd_model": 0, "caffemodel_weight": 0, "get_caffemodel": 0, "thi": [0, 1], "work": [0, 1], "i": [0, 1], "follow": [0, 1], "literatur": 0, "bochinski": 0, "e": [0, 1], "eiselein": 0, "v": 0, "sikora": 0, "t": 0, "2017": 0, "august": 0, "high": 0, "speed": 0, "without": 0, "us": [0, 2], "imag": [0, 1], "inform": 0, "In": [0, 1], "14th": 0, "ieee": 0, "intern": 0, "confer": 0, "advanc": 0, "video": 0, "signal": 0, "surveil": 0, "avss": 0, "pp": 0, "1": [0, 1], "6": 0, "pdf": 0, "bewlei": 0, "A": 0, "ge": 0, "z": [0, 1], "ott": 0, "l": 0, "ramo": 0, "f": 0, "upcroft": 0, "b": 0, "2016": 0, "septemb": 0, "simpl": [0, 1], "onlin": 0, "realtim": 0, "process": 0, "icip": 0, "3464": 0, "3468": 0, "arxiv": 0, "websit": 0, "wiki": 0, "api": 0, "caff": 0, "opencv": [0, 2], "interest": 0, "foster": 0, "an": [0, 1], "open": 0, "welcom": 0, "environ": 0, "we": 0, "maintain": 0, "make": 0, "particip": 0, "project": 0, "commun": 0, "harass": 0, "free": 0, "experi": 0, "everyon": 0, "regardless": 0, "ag": 0, "bodi": 0, "size": 0, "disabl": 0, "ethnic": 0, "sex": 0, "characterist": 0, "gender": 0, "ident": 0, "express": 0, "level": 0, "educ": 0, "socio": 0, "econom": 0, "statu": 0, "nation": 0, "person": 0, "appear": [0, 1], "race": 0, "religion": 0, "sexual": 0, "orient": 0, "behavior": 0, "contribut": [0, 2], "creat": [0, 1], "posit": 0, "includ": 0, "inclus": 0, "languag": 0, "Being": 0, "respect": [0, 1], "differ": 0, "viewpoint": 0, "gracefulli": 0, "accept": [0, 1], "construct": 0, "critic": 0, "focus": 0, "what": [0, 1], "best": 0, "show": 0, "empathi": 0, "toward": 0, "other": 0, "member": 0, "unaccept": 0, "The": [0, 1], "imageri": 0, "unwelcom": 0, "attent": 0, "troll": 0, "insult": 0, "derogatori": 0, "comment": 0, "polit": 0, "attack": 0, "public": 0, "privat": 0, "publish": [0, 1], "physic": 0, "electron": 0, "address": 0, "explicit": 0, "permiss": 0, "which": 0, "could": 0, "reason": 0, "consid": [0, 1], "inappropri": 0, "profession": 0, "set": 0, "ar": [0, 1], "clarifi": 0, "expect": 0, "take": 0, "appropri": 0, "fair": 0, "correct": 0, "action": 0, "ani": [0, 1], "instanc": 0, "have": [0, 1], "right": 0, "remov": 0, "edit": 0, "reject": 0, "commit": 0, "issu": [0, 1], "align": 0, "ban": 0, "temporarili": 0, "perman": 0, "thei": 0, "deem": 0, "threaten": 0, "offens": 0, "harm": 0, "appli": 0, "both": 0, "within": 0, "space": 0, "when": 0, "individu": 0, "repres": 0, "its": 0, "offici": 0, "mail": 0, "post": 0, "via": 0, "social": 0, "media": 0, "account": 0, "act": 0, "appoint": 0, "offlin": 0, "event": 0, "represent": 0, "mai": [0, 1], "further": 0, "defin": 0, "abus": 0, "otherwis": 0, "report": 0, "contact": 0, "team": 0, "adityadeshpande2010": 0, "gmail": 0, "com": [0, 1], "all": 0, "complaint": 0, "review": 0, "investig": 0, "result": 0, "necessari": 0, "circumst": 0, "oblig": 0, "confidenti": 0, "regard": 0, "incid": 0, "detail": [0, 1], "specif": 0, "polici": 0, "separ": 0, "who": 0, "do": 0, "good": 0, "faith": 0, "face": 0, "temporari": 0, "repercuss": 0, "determin": 0, "": 0, "leadership": 0, "adapt": 0, "from": [0, 1], "version": [0, 1], "4": [0, 1], "avail": [0, 2], "http": [0, 1], "www": 0, "org": 0, "html": 0, "For": [0, 1], "answer": 0, "common": 0, "question": 0, "about": 0, "see": [0, 1], "faq": 0, "easi": 1, "implement": 1, "variou": 1, "track": [1, 2], "algorithm": 1, "ioutrack": 1, "centroidkf_track": 1, "sort": [1, 2], "tf_ssdmobilenetv2": 1, "caffe_ssdmobilenet": 1, "pip": 1, "3": 1, "later": 1, "here": 1, "can": 1, "done": 1, "command": 1, "motrack": 1, "addition": 1, "you": 1, "packag": 1, "through": 1, "instead": 1, "git": 1, "clone": 1, "adipanda": 1, "neural": [1, 2], "network": [1, 2], "gpu": 1, "dnn": 1, "modul": 1, "provid": 1, "repositori": 1, "compil": 1, "cuda": 1, "enabl": 1, "sourc": 1, "To": 1, "build": 1, "link": 1, "2": 1, "interfac": 1, "each": 1, "similar": 1, "pleas": 1, "templat": 1, "below": 1, "import": 1, "input_data": 1, "while": 1, "true": 1, "read": 1, "break": 1, "detection_bbox": 1, "detection_confid": 1, "detection_class_id": 1, "numpi": 1, "ndarrai": 1, "shape": 1, "n": 1, "row": 1, "contain": 1, "bb_left": 1, "bb_top": 1, "bb_width": 1, "bb_height": 1, "output_track": 1, "updat": 1, "list": 1, "element": 1, "tupl": 1, "frame": 1, "id": 1, "conf": 1, "y": 1, "confid": 1, "assert": 1, "len": 1, "10": 1, "print": 1, "folder": 1, "more": 1, "run": 1, "download": [1, 2], "weight": [1, 2], "shell": 1, "script": 1, "download_weight": 1, "md": 1, "There": 1, "some": 1, "variat": 1, "compar": 1, "paper": 1, "iou": [1, 2], "case": 1, "find": 1, "bug": 1, "happi": 1, "your": 1, "pull": 1, "request": 1, "point": 1, "out": 1, "If": 1, "cite": 1, "misc": 1, "multiobjtracker_amd2018": 1, "author": 1, "deshpand": 1, "aditya": 1, "m": 1, "titl": 1, "year": 1, "2020": 1, "journal": 1, "howpublish": 1, "url": 1, "base": 2, "detector": 2, "instal": 2, "how": 2, "pretrain": 2, "detect": 2, "model": 2, "refer": 2, "credit": 2, "citat": 2, "tf": 2, "mobilenetssd": 2, "centroidtrack": 2, "yolov3": 2, "kalman": 2, "filter": 2, "centroid": 2, "util": 2, "contributor": 2, "coven": 2, "code": 2, "conduct": 2, "our": 2, "pledg": 2, "standard": 2, "respons": 2, "scope": 2, "enforc": 2, "attribut": 2, "index": 2}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"tracker": [0, 1, 2], "sort": 0, "iou": 0, "kalman": 0, "filter": 0, "base": [0, 1], "centroid": 0, "track": 0, "object": [0, 1, 2], "detect": [0, 1], "util": 0, "download": 0, "pretrain": [0, 1], "neural": 0, "network": 0, "weight": 0, "yolov3": [0, 1], "tensorflow": 0, "mobilenetssdv2": 0, "caffemodel": 0, "mobilenetssd": [0, 1], "refer": [0, 1], "credit": [0, 1], "contributor": 0, "coven": 0, "code": 0, "conduct": 0, "our": 0, "pledg": 0, "standard": 0, "respons": 0, "scope": 0, "enforc": 0, "attribut": 0, "multi": [1, 2], "python": [1, 2], "avail": 1, "opencv": 1, "detector": 1, "instal": 1, "how": 1, "us": 1, "exampl": 1, "model": 1, "note": 1, "contribut": 1, "citat": 1, "tf": 1, "centroidtrack": 1, "welcom": 2, "": 2, "document": 2, "indic": 2, "tabl": 2}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx": 56}}) \ No newline at end of file +Search.setIndex({"docnames": ["includeme/apidocuments", "includeme/readmefile", "index"], "filenames": ["includeme/apidocuments.rst", "includeme/readmefile.rst", "index.rst"], "titles": ["Tracker", "Multi-object trackers in Python", "Welcome to Multi-object trackers in Python\u2019s documentation!"], "terms": {"class": 0, "motrack": [0, 1], "max_lost": 0, "5": 0, "tracker_output_format": 0, "mot_challeng": 0, "sourc": [0, 1], "greedi": 0, "locat": 0, "bound": 0, "box": 0, "thi": [0, 1], "i": [0, 1], "also": 0, "centroidtrack": [0, 2], "repositori": [0, 1], "paramet": 0, "int": 0, "maximum": 0, "number": 0, "consecut": 0, "frame": [0, 1], "wa": 0, "str": 0, "output": 0, "format": 0, "static": 0, "preprocess_input": 0, "bbox": 0, "class_id": 0, "detection_scor": 0, "preprocess": 0, "input": 0, "data": 0, "list": [0, 1], "numpi": [0, 1], "ndarrai": [0, 1], "arrai": 0, "each": [0, 1], "tupl": [0, 1], "contain": [0, 1], "xmin": 0, "ymin": 0, "width": 0, "height": 0, "id": [0, 1], "label": 0, "score": 0, "k": 0, "probabl": 0, "return": 0, "type": 0, "updat": [0, 1], "new": 0, "current": 0, "element": [0, 1], "repres": 0, "coordin": 0, "top": 0, "left": 0, "x": [0, 1], "y": [0, 1], "correspond": 0, "default": 0, "none": 0, "being": 0, "frame_id": 0, "track_id": 0, "bb_left": [0, 1], "bb_top": [0, 1], "bb_width": [0, 1], "bb_height": [0, 1], "conf": [0, 1], "z": [0, 1], "sort_track": 0, "assign_tracks2detection_i": [0, 2], "bbox_track": 0, "bbox_detect": 0, "iou_threshold": 0, "0": 0, "3": [0, 1], "assign": 0, "us": [0, 2], "distanc": 0, "metric": 0, "shape": [0, 1], "n": [0, 1], "4": [0, 1], "where": 0, "alreadi": 0, "m": [0, 1], "ar": [0, 1], "newli": 0, "float": 0, "threashold": 0, "follow": [0, 1], "given": 0, "order": 0, "match": 0, "2": [0, 1], "pair": 0, "form": 0, "after": 0, "an": [0, 1], "indic": 0, "track_index": 0, "detection_index": 0, "unmatched_detect": 0, "unmatch": 0, "unmatched_track": 0, "process_noise_scal": 0, "1": [0, 1], "measurement_noise_scal": 0, "time_step": 0, "multi": 0, "max": 0, "time": 0, "lost": 0, "while": [0, 1], "intersect": 0, "over": 0, "union": 0, "minimum": 0, "valu": 0, "process": 0, "nois": 0, "covari": 0, "matrix": 0, "magnitud": 0, "scalar": 0, "measur": 0, "step": 0, "iou_track": 0, "ioutrack": [0, 1, 2], "min_detection_confid": 0, "max_detection_confid": 0, "7": 0, "implement": [0, 1], "algorithm": [0, 1], "heavili": 0, "http": [0, 1], "github": [0, 1], "com": [0, 1], "bochinski": 0, "threshold": 0, "confid": [0, 1], "centroid_kf_track": 0, "assign_tracks2detection_centroid_dist": [0, 2], "distance_threshold": 0, "10": [0, 1], "row": [0, 1], "between": 0, "consid": [0, 1], "centroidkf_track": [0, 1, 2], "centroid_distance_threshold": 0, "30": 0, "multipl": 0, "detection_confid": [0, 1], "iou_scor": 0, "data_output_format": 0, "kwarg": 0, "variou": [0, 1], "camera": 0, "pixel": 0, "option": 0, "includ": 0, "visdrone_challeng": 0, "dict": 0, "addit": 0, "kei": 0, "word": 0, "argument": 0, "properti": 0, "get_mot_challenge_format": 0, "get": 0, "mot": 0, "challeng": 0, "websit": 0, "motchalleng": 0, "net": 0, "get_vis_drone_format": 0, "visdron": 0, "frame_index": 0, "target_id": 0, "bbox_left": 0, "bbox_top": 0, "bbox_width": 0, "bbox_height": 0, "object_categori": 0, "truncat": 0, "occlus": 0, "aiskyey": 0, "paper": [0, 1], "arxiv": 0, "org": 0, "ab": 0, "2001": 0, "06303": 0, "visdrone2018": 0, "toolkit": 0, "predict": 0, "next": 0, "estim": 0, "kftracksort": [0, 2], "scale": 0, "kftrack4dsort": [0, 2], "kf_time_step": 0, "kftrackcentroid": [0, 2], "kalman_track": 0, "kalmanfilt": [0, 2], "transition_matrix": 0, "measurement_matrix": 0, "control_matrix": 0, "process_noise_covari": 0, "measurement_noise_covari": 0, "prediction_covari": 0, "initial_st": 0, "transit": 0, "control": 0, "priori": 0, "initi": 0, "state": 0, "u": 0, "vector": 0, "system": 0, "kftrackerconstantacceler": [0, 2], "initial_measur": 0, "constant": 0, "acceler": 0, "kinemat": 0, "model": [0, 2], "kftracker1d": [0, 2], "kftracker2d": [0, 2], "kftracker4d": [0, 2], "kftrackersort": [0, 2], "xmid": 0, "ymid": 0, "area": 0, "aspect_ratio": 0, "detector": [0, 2], "object_nam": 0, "confidence_threshold": 0, "nms_threshold": 0, "draw_bbox": 0, "true": [0, 1], "abstract": 0, "dictionari": 0, "class_nam": 0, "non": 0, "maxim": 0, "suppress": 0, "bool": 0, "If": [0, 1], "draw": 0, "imag": [0, 1], "possibl": 0, "label_id": 0, "about": 0, "video": 0, "aka": 0, "drawn": 0, "forward": 0, "pass": 0, "caff": 0, "caffe_ssdmobilenet": [0, 1, 2], "weights_path": 0, "configfile_path": 0, "labels_path": 0, "use_gpu": 0, "fals": 0, "ssd": 0, "mobilenet": 0, "path": 0, "file": 0, "configur": 0, "json": 0, "select": 0, "color": 0, "try": 0, "load": 0, "gpu": [0, 1], "tf": [0, 2], "tf_ssdmobilenetv2": [0, 1, 2], "mobilenetv2": 0, "yolo": 0, "modul": [0, 1], "misc": [0, 1], "get_centroid": [0, 2], "calcul": 0, "bbox1": 0, "bbox2": 0, "two": 0, "blob": 0, "master": 0, "py": 0, "length": 0, "bottom": 0, "right": 0, "onion": 0, "iou_xywh": [0, 2], "xyxy2xywh": [0, 2], "xyxi": 0, "convert": 0, "from": [0, 1], "xmax": 0, "ymax": 0, "xywh2xyxi": [0, 2], "xywh": 0, "midwh2xywh": [0, 2], "midwh": 0, "intersection_complement_indic": [0, 2], "big_set_indic": 0, "small_set_indic": 0, "complement": 0, "set": 0, "big": 0, "small": 0, "which": 0, "complementari": 0, "nm": [0, 2], "overlapthresh": 0, "malisiewicz": 0, "et": 0, "al": 0, "overlap": 0, "merg": 0, "specifi": 0, "draw_track": [0, 2], "load_labelsjson": [0, 2], "json_fil": 0, "dict2jsonfil": [0, 2], "dict_data": 0, "json_file_path": 0, "filechooser_util": 0, "create_filechoos": [0, 2], "default_path": 0, "html_titl": 0, "use_dir_icon": 0, "select_caffemodel_prototxt": [0, 2], "select_caffemodel_weight": [0, 2], "select_caffemodel": [0, 2], "select_videofil": [0, 2], "select_yolo_weight": [0, 2], "select_coco_label": [0, 2], "select_yolo_config": [0, 2], "select_yolo_model": [0, 2], "select_pbtxt": [0, 2], "select_tfmobilenet_weight": [0, 2], "select_tfmobilenet": [0, 2], "webpag": 0, "cd": [0, 1], "exampl": [0, 2], "pretrained_model": 0, "yolo_weight": 0, "sudo": 0, "chmod": 0, "get_yolo": 0, "sh": 0, "tensorflow_weight": 0, "get_ssd_model": 0, "caffemodel_weight": 0, "get_caffemodel": 0, "work": [0, 1], "literatur": 0, "e": [0, 1], "eiselein": 0, "v": 0, "sikora": 0, "t": 0, "2017": 0, "august": 0, "high": 0, "speed": 0, "without": 0, "inform": 0, "In": [0, 1], "14th": 0, "ieee": 0, "intern": 0, "confer": 0, "advanc": 0, "signal": 0, "surveil": 0, "avss": 0, "pp": 0, "6": 0, "pdf": 0, "bewlei": 0, "A": 0, "ge": 0, "ott": 0, "l": 0, "ramo": 0, "f": 0, "upcroft": 0, "b": 0, "2016": 0, "septemb": 0, "simpl": [0, 1], "onlin": 0, "realtim": 0, "icip": 0, "3464": 0, "3468": 0, "wiki": 0, "api": 0, "opencv": [0, 2], "interest": 0, "foster": 0, "open": 0, "welcom": 0, "environ": 0, "we": 0, "maintain": 0, "make": 0, "particip": 0, "project": 0, "commun": 0, "harass": 0, "free": 0, "experi": 0, "everyon": 0, "regardless": 0, "ag": 0, "bodi": 0, "size": 0, "disabl": 0, "ethnic": 0, "sex": 0, "characterist": 0, "gender": 0, "ident": 0, "express": 0, "level": 0, "educ": 0, "socio": 0, "econom": 0, "statu": 0, "nation": 0, "person": 0, "appear": [0, 1], "race": 0, "religion": 0, "sexual": 0, "orient": 0, "behavior": 0, "contribut": [0, 2], "creat": [0, 1], "posit": 0, "inclus": 0, "languag": 0, "Being": 0, "respect": [0, 1], "differ": 0, "viewpoint": 0, "gracefulli": 0, "accept": [0, 1], "construct": 0, "critic": 0, "focus": 0, "what": [0, 1], "best": 0, "show": 0, "empathi": 0, "toward": 0, "other": 0, "member": 0, "unaccept": 0, "The": [0, 1], "imageri": 0, "unwelcom": 0, "attent": 0, "troll": 0, "insult": 0, "derogatori": 0, "comment": 0, "polit": 0, "attack": 0, "public": 0, "privat": 0, "publish": [0, 1], "physic": 0, "electron": 0, "address": 0, "explicit": 0, "permiss": 0, "could": 0, "reason": 0, "inappropri": 0, "profession": 0, "clarifi": 0, "expect": 0, "take": 0, "appropri": 0, "fair": 0, "correct": 0, "action": 0, "ani": [0, 1], "instanc": 0, "have": [0, 1], "remov": 0, "edit": 0, "reject": 0, "commit": 0, "issu": [0, 1], "align": 0, "ban": 0, "temporarili": 0, "perman": 0, "thei": 0, "deem": 0, "threaten": 0, "offens": 0, "harm": 0, "appli": 0, "both": 0, "within": 0, "space": 0, "when": 0, "individu": 0, "its": 0, "offici": 0, "mail": 0, "post": 0, "via": 0, "social": 0, "media": 0, "account": 0, "act": 0, "appoint": 0, "offlin": 0, "event": 0, "represent": 0, "mai": [0, 1], "further": 0, "defin": 0, "abus": 0, "otherwis": 0, "report": 0, "contact": 0, "team": 0, "adityadeshpande2010": 0, "gmail": 0, "all": 0, "complaint": 0, "review": 0, "investig": 0, "result": 0, "necessari": 0, "circumst": 0, "oblig": 0, "confidenti": 0, "regard": 0, "incid": 0, "detail": [0, 1], "specif": 0, "polici": 0, "separ": 0, "who": 0, "do": 0, "good": 0, "faith": 0, "face": 0, "temporari": 0, "repercuss": 0, "determin": 0, "": 0, "leadership": 0, "adapt": 0, "version": [0, 1], "avail": [0, 2], "www": 0, "html": 0, "For": [0, 1], "answer": 0, "common": 0, "question": 0, "see": [0, 1], "faq": 0, "easi": 1, "track": [1, 2], "sort": [1, 2], "pip": 1, "later": 1, "here": 1, "can": 1, "done": 1, "command": 1, "addition": 1, "you": 1, "packag": 1, "through": 1, "instead": 1, "git": 1, "clone": 1, "adipanda": 1, "neural": [1, 2], "network": [1, 2], "dnn": 1, "provid": 1, "compil": 1, "cuda": 1, "enabl": 1, "To": 1, "build": 1, "link": 1, "interfac": 1, "similar": 1, "pleas": 1, "templat": 1, "below": 1, "import": 1, "input_data": 1, "read": 1, "break": 1, "detection_bbox": 1, "detection_class_id": 1, "output_track": 1, "assert": 1, "len": 1, "print": 1, "folder": 1, "more": 1, "run": 1, "download": [1, 2], "weight": [1, 2], "shell": 1, "script": 1, "download_weight": 1, "md": 1, "There": 1, "some": 1, "variat": 1, "compar": 1, "iou": [1, 2], "case": 1, "find": 1, "bug": 1, "happi": 1, "your": 1, "pull": 1, "request": 1, "point": 1, "out": 1, "cite": 1, "multiobjtracker_amd2018": 1, "author": 1, "deshpand": 1, "aditya": 1, "titl": 1, "year": 1, "2020": 1, "journal": 1, "howpublish": 1, "url": 1, "base": 2, "instal": 2, "how": 2, "pretrain": 2, "detect": 2, "refer": 2, "credit": 2, "citat": 2, "mobilenetssd": 2, "yolov3": 2, "kalman": 2, "filter": 2, "centroid": 2, "util": 2, "contributor": 2, "coven": 2, "code": 2, "conduct": 2, "our": 2, "pledg": 2, "standard": 2, "respons": 2, "scope": 2, "enforc": 2, "attribut": 2, "index": 2}, "objects": {"motrackers.centroid_kf_tracker": [[0, 0, 1, "", "CentroidKF_Tracker"], [0, 2, 1, "", "assign_tracks2detection_centroid_distances"]], "motrackers.centroid_kf_tracker.CentroidKF_Tracker": [[0, 1, 1, "", "update"]], "motrackers.detectors.caffe": [[0, 0, 1, "", "Caffe_SSDMobileNet"]], "motrackers.detectors.caffe.Caffe_SSDMobileNet": [[0, 1, 1, "", "forward"]], "motrackers.detectors.detector": [[0, 0, 1, "", "Detector"]], "motrackers.detectors.detector.Detector": [[0, 1, 1, "", "detect"], [0, 1, 1, "", "draw_bboxes"], [0, 1, 1, "", "forward"]], "motrackers.detectors.tf": [[0, 0, 1, "", "TF_SSDMobileNetV2"]], "motrackers.detectors.tf.TF_SSDMobileNetV2": [[0, 1, 1, "", "forward"]], "motrackers.detectors.yolo": [[0, 0, 1, "", "YOLOv3"]], "motrackers.detectors.yolo.YOLOv3": [[0, 1, 1, "", "detect"], [0, 1, 1, "", "forward"]], "motrackers.iou_tracker": [[0, 0, 1, "", "IOUTracker"]], "motrackers.iou_tracker.IOUTracker": [[0, 1, 1, "", "update"]], "motrackers.kalman_tracker": [[0, 0, 1, "", "KFTracker1D"], [0, 0, 1, "", "KFTracker2D"], [0, 0, 1, "", "KFTracker4D"], [0, 0, 1, "", "KFTrackerConstantAcceleration"], [0, 0, 1, "", "KFTrackerSORT"], [0, 0, 1, "", "KalmanFilter"]], "motrackers.kalman_tracker.KalmanFilter": [[0, 1, 1, "", "predict"], [0, 1, 1, "", "update"]], "motrackers.sort_tracker": [[0, 0, 1, "", "SORT"], [0, 2, 1, "", "assign_tracks2detection_iou"]], "motrackers.sort_tracker.SORT": [[0, 1, 1, "", "update"]], "motrackers.track": [[0, 0, 1, "", "KFTrack4DSORT"], [0, 0, 1, "", "KFTrackCentroid"], [0, 0, 1, "", "KFTrackSORT"], [0, 0, 1, "", "Track"]], "motrackers.track.KFTrack4DSORT": [[0, 1, 1, "", "predict"], [0, 1, 1, "", "update"]], "motrackers.track.KFTrackCentroid": [[0, 1, 1, "", "predict"], [0, 1, 1, "", "update"]], "motrackers.track.KFTrackSORT": [[0, 1, 1, "", "predict"], [0, 1, 1, "", "update"]], "motrackers.track.Track": [[0, 3, 1, "", "centroid"], [0, 1, 1, "", "get_mot_challenge_format"], [0, 1, 1, "", "get_vis_drone_format"], [0, 1, 1, "", "predict"], [0, 1, 1, "", "update"]], "motrackers.tracker": [[0, 0, 1, "", "Tracker"]], "motrackers.tracker.Tracker": [[0, 1, 1, "", "preprocess_input"], [0, 1, 1, "", "update"]], "motrackers.utils.filechooser_utils": [[0, 2, 1, "", "create_filechooser"], [0, 2, 1, "", "select_caffemodel"], [0, 2, 1, "", "select_caffemodel_prototxt"], [0, 2, 1, "", "select_caffemodel_weights"], [0, 2, 1, "", "select_coco_labels"], [0, 2, 1, "", "select_pbtxt"], [0, 2, 1, "", "select_tfmobilenet"], [0, 2, 1, "", "select_tfmobilenet_weights"], [0, 2, 1, "", "select_videofile"], [0, 2, 1, "", "select_yolo_config"], [0, 2, 1, "", "select_yolo_model"], [0, 2, 1, "", "select_yolo_weights"]], "motrackers.utils.misc": [[0, 2, 1, "", "dict2jsonfile"], [0, 2, 1, "", "draw_tracks"], [0, 2, 1, "", "get_centroid"], [0, 2, 1, "", "intersection_complement_indices"], [0, 2, 1, "", "iou"], [0, 2, 1, "", "iou_xywh"], [0, 2, 1, "", "load_labelsjson"], [0, 2, 1, "", "midwh2xywh"], [0, 2, 1, "", "nms"], [0, 2, 1, "", "xywh2xyxy"], [0, 2, 1, "", "xyxy2xywh"]]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:function", "3": "py:property"}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "function", "Python function"], "3": ["py", "property", "Python property"]}, "titleterms": {"tracker": [0, 1, 2], "sort": 0, "iou": 0, "kalman": 0, "filter": 0, "base": [0, 1], "centroid": 0, "track": 0, "object": [0, 1, 2], "detect": [0, 1], "util": 0, "download": 0, "pretrain": [0, 1], "neural": 0, "network": 0, "weight": 0, "yolov3": [0, 1], "tensorflow": 0, "mobilenetssdv2": 0, "caffemodel": 0, "mobilenetssd": [0, 1], "refer": [0, 1], "credit": [0, 1], "contributor": 0, "coven": 0, "code": 0, "conduct": 0, "our": 0, "pledg": 0, "standard": 0, "respons": 0, "scope": 0, "enforc": 0, "attribut": 0, "multi": [1, 2], "python": [1, 2], "avail": 1, "opencv": 1, "detector": 1, "instal": 1, "how": 1, "us": 1, "exampl": 1, "model": 1, "note": 1, "contribut": 1, "citat": 1, "tf": 1, "centroidtrack": 1, "welcom": 2, "": 2, "document": 2, "indic": 2, "tabl": 2}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx": 57}, "alltitles": {"Tracker": [[0, "tracker"]], "SORT": [[0, "sort"]], "IOU Tracker": [[0, "iou-tracker"]], "Kalman Filter based Centroid Tracker": [[0, "kalman-filter-based-centroid-tracker"]], "Tracks": [[0, "tracks"]], "Kalman Filters": [[0, "kalman-filters"]], "Object Detection": [[0, "object-detection"]], "Utilities": [[0, "utilities"]], "Download pretrained neural-network weights.": [[0, "download-pretrained-neural-network-weights"]], "YOLOv3": [[0, "yolov3"]], "TensorFlow - MobileNetSSDv2": [[0, "tensorflow-mobilenetssdv2"]], "Caffemodel - MobileNetSSD": [[0, "caffemodel-mobilenetssd"]], "References and Credits": [[0, "references-and-credits"]], "Contributor Covenant Code of Conduct": [[0, "contributor-covenant-code-of-conduct"]], "Our Pledge": [[0, "our-pledge"]], "Our Standards": [[0, "our-standards"]], "Our Responsibilities": [[0, "our-responsibilities"]], "Scope": [[0, "scope"]], "Enforcement": [[0, "enforcement"]], "Attribution": [[0, "attribution"]], "Multi-object trackers in Python": [[1, "multi-object-trackers-in-python"]], "Available Multi Object Trackers": [[1, "available-multi-object-trackers"]], "Available OpenCV-based object detectors:": [[1, "available-opencv-based-object-detectors"]], "Installation": [[1, "installation"]], "How to use?: Examples": [[1, "how-to-use-examples"]], "Pretrained object detection models": [[1, "pretrained-object-detection-models"]], "Notes": [[1, "notes"]], "References, Credits and Contributions": [[1, "references-credits-and-contributions"]], "Citation": [[1, "citation"]], "Example: TF-MobileNetSSD + CentroidTracker": [[1, "example-tf-mobilenetssd-centroidtracker"]], "Example: YOLOv3 + CentroidTracker": [[1, "example-yolov3-centroidtracker"]], "Welcome to Multi-object trackers in Python\u2019s documentation!": [[2, "welcome-to-multi-object-trackers-in-python-s-documentation"]], "Indices and tables": [[2, "indices-and-tables"]]}, "indexentries": {"caffe_ssdmobilenet (class in motrackers.detectors.caffe)": [[0, "motrackers.detectors.caffe.Caffe_SSDMobileNet"]], "centroidkf_tracker (class in motrackers.centroid_kf_tracker)": [[0, "motrackers.centroid_kf_tracker.CentroidKF_Tracker"]], "detector (class in motrackers.detectors.detector)": [[0, "motrackers.detectors.detector.Detector"]], "ioutracker (class in motrackers.iou_tracker)": [[0, "motrackers.iou_tracker.IOUTracker"]], "kftrack4dsort (class in motrackers.track)": [[0, "motrackers.track.KFTrack4DSORT"]], "kftrackcentroid (class in motrackers.track)": [[0, "motrackers.track.KFTrackCentroid"]], "kftracksort (class in motrackers.track)": [[0, "motrackers.track.KFTrackSORT"]], "kftracker1d (class in motrackers.kalman_tracker)": [[0, "motrackers.kalman_tracker.KFTracker1D"]], "kftracker2d (class in motrackers.kalman_tracker)": [[0, "motrackers.kalman_tracker.KFTracker2D"]], "kftracker4d (class in motrackers.kalman_tracker)": [[0, "motrackers.kalman_tracker.KFTracker4D"]], "kftrackerconstantacceleration (class in motrackers.kalman_tracker)": [[0, "motrackers.kalman_tracker.KFTrackerConstantAcceleration"]], "kftrackersort (class in motrackers.kalman_tracker)": [[0, "motrackers.kalman_tracker.KFTrackerSORT"]], "kalmanfilter (class in motrackers.kalman_tracker)": [[0, "motrackers.kalman_tracker.KalmanFilter"]], "sort (class in motrackers.sort_tracker)": [[0, "motrackers.sort_tracker.SORT"]], "tf_ssdmobilenetv2 (class in motrackers.detectors.tf)": [[0, "motrackers.detectors.tf.TF_SSDMobileNetV2"]], "track (class in motrackers.track)": [[0, "motrackers.track.Track"]], "tracker (class in motrackers.tracker)": [[0, "motrackers.tracker.Tracker"]], "yolov3 (class in motrackers.detectors.yolo)": [[0, "motrackers.detectors.yolo.YOLOv3"]], "assign_tracks2detection_centroid_distances() (in module motrackers.centroid_kf_tracker)": [[0, "motrackers.centroid_kf_tracker.assign_tracks2detection_centroid_distances"]], "assign_tracks2detection_iou() (in module motrackers.sort_tracker)": [[0, "motrackers.sort_tracker.assign_tracks2detection_iou"]], "centroid (motrackers.track.track property)": [[0, "motrackers.track.Track.centroid"]], "create_filechooser() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.create_filechooser"]], "detect() (motrackers.detectors.detector.detector method)": [[0, "motrackers.detectors.detector.Detector.detect"]], "detect() (motrackers.detectors.yolo.yolov3 method)": [[0, "motrackers.detectors.yolo.YOLOv3.detect"]], "dict2jsonfile() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.dict2jsonfile"]], "draw_bboxes() (motrackers.detectors.detector.detector method)": [[0, "motrackers.detectors.detector.Detector.draw_bboxes"]], "draw_tracks() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.draw_tracks"]], "forward() (motrackers.detectors.caffe.caffe_ssdmobilenet method)": [[0, "motrackers.detectors.caffe.Caffe_SSDMobileNet.forward"]], "forward() (motrackers.detectors.detector.detector method)": [[0, "motrackers.detectors.detector.Detector.forward"]], "forward() (motrackers.detectors.tf.tf_ssdmobilenetv2 method)": [[0, "motrackers.detectors.tf.TF_SSDMobileNetV2.forward"]], "forward() (motrackers.detectors.yolo.yolov3 method)": [[0, "motrackers.detectors.yolo.YOLOv3.forward"]], "get_centroid() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.get_centroid"]], "get_mot_challenge_format() (motrackers.track.track method)": [[0, "motrackers.track.Track.get_mot_challenge_format"]], "get_vis_drone_format() (motrackers.track.track method)": [[0, "motrackers.track.Track.get_vis_drone_format"]], "intersection_complement_indices() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.intersection_complement_indices"]], "iou() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.iou"]], "iou_xywh() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.iou_xywh"]], "load_labelsjson() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.load_labelsjson"]], "midwh2xywh() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.midwh2xywh"]], "nms() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.nms"]], "predict() (motrackers.kalman_tracker.kalmanfilter method)": [[0, "motrackers.kalman_tracker.KalmanFilter.predict"]], "predict() (motrackers.track.kftrack4dsort method)": [[0, "motrackers.track.KFTrack4DSORT.predict"]], "predict() (motrackers.track.kftrackcentroid method)": [[0, "motrackers.track.KFTrackCentroid.predict"]], "predict() (motrackers.track.kftracksort method)": [[0, "motrackers.track.KFTrackSORT.predict"]], "predict() (motrackers.track.track method)": [[0, "motrackers.track.Track.predict"]], "preprocess_input() (motrackers.tracker.tracker static method)": [[0, "motrackers.tracker.Tracker.preprocess_input"]], "select_caffemodel() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_caffemodel"]], "select_caffemodel_prototxt() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_caffemodel_prototxt"]], "select_caffemodel_weights() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_caffemodel_weights"]], "select_coco_labels() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_coco_labels"]], "select_pbtxt() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_pbtxt"]], "select_tfmobilenet() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_tfmobilenet"]], "select_tfmobilenet_weights() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_tfmobilenet_weights"]], "select_videofile() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_videofile"]], "select_yolo_config() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_yolo_config"]], "select_yolo_model() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_yolo_model"]], "select_yolo_weights() (in module motrackers.utils.filechooser_utils)": [[0, "motrackers.utils.filechooser_utils.select_yolo_weights"]], "update() (motrackers.centroid_kf_tracker.centroidkf_tracker method)": [[0, "motrackers.centroid_kf_tracker.CentroidKF_Tracker.update"]], "update() (motrackers.iou_tracker.ioutracker method)": [[0, "motrackers.iou_tracker.IOUTracker.update"]], "update() (motrackers.kalman_tracker.kalmanfilter method)": [[0, "motrackers.kalman_tracker.KalmanFilter.update"]], "update() (motrackers.sort_tracker.sort method)": [[0, "motrackers.sort_tracker.SORT.update"]], "update() (motrackers.track.kftrack4dsort method)": [[0, "motrackers.track.KFTrack4DSORT.update"]], "update() (motrackers.track.kftrackcentroid method)": [[0, "motrackers.track.KFTrackCentroid.update"]], "update() (motrackers.track.kftracksort method)": [[0, "motrackers.track.KFTrackSORT.update"]], "update() (motrackers.track.track method)": [[0, "motrackers.track.Track.update"]], "update() (motrackers.tracker.tracker method)": [[0, "motrackers.tracker.Tracker.update"]], "xywh2xyxy() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.xywh2xyxy"]], "xyxy2xywh() (in module motrackers.utils.misc)": [[0, "motrackers.utils.misc.xyxy2xywh"]]}}) \ No newline at end of file From 038fdda71cdd87560d34de8913ed9f5c2d77c0ec Mon Sep 17 00:00:00 2001 From: adg4jfx Date: Thu, 10 Aug 2023 10:31:29 +0200 Subject: [PATCH 3/8] fixed bug: hard coded iou_threshold --- motrackers/sort_tracker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motrackers/sort_tracker.py b/motrackers/sort_tracker.py index baaf174..0a3519d 100644 --- a/motrackers/sort_tracker.py +++ b/motrackers/sort_tracker.py @@ -140,7 +140,7 @@ def update(self, bboxes, detection_scores, class_ids): self._remove_track(track_id) else: matches, unmatched_detections, unmatched_tracks = assign_tracks2detection_iou( - bbox_tracks, bbox_detections, iou_threshold=0.3) + bbox_tracks, bbox_detections, iou_threshold=self.iou_threshold) for i in range(matches.shape[0]): t, d = matches[i, :] From b1a3bfb2043cf04e93a7073b8abe1ee70edabb38 Mon Sep 17 00:00:00 2001 From: Parthiban Marimuthu <66585214+partheee@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:43:00 +0530 Subject: [PATCH 4/8] Update yolo.py --- motrackers/detectors/yolo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motrackers/detectors/yolo.py b/motrackers/detectors/yolo.py index d6fd24d..e153fa5 100644 --- a/motrackers/detectors/yolo.py +++ b/motrackers/detectors/yolo.py @@ -23,7 +23,7 @@ def __init__(self, weights_path, configfile_path, labels_path, confidence_thresh object_names = load_labelsjson(labels_path) layer_names = self.net.getLayerNames() - if cv2.__version__ == '4.6.0': + if cv.__version__ == '4.6.0': self.layer_names = [layer_names[i - 1] for i in self.net.getUnconnectedOutLayers()] else: self.layer_names = [layer_names[i[0] - 1] for i in self.net.getUnconnectedOutLayers()] From b8ac59a64bd422274fd6e1afb58ee331c7f6493b Mon Sep 17 00:00:00 2001 From: Parthiban Marimuthu <66585214+partheee@users.noreply.github.com> Date: Thu, 21 Sep 2023 14:34:24 +0530 Subject: [PATCH 5/8] Update motrackers/detectors/yolo.py Co-authored-by: taekim027 --- motrackers/detectors/yolo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motrackers/detectors/yolo.py b/motrackers/detectors/yolo.py index e153fa5..ee169ec 100644 --- a/motrackers/detectors/yolo.py +++ b/motrackers/detectors/yolo.py @@ -23,7 +23,7 @@ def __init__(self, weights_path, configfile_path, labels_path, confidence_thresh object_names = load_labelsjson(labels_path) layer_names = self.net.getLayerNames() - if cv.__version__ == '4.6.0': + if cv.__version__ >= '4.6.0': self.layer_names = [layer_names[i - 1] for i in self.net.getUnconnectedOutLayers()] else: self.layer_names = [layer_names[i[0] - 1] for i in self.net.getUnconnectedOutLayers()] From c9ba8e23d2a0e6128ca1fce7cdbbe4b33727e6a7 Mon Sep 17 00:00:00 2001 From: adipandas Date: Tue, 10 Oct 2023 14:34:29 -0400 Subject: [PATCH 6/8] Bug fix in tracker.py [issue #48] --- motrackers/tracker.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/motrackers/tracker.py b/motrackers/tracker.py index da92b19..cbbff58 100644 --- a/motrackers/tracker.py +++ b/motrackers/tracker.py @@ -83,9 +83,10 @@ def _get_tracks(tracks): """ outputs = [] - for trackid, track in tracks.items(): - if not track.lost: - outputs.append(track.output()) + for _, track in tracks.items(): + # if not track.lost: + # outputs.append(track.output()) + outputs.append(track.output()) return outputs @staticmethod From a1a7f7e7d2ef3e05fba39007eb24bce1e44df29a Mon Sep 17 00:00:00 2001 From: adipandas Date: Tue, 10 Oct 2023 14:43:54 -0400 Subject: [PATCH 7/8] Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cd96f5f..f2ff5ba 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Easy to use implementation of various multi-object tracking algorithms. [![DOI](https://zenodo.org/badge/148338463.svg)](https://zenodo.org/badge/latestdoi/148338463) -[![Upload motrackers to PyPI](https://github.com/adipandas/multi-object-tracker/actions/workflows/python-publish.yml/badge.svg)](https://github.com/adipandas/multi-object-tracker/actions/workflows/python-publish.yml) + `YOLOv3 + CentroidTracker` | `TF-MobileNetSSD + CentroidTracker` From ce7130a35eed57c8d0552b8b35e62edbe8386100 Mon Sep 17 00:00:00 2001 From: adipandas Date: Tue, 10 Oct 2023 14:56:53 -0400 Subject: [PATCH 8/8] v0.0.2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 155c620..6ce1ac0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "motrackers" -version = "0.0.1" +version = "0.0.2" description = "Multi-object trackers in Python" authors = [ {name = "Aditya M. Deshpande", email = "adityadeshpande2010@gmail.com"}