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

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/forge/baranekresorts.com/node_modules/flatpickr/src/flatpickr.js
/*! flatpickr v2.6.2, @license MIT */
function Flatpickr(element, config) {
	const self = this;

	self._ = {};
	self._.afterDayAnim = afterDayAnim;
	self.changeMonth = changeMonth;
	self.changeYear = changeYear;
	self.clear = clear;
	self.close = close;
	self._createElement = createElement;
	self.destroy = destroy;
	self.isEnabled = isEnabled;
	self.jumpToDate = jumpToDate;
	self.open = open;
	self.redraw = redraw;
	self.set = set;
	self.setDate = setDate;
	self.toggle = toggle;

	function init() {
		self.element = element;
		self.instanceConfig = config || {};
		self.parseDate = Flatpickr.prototype.parseDate.bind(self);
		self.formatDate = Flatpickr.prototype.formatDate.bind(self);

		setupFormats();
		parseConfig();
		setupLocale();
		setupInputs();
		setupDates();
		setupHelperFunctions();

		self.isOpen = false;

		self.isMobile = (
			!self.config.disableMobile &&
			!self.config.inline &&
			self.config.mode === "single" &&
			!self.config.disable.length &&
			!self.config.enable.length &&
			!self.config.weekNumbers &&
			/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
		);

		if (!self.isMobile)
			build();

		bindEvents();

		if (self.selectedDates.length || self.config.noCalendar) {
			if (self.config.enableTime) {
				setHoursFromDate(self.config.noCalendar
					? self.latestSelectedDateObj || self.config.minDate
					: null);
			}
			updateValue();
		}

		if (self.config.weekNumbers) {
			self.calendarContainer.style.width = self.daysContainer.offsetWidth
				+ self.weekWrapper.offsetWidth + "px";
		}

		self.showTimeInput = self.selectedDates.length > 0 || self.config.noCalendar;

		if (!self.isMobile)
			positionCalendar();

		triggerEvent("Ready");
	}

	/**
	 * Binds a function to the current flatpickr instance
	 * @param {Function} fn the function
	 * @return {Function} the function bound to the instance
	 */
	function bindToInstance(fn) {
		return fn.bind(self);
	}

	/**
	 * The handler for all events targeting the time inputs
	 * @param {Event} e the event - "input", "wheel", "increment", etc
	 */
	function updateTime(e) {
		if (self.config.noCalendar && !self.selectedDates.length)
			// picking time only
			self.selectedDates = [self.now];

		timeWrapper(e);

		if (!self.selectedDates.length)
			return;

		if (!self.minDateHasTime || e.type !== "input" || e.target.value.length >= 2) {
			setHoursFromInputs();
			updateValue();
		}

		else {
			setTimeout(function(){
				setHoursFromInputs();
				updateValue();
			}, 1000);
		}
	}

	/**
	 * Syncs the selected date object time with user's time input
	 */
	function setHoursFromInputs(){
		if (!self.config.enableTime)
			return;

		let hours = (parseInt(self.hourElement.value, 10) || 0) % (self.amPM ? 12 : 24),
			minutes = (parseInt(self.minuteElement.value, 10) || 0) % 60,
			seconds = self.config.enableSeconds
				? (parseInt(self.secondElement.value, 10) || 0)  % 60
				: 0;

		if (self.amPM !== undefined)
			hours = (hours % 12) + (12 * (self.amPM.textContent === "PM"));

		if (
			self.minDateHasTime
			&& compareDates(self.latestSelectedDateObj, self.config.minDate) === 0
		) {

			hours = Math.max(hours, self.config.minDate.getHours());
			if (hours === self.config.minDate.getHours())
				minutes = Math.max(minutes, self.config.minDate.getMinutes());
		}

		if (
			self.maxDateHasTime
			&& compareDates(self.latestSelectedDateObj, self.config.maxDate) === 0
		) {
			hours = Math.min(hours, self.config.maxDate.getHours());
			if (hours === self.config.maxDate.getHours())
				minutes = Math.min(minutes, self.config.maxDate.getMinutes());
		}

		setHours(hours, minutes, seconds);
	}

	/**
	 * Syncs time input values with a date
	 * @param {Date} dateObj the date to sync with
	 */
	function setHoursFromDate(dateObj){
		const date = dateObj || self.latestSelectedDateObj;

		if (date)
			setHours(date.getHours(), date.getMinutes(), date.getSeconds());
	}

	/**
	 * Sets the hours, minutes, and optionally seconds
	 * of the latest selected date object and the
	 * corresponding time inputs
	 * @param {Number} hours the hour. whether its military
	 *                 or am-pm gets inferred from config
	 * @param {Number} minutes the minutes
	 * @param {Number} seconds the seconds (optional)
	 */
	function setHours(hours, minutes, seconds) {
		if (self.selectedDates.length) {
			self.latestSelectedDateObj.setHours(
				hours % 24, minutes, seconds || 0, 0
			);
		}

		if (!self.config.enableTime || self.isMobile)
			return;

		self.hourElement.value = self.pad(
			!self.config.time_24hr
				? (12 + hours) % 12 + 12 * (hours % 12 === 0)
				: hours
		);

		self.minuteElement.value = self.pad(minutes);

		if (!self.config.time_24hr)
			self.amPM.textContent = hours >= 12 ? "PM" : "AM";

		if (self.config.enableSeconds === true)
			self.secondElement.value = self.pad(seconds);
	}

	/**
	 * Handles the year input and incrementing events
	 * @param {Event} event the keyup or increment event
	 */
	function onYearInput(event) {
		let year = event.target.value;
		if (event.delta)
			year = (parseInt(year) + event.delta).toString();

		if (year.length === 4 || event.key === "Enter") {
			self.currentYearElement.blur();
			if (!/[^\d]/.test(year))
				changeYear(year);
		}
	}

	/**
	 * Essentially addEventListener + tracking
	 * @param {Element} element the element to addEventListener to
	 * @param {String} event the event name
	 * @param {Function} handler the event handler
	 */
	function bind(element, event, handler) {
		if (event instanceof Array)
			return event.forEach(ev => bind(element, ev, handler));

		if (element instanceof Array)
			return element.forEach(el => bind(el, event, handler));

		element.addEventListener(event, handler);
		self._handlers.push({element, event, handler});
	}

	/**
	 * A mousedown handler which mimics click.
	 * Minimizes latency, since we don't need to wait for mouseup in most cases.
	 * Also, avoids handling right clicks.
	 *
	 * @param {Function} handler the event handler
	 */
	function onClick(handler) {
		return evt => evt.which === 1 && (handler(evt));
	}

	/**
	 * Adds all the necessary event listeners
	 */
	function bindEvents() {
		self._handlers = [];
		if (self.config.wrap) {
			["open", "close", "toggle", "clear"].forEach(evt => {
				Array.prototype.forEach.call(
					self.element.querySelectorAll(`[data-${evt}]`),
					el => bind(el, "mousedown", onClick(self[evt]))
				)
			});
		}

		if (self.isMobile)
			return setupMobile();

		self.debouncedResize = debounce(onResize, 50);
		self.triggerChange = () => {
			triggerEvent("Change");
		};
		self.debouncedChange = debounce(self.triggerChange, 300);

		if (self.config.mode === "range" && self.daysContainer)
			bind(self.daysContainer, "mouseover", e => onMouseOver(e.target));

		bind(window.document.body, "keydown", onKeyDown);

		if (!self.config.static)
			bind(self._input, "keydown", onKeyDown);

		if (!self.config.inline && !self.config.static)
			bind(window, "resize", self.debouncedResize);

		if (window.ontouchstart !== undefined)
			bind(window.document, "touchstart", documentClick);

		bind(window.document, "mousedown", onClick(documentClick));
		bind(self._input, "blur", documentClick);

		if (self.config.clickOpens === true)
			bind(self._input, "focus", self.open);

		if (!self.config.noCalendar) {
			self.monthNav.addEventListener("wheel", e => e.preventDefault());
			bind(self.monthNav, "wheel", debounce(onMonthNavScroll, 10));
			bind(self.monthNav, "mousedown", onClick(onMonthNavClick));

			bind(self.monthNav, ["keyup", "increment"], onYearInput);
			bind(self.daysContainer, "mousedown", onClick(selectDate));

			if (self.config.animate) {
				bind(self.daysContainer, ["webkitAnimationEnd","animationend"], animateDays);
				bind(self.monthNav, ["webkitAnimationEnd","animationend"], animateMonths);
			}
		}

		if (self.config.enableTime) {
			const selText = e => e.target.select();
			bind(self.timeContainer, ["wheel",  "input", "increment"], updateTime);
			bind(self.timeContainer, "mousedown", onClick(timeIncrement));

			bind(self.timeContainer, ["wheel", "increment"], self.debouncedChange);
			bind(self.timeContainer, "input", self.triggerChange);

			bind([self.hourElement,self.minuteElement], "focus", selText);

			if (self.secondElement !== undefined)
				bind(self.secondElement, "focus", () => self.secondElement.select());

			if (self.amPM !== undefined) {
				bind(self.amPM, "mousedown", onClick(e => {
					updateTime(e);
					self.triggerChange(e);
				}));
			}
		}
	}

	/**
	 * Removes the day container that slided out of view
	 * @param {Event} e the animation event
	 */
	function animateDays (e) {
		if (self.daysContainer.childNodes.length > 1) {
			switch(e.animationName) {
				case "fpSlideLeft":
					self.daysContainer.lastChild.classList.remove("slideLeftNew")
					self.daysContainer.removeChild(self.daysContainer.firstChild);
					self.days = self.daysContainer.firstChild;

					break;

				case "fpSlideRight":
					self.daysContainer.firstChild.classList.remove("slideRightNew")
					self.daysContainer.removeChild(self.daysContainer.lastChild);
					self.days = self.daysContainer.firstChild;

					break;

				default: break;
			}
		}
	}

	/**
	 * Removes the month element that animated out of view
	 * @param {Event} e the animation event
	 */
	function animateMonths(e){
		switch(e.animationName) {
			case "fpSlideLeftNew":
			case "fpSlideRightNew":
				self.navigationCurrentMonth.classList.remove("slideLeftNew");
				self.navigationCurrentMonth.classList.remove("slideRightNew");
				const nav = self.navigationCurrentMonth;

				while (nav.nextSibling && /curr/.test(nav.nextSibling.className))
					self.monthNav.removeChild(nav.nextSibling);

				while (nav.previousSibling && /curr/.test(nav.previousSibling.className))
					self.monthNav.removeChild(nav.previousSibling);

				self.oldCurMonth = null;
				break;
		}
	}

	/**
	 * Set the calendar view to a particular date.
	 * @param {Date} jumpDate the date to set the view to
	 */
	function jumpToDate(jumpDate) {
		jumpDate = jumpDate
			? self.parseDate(jumpDate)
			: self.latestSelectedDateObj || (self.config.minDate > self.now
				? self.config.minDate
				: self.config.maxDate && self.config.maxDate < self.now
					? self.config.maxDate
					: self.now
			);

		try {
			self.currentYear = jumpDate.getFullYear();
			self.currentMonth = jumpDate.getMonth();
		}

		catch (e) {
			/* istanbul ignore next */
			console.error(e.stack);
			/* istanbul ignore next */
			console.warn("Invalid date supplied: " + jumpDate);
		}

		self.redraw();
	}

	/**
	 * The up/down arrow handler for time inputs
	 * @param {Event} e the click event
	 */
	function timeIncrement(e) {
		if (~e.target.className.indexOf("arrow"))
			incrementNumInput(e, e.target.classList.contains("arrowUp") ? 1 : -1);
	}

	/**
	 * Increments/decrements the value of input associ-
	 * ated with the up/down arrow by dispatching an
	 * "increment" event on the input.
	 *
	 * @param {Event} e the click event
	 * @param {Number} delta the diff (usually 1 or -1)
	 * @param {Element} inputElem the input element
	 */
	function incrementNumInput(e, delta, inputElem) {
		const input = inputElem || e.target.parentNode.childNodes[0];
		const event = createEvent("increment");
		event.delta = delta;
		input.dispatchEvent(event);
	}

	function createNumberInput(inputClassName) {
		const wrapper = createElement("div", "numInputWrapper"),
			numInput = createElement("input", "numInput " + inputClassName),
			arrowUp = createElement("span", "arrowUp"),
			arrowDown = createElement("span", "arrowDown");

		numInput.type = "text";
		numInput.pattern = "\\d*";

		wrapper.appendChild(numInput);
		wrapper.appendChild(arrowUp);
		wrapper.appendChild(arrowDown);

		return wrapper;
	}

	function build() {
		const fragment = window.document.createDocumentFragment();
		self.calendarContainer = createElement("div", "flatpickr-calendar");
		self.calendarContainer.tabIndex = -1;

		if (!self.config.noCalendar) {
			fragment.appendChild(buildMonthNav());
			self.innerContainer = createElement("div", "flatpickr-innerContainer")

			if (self.config.weekNumbers)
				self.innerContainer.appendChild(buildWeeks());

			self.rContainer = createElement("div", "flatpickr-rContainer");
			self.rContainer.appendChild(buildWeekdays());

			if (!self.daysContainer) {
				self.daysContainer = createElement("div", "flatpickr-days");
				self.daysContainer.tabIndex = -1;
			}

			buildDays();
			self.rContainer.appendChild(self.daysContainer);

			self.innerContainer.appendChild(self.rContainer);
			fragment.appendChild(self.innerContainer);
		}

		if (self.config.enableTime)
			fragment.appendChild(buildTime());

		toggleClass(self.calendarContainer, "rangeMode", self.config.mode === "range");
		toggleClass(self.calendarContainer, "animate", self.config.animate);

		self.calendarContainer.appendChild(fragment);

		const customAppend = self.config.appendTo && self.config.appendTo.nodeType;

		if (self.config.inline || self.config.static) {
			self.calendarContainer.classList.add(self.config.inline ? "inline" : "static");


			if (self.config.inline && !customAppend) {
				return self.element.parentNode.insertBefore(
					self.calendarContainer,
					self._input.nextSibling
				);
			}

			if (self.config.static){
				const wrapper = createElement("div", "flatpickr-wrapper");
				self.element.parentNode.insertBefore(wrapper, self.element);
				wrapper.appendChild(self.element);

				if(self.altInput)
					wrapper.appendChild(self.altInput);

				wrapper.appendChild(self.calendarContainer);
				return;
			}
		}

		(customAppend ? self.config.appendTo : window.document.body)
			.appendChild(self.calendarContainer);
	}

	function createDay(className, date, dayNumber, i) {
		const dateIsEnabled = isEnabled(date, true),
			dayElement = createElement(
				"span",
				"flatpickr-day " + className,
				date.getDate()
			);

		dayElement.dateObj = date;
		dayElement.$i = i;
		dayElement.setAttribute("aria-label", self.formatDate(date, self.config.ariaDateFormat));

		if (compareDates(date, self.now) === 0) {
			self.todayDateElem = dayElement;
			dayElement.classList.add("today");
		}

		if (dateIsEnabled) {
			dayElement.tabIndex = -1;
			if (isDateSelected(date)){
				dayElement.classList.add("selected");
				self.selectedDateElem = dayElement;
				if (self.config.mode === "range") {
					toggleClass(
						dayElement,
						"startRange",
						compareDates(date, self.selectedDates[0]) === 0
					);

					toggleClass(
						dayElement,
						"endRange",
						compareDates(date, self.selectedDates[1]) === 0
					);
				}
			}
		}

		else {
			dayElement.classList.add("disabled");
			if (
				self.selectedDates[0]
				&& date > self.minRangeDate
				&& date < self.selectedDates[0]
			)

				self.minRangeDate = date;

			else if (
				self.selectedDates[0]
				&& date < self.maxRangeDate
				&& date > self.selectedDates[0]
			)
				self.maxRangeDate = date;
		}

		if (self.config.mode === "range") {
			if (isDateInRange(date) && !isDateSelected(date))
				dayElement.classList.add("inRange");

			if (
				self.selectedDates.length === 1 &&
				(date < self.minRangeDate || date > self.maxRangeDate)
			)
				dayElement.classList.add("notAllowed");
		}

		if (self.config.weekNumbers && className !== "prevMonthDay" && dayNumber % 7 === 1) {
			self.weekNumbers.insertAdjacentHTML(
				"beforeend",
				"<span class='disabled flatpickr-day'>" + self.config.getWeek(date) + "</span>"
			);
		}

		triggerEvent("DayCreate", dayElement);

		return dayElement;
	}

	function focusOnDay(currentIndex, offset) {
		let newIndex = currentIndex + offset || 0,
			targetNode = currentIndex !== undefined
				? self.days.childNodes[newIndex]
				: self.selectedDateElem || self.todayDateElem || self.days.childNodes[0],
			focus = () => {
				targetNode = targetNode || self.days.childNodes[newIndex];
				targetNode.focus();

				if (self.config.mode === "range")
					onMouseOver(targetNode);
			};

		if (targetNode === undefined && offset !== 0) {
			if (offset > 0) {
				self.changeMonth(1);
				newIndex = newIndex % 42;
			}

			else if (offset < 0) {
				self.changeMonth(-1);
				newIndex += 42;
			}

			return afterDayAnim(focus);
		}

		focus();
	}

	function afterDayAnim(fn) {
		if (self.config.animate)
			return setTimeout(fn, self._.daysAnimDuration + 1);
		fn();
	}

	function buildDays(delta) {
		const firstOfMonth = (
				new Date(self.currentYear, self.currentMonth, 1).getDay() -
				self.l10n.firstDayOfWeek + 7
			) % 7,
			isRangeMode = self.config.mode === "range";

		self.prevMonthDays = self.utils.getDaysinMonth((self.currentMonth - 1 + 12) % 12);
		self.selectedDateElem = undefined;
		self.todayDateElem = undefined;

		const daysInMonth = self.utils.getDaysinMonth(),
			days = window.document.createDocumentFragment();

		let	dayNumber = self.prevMonthDays + 1 - firstOfMonth,
			dayIndex = 0;

		if (self.config.weekNumbers && self.weekNumbers.firstChild)
			self.weekNumbers.textContent = "";

		if (isRangeMode) {
			// const dateLimits = self.config.enable.length || self.config.disable.length || self.config.mixDate || self.config.maxDate;
			self.minRangeDate = new Date(self.currentYear, self.currentMonth - 1, dayNumber);
			self.maxRangeDate = new Date(
				self.currentYear,
				self.currentMonth + 1,
				(42 - firstOfMonth) % daysInMonth
			);
		}

		// prepend days from the ending of previous month
		for (; dayNumber <= self.prevMonthDays; dayNumber++, dayIndex++) {
			days.appendChild(
				createDay(
					"prevMonthDay",
					new Date(self.currentYear, self.currentMonth - 1, dayNumber),
					dayNumber,
					dayIndex
				)
			);
		}

		// Start at 1 since there is no 0th day
		for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++, dayIndex++) {
			days.appendChild(
				createDay(
					"",
					new Date(self.currentYear, self.currentMonth, dayNumber),
					dayNumber,
					dayIndex
				)
			);
		}

		// append days from the next month
		for (let dayNum = daysInMonth + 1; dayNum <= 42 - firstOfMonth; dayNum++, dayIndex++) {
			days.appendChild(
				createDay(
					"nextMonthDay",
					new Date(self.currentYear, self.currentMonth + 1, dayNum % daysInMonth),
					dayNum,
					dayIndex
				)
			);
		}

		if (isRangeMode && self.selectedDates.length === 1 && days.childNodes[0]) {
			self._hidePrevMonthArrow = self._hidePrevMonthArrow ||
				self.minRangeDate > days.childNodes[0].dateObj;

			self._hideNextMonthArrow = self._hideNextMonthArrow ||
				self.maxRangeDate < new Date(self.currentYear, self.currentMonth + 1, 1);
		}

		else
			updateNavigationCurrentMonth();

		const dayContainer = createElement("div", "dayContainer");
		dayContainer.appendChild(days);

		if (!self.config.animate || delta === undefined)
			clearNode(self.daysContainer);

		else {
			while (self.daysContainer.childNodes.length > 1)
				self.daysContainer.removeChild(self.daysContainer.firstChild);
		}

		if (delta >= 0)
			self.daysContainer.appendChild(dayContainer);
		else
			self.daysContainer.insertBefore(dayContainer, self.daysContainer.firstChild);

		self.days = self.daysContainer.firstChild;
		return self.daysContainer;
	}

	function clearNode(node) {
		while (node.firstChild)
			node.removeChild(node.firstChild);
	}

	function buildMonthNav() {
		const monthNavFragment = window.document.createDocumentFragment();
		self.monthNav = createElement("div", "flatpickr-month");

		self.prevMonthNav = createElement("span", "flatpickr-prev-month");
		self.prevMonthNav.innerHTML = self.config.prevArrow;

		self.currentMonthElement = createElement("span", "cur-month");
		self.currentMonthElement.title = self.l10n.scrollTitle;

		const yearInput = createNumberInput("cur-year");
		self.currentYearElement =  yearInput.childNodes[0];
		self.currentYearElement.title = self.l10n.scrollTitle;

		if (self.config.minDate)
			self.currentYearElement.min = self.config.minDate.getFullYear();

		if (self.config.maxDate) {
			self.currentYearElement.max = self.config.maxDate.getFullYear();

			self.currentYearElement.disabled = self.config.minDate	&&
				self.config.minDate.getFullYear() === self.config.maxDate.getFullYear();
		}

		self.nextMonthNav = createElement("span", "flatpickr-next-month");
		self.nextMonthNav.innerHTML = self.config.nextArrow;

		self.navigationCurrentMonth = createElement("span", "flatpickr-current-month");
		self.navigationCurrentMonth.appendChild(self.currentMonthElement);
		self.navigationCurrentMonth.appendChild(yearInput);

		monthNavFragment.appendChild(self.prevMonthNav);
		monthNavFragment.appendChild(self.navigationCurrentMonth);
		monthNavFragment.appendChild(self.nextMonthNav);
		self.monthNav.appendChild(monthNavFragment);

		Object.defineProperty(self, "_hidePrevMonthArrow", {
			get () {
				return this.__hidePrevMonthArrow;
			},
			set (bool) {
				if (this.__hidePrevMonthArrow !== bool)
					self.prevMonthNav.style.display = bool ? "none" : "block";
				this.__hidePrevMonthArrow = bool;
			}
		});

		Object.defineProperty(self, "_hideNextMonthArrow", {
			get () {
				return this.__hideNextMonthArrow;
			},
			set (bool) {
				if (this.__hideNextMonthArrow !== bool)
					self.nextMonthNav.style.display = bool ? "none" : "block";
				this.__hideNextMonthArrow = bool;
			}
		});

		updateNavigationCurrentMonth();

		return self.monthNav;
	}

	function buildTime() {
		self.calendarContainer.classList.add("hasTime");
		if (self.config.noCalendar)
			self.calendarContainer.classList.add("noCalendar");
		self.timeContainer = createElement("div", "flatpickr-time");
		self.timeContainer.tabIndex = -1;
		const separator = createElement("span", "flatpickr-time-separator", ":");

		const hourInput = createNumberInput("flatpickr-hour");
		self.hourElement =  hourInput.childNodes[0];

		const minuteInput = createNumberInput("flatpickr-minute");
		self.minuteElement =  minuteInput.childNodes[0];

		self.hourElement.tabIndex = self.minuteElement.tabIndex = -1;

		self.hourElement.value = self.pad(self.latestSelectedDateObj
			? self.latestSelectedDateObj.getHours()
			: self.config.defaultHour
		);

		self.minuteElement.value = self.pad(self.latestSelectedDateObj
			? self.latestSelectedDateObj.getMinutes()
			: self.config.defaultMinute
		);

		self.hourElement.step = self.config.hourIncrement;
		self.minuteElement.step = self.config.minuteIncrement;

		self.hourElement.min = self.config.time_24hr ? 0 : 1;
		self.hourElement.max = self.config.time_24hr ? 23 : 12;

		self.minuteElement.min = 0;
		self.minuteElement.max = 59;

		self.hourElement.title = self.minuteElement.title = self.l10n.scrollTitle;

		self.timeContainer.appendChild(hourInput);
		self.timeContainer.appendChild(separator);
		self.timeContainer.appendChild(minuteInput);

		if (self.config.time_24hr)
			self.timeContainer.classList.add("time24hr");

		if (self.config.enableSeconds) {
			self.timeContainer.classList.add("hasSeconds");

			const secondInput = createNumberInput("flatpickr-second");
			self.secondElement =  secondInput.childNodes[0];

			self.secondElement.value =
				self.latestSelectedDateObj ? self.pad(self.latestSelectedDateObj.getSeconds()) : "00";

			self.secondElement.step = self.minuteElement.step;
			self.secondElement.min = self.minuteElement.min;
			self.secondElement.max = self.minuteElement.max;

			self.timeContainer.appendChild(
				createElement("span", "flatpickr-time-separator", ":")
			);
			self.timeContainer.appendChild(secondInput);
		}

		if (!self.config.time_24hr) { // add self.amPM if appropriate
			self.amPM = createElement(
				"span",
				"flatpickr-am-pm",
				["AM", "PM"][(self.hourElement.value > 11) | 0]
			);
			self.amPM.title = self.l10n.toggleTitle;
			self.amPM.tabIndex = -1;
			self.timeContainer.appendChild(self.amPM);
		}

		return self.timeContainer;
	}

	function buildWeekdays() {
		if (!self.weekdayContainer)
			self.weekdayContainer = createElement("div", "flatpickr-weekdays");

		const firstDayOfWeek = self.l10n.firstDayOfWeek;
		let	weekdays = self.l10n.weekdays.shorthand.slice();

		if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) {
			weekdays = [].concat(
				weekdays.splice(firstDayOfWeek, weekdays.length),
				weekdays.splice(0, firstDayOfWeek)
			);
		}

		self.weekdayContainer.innerHTML = `
		<span class=flatpickr-weekday>
			${weekdays.join("</span><span class=flatpickr-weekday>")}
		</span>
		`;

		return self.weekdayContainer;
	}

	/* istanbul ignore next */
	function buildWeeks() {
		self.calendarContainer.classList.add("hasWeeks");
		self.weekWrapper = createElement("div", "flatpickr-weekwrapper");
		self.weekWrapper.appendChild(
			createElement("span", "flatpickr-weekday", self.l10n.weekAbbreviation)
		);
		self.weekNumbers = createElement("div", "flatpickr-weeks");
		self.weekWrapper.appendChild(self.weekNumbers);

		return self.weekWrapper;
	}

	function changeMonth(value, is_offset, animate) {
		is_offset = (is_offset === undefined) || is_offset;
		const delta = is_offset ? value : value - self.currentMonth;
		const skipAnimations = !self.config.animate || animate === false;

		if (
			(delta < 0 && self._hidePrevMonthArrow) ||
			(delta > 0 && self._hideNextMonthArrow)
		)
			return;

		self.currentMonth += delta;

		if (self.currentMonth < 0 || self.currentMonth > 11) {
			self.currentYear += (self.currentMonth > 11 ? 1 : -1);
			self.currentMonth = (self.currentMonth + 12) % 12;

			triggerEvent("YearChange");
		}

		buildDays(!skipAnimations ? delta : undefined);



		if (skipAnimations) {
			triggerEvent("MonthChange");
			return updateNavigationCurrentMonth();
		}

		// remove possible remnants from clicking too fast
		const nav = self.navigationCurrentMonth;
		if(delta < 0) {
			while (nav.nextSibling && /curr/.test(nav.nextSibling.className))
				self.monthNav.removeChild(nav.nextSibling);
		}

		else if (delta > 0) {
			while (nav.previousSibling && /curr/.test(nav.previousSibling.className))
				self.monthNav.removeChild(nav.previousSibling);
		}

		self.oldCurMonth = self.navigationCurrentMonth;

		self.navigationCurrentMonth = self.monthNav.insertBefore(
			self.oldCurMonth.cloneNode(true),
			delta > 0
				? self.oldCurMonth.nextSibling
				: self.oldCurMonth
		);


		if (delta > 0) {
			self.daysContainer.firstChild.classList.add("slideLeft");
			self.daysContainer.lastChild.classList.add("slideLeftNew");

			self.oldCurMonth.classList.add("slideLeft");
			self.navigationCurrentMonth.classList.add("slideLeftNew");
		}

		else if (delta < 0) {
			self.daysContainer.firstChild.classList.add("slideRightNew");
			self.daysContainer.lastChild.classList.add("slideRight");

			self.oldCurMonth.classList.add("slideRight");
			self.navigationCurrentMonth.classList.add("slideRightNew");
		}

		self.currentMonthElement = self.navigationCurrentMonth.firstChild;
		self.currentYearElement = self.navigationCurrentMonth.lastChild.childNodes[0];

		updateNavigationCurrentMonth();
		self.oldCurMonth.firstChild.textContent =
			self.utils.monthToStr(self.currentMonth - delta);

		triggerEvent("MonthChange");

		if (self._.daysAnimDuration === undefined) {
			const compStyle = window.getComputedStyle(self.daysContainer.lastChild);

			const duration = compStyle.getPropertyValue("animation-duration")
				|| compStyle.getPropertyValue("-webkit-animation-duration");

			self._.daysAnimDuration = parseInt(/(\d+)s/.exec(duration)[1]);
		}
	}

	function clear(triggerChangeEvent) {
		self.input.value = "";

		if (self.altInput)
			self.altInput.value = "";

		if (self.mobileInput)
			self.mobileInput.value = "";

		self.selectedDates = [];
		self.latestSelectedDateObj = undefined;
		self.showTimeInput = false;

		self.redraw();

		if (triggerChangeEvent !== false)
			// triggerChangeEvent is true (default) or an Event
			triggerEvent("Change");
	}

	function close() {
		self.isOpen = false;

		if (!self.isMobile) {
			self.calendarContainer.classList.remove("open");
			self._input.classList.remove("active");
		}

		triggerEvent("Close");
	}

	function destroy() {
		for (let i = self._handlers.length; i--;) {
			const h = self._handlers[i];
			h.element.removeEventListener(h.event, h.handler);
		}

		self._handlers = [];

		if (self.mobileInput) {
			if (self.mobileInput.parentNode)
				self.mobileInput.parentNode.removeChild(self.mobileInput);
			self.mobileInput = null;
		}

		else if (self.calendarContainer && self.calendarContainer.parentNode)
			self.calendarContainer.parentNode.removeChild(self.calendarContainer);

		if (self.altInput) {
			self.input.type = "text";
			if (self.altInput.parentNode)
				self.altInput.parentNode.removeChild(self.altInput);
			delete self.altInput;
		}

		if (self.input) {
			self.input.type = self.input._type;
			self.input.classList.remove("flatpickr-input");
			self.input.removeAttribute("readonly");
			self.input.value = "";
		}

		[
			"_showTimeInput", "latestSelectedDateObj", "_hideNextMonthArrow", "_hidePrevMonthArrow",
			"__hideNextMonthArrow",	"__hidePrevMonthArrow",	"isMobile",	"isOpen",	"selectedDateElem",
			"minDateHasTime", "maxDateHasTime", "days", "daysContainer", "_input",
			"_positionElement", "innerContainer",	"rContainer",	"monthNav",	"todayDateElem",
			"calendarContainer", "weekdayContainer", "prevMonthNav", "nextMonthNav",
			"currentMonthElement", "currentYearElement", "navigationCurrentMonth",
			"selectedDateElem", "config"
		].forEach(k => delete self[k]);
	}

	function isCalendarElem(elem) {
		if (self.config.appendTo && self.config.appendTo.contains(elem))
			return true;

		return self.calendarContainer.contains(elem);
	}

	function documentClick(e) {
		if (self.isOpen && !self.config.inline) {
			const isCalendarElement = isCalendarElem(e.target);
			const isInput = e.target === self.input
				|| e.target === self.altInput
				|| self.element.contains(e.target)
				|| (
					// web components
					e.path && e.path.indexOf &&
					(~e.path.indexOf(self.input) || ~e.path.indexOf(self.altInput))
				);

			const lostFocus = e.type === "blur"
				? isInput && e.relatedTarget && !isCalendarElem(e.relatedTarget)
				: !isInput && !isCalendarElement;

			if(lostFocus) {
				e.preventDefault();
				self.close();

				if (self.config.mode === "range" && self.selectedDates.length === 1) {
					self.clear(false);
					self.redraw();
				}
			}
		}
	}

	function changeYear(newYear) {
		if (
			!newYear
			|| (self.currentYearElement.min && newYear < self.currentYearElement.min)
			|| (self.currentYearElement.max && newYear > self.currentYearElement.max)
		)
			return;

		const newYearNum = parseInt(newYear, 10),
			isNewYear = self.currentYear !== newYearNum;

		self.currentYear = newYearNum || self.currentYear;

		if (self.config.maxDate	&& self.currentYear === self.config.maxDate.getFullYear()) {
			self.currentMonth = Math.min(
				self.config.maxDate.getMonth(),
				self.currentMonth
			);
		}

		else if (
			self.config.minDate && self.currentYear === self.config.minDate.getFullYear()) {
			self.currentMonth = Math.max(
				self.config.minDate.getMonth(),
				self.currentMonth
			);
		}

		if (isNewYear) {
			self.redraw();
			triggerEvent("YearChange");
		}
	}

	function isEnabled(date, timeless) {
		if (
			(self.config.minDate && compareDates(
				date,
				self.config.minDate,
				timeless !== undefined ? timeless : !self.minDateHasTime
			) < 0) || (self.config.maxDate && compareDates(
				date,
				self.config.maxDate,
				timeless !== undefined ? timeless : !self.maxDateHasTime
			) > 0)
		)
			return false;

		if (!self.config.enable.length && !self.config.disable.length)
			return true;

		const dateToCheck = self.parseDate(date, null, true); // timeless

		const bool = self.config.enable.length > 0,
			array = bool ? self.config.enable : self.config.disable;

		for (let i = 0, d; i < array.length; i++) {
			d = array[i];

			if (d instanceof Function && d(dateToCheck)) // disabled by function
				return bool;

			else if (d instanceof Date && d.getTime() === dateToCheck.getTime())
				// disabled by date
				return bool;

			else if (typeof d === "string" && self.parseDate(d, null, true).getTime() === dateToCheck.getTime())
				// disabled by date string
				return bool;

			else if ( // disabled by range
				typeof d === "object" && d.from && d.to &&
				dateToCheck >= d.from && dateToCheck <= d.to
			)
				return bool;
		}

		return !bool;
	}

	function onKeyDown(e) {
		const isInput = e.target === self._input;
		const calendarElem = isCalendarElem(e.target);
		const allowInput = self.config.allowInput;
		const allowKeydown = self.isOpen && (!allowInput || !isInput);
		const allowInlineKeydown = self.config.inline && isInput && !allowInput;

		if (e.key === "Enter" && allowInput && isInput) {
			self.setDate(
				self._input.value,
				true,
				e.target === self.altInput
					? self.config.altFormat
					: self.config.dateFormat
			);
			return e.target.blur();
		}

		else if (calendarElem || allowKeydown || allowInlineKeydown) {
			const isTimeObj = self.timeContainer
				&& self.timeContainer.contains(e.target);
			switch (e.key) {
				case "Enter":
					if (isTimeObj)
						updateValue();

					else
						selectDate(e);

					break;

				case "Escape": // escape
					e.preventDefault();
					self.close();
					break;

				case "ArrowLeft":
				case "ArrowRight":
					if (!isTimeObj) {
						e.preventDefault();

						if (self.daysContainer) {
							const delta = e.key === "ArrowRight" ? 1 : -1;

							if (!e.ctrlKey)
								focusOnDay(e.target.$i, delta);

							else {
								changeMonth(delta, true);
								afterDayAnim(() => {
									focusOnDay(e.target.$i, 0)
								});
							}
						}

						else if (self.config.enableTime && !isTimeObj)
							self.hourElement.focus();
					}

					break;

				case "ArrowUp":
				case "ArrowDown":
					e.preventDefault();
					const delta = e.key === "ArrowDown" ? 1 : -1;

					if (self.daysContainer) {
						if (e.ctrlKey) {
							changeYear(self.currentYear - delta);
							focusOnDay(e.target.$i, 0);
						}

						else if (!isTimeObj)
							focusOnDay(e.target.$i, delta * 7);
					}

					else if (self.config.enableTime) {
						if (!isTimeObj)
							self.hourElement.focus();
						updateTime(e);
					}

					break;

				case "Tab":
					if (e.target === self.hourElement) {
						e.preventDefault();
						self.minuteElement.select();
					}

					else if (
						e.target === self.minuteElement && 
						(self.secondElement || self.amPM)
					) {
						e.preventDefault();
						(self.secondElement || self.amPM).focus();
					}

					else if (e.target === self.secondElement) {
						e.preventDefault();
						self.amPM.focus();
					}				

					break;

				case "a":
					if (e.target === self.amPM) {
						self.amPM.textContent = "AM";
						setHoursFromInputs();
						updateValue();
					}
					break;

				case "p":
					if (e.target === self.amPM) {
						self.amPM.textContent = "PM";
						setHoursFromInputs();
						updateValue();
					}
					break;

				default: break;

			}

			triggerEvent("KeyDown", e);
		}
	}

	function onMouseOver(elem) {
		if (self.selectedDates.length !== 1 || !elem.classList.contains("flatpickr-day"))
			return;

		let hoverDate = elem.dateObj,
			initialDate = self.parseDate(self.selectedDates[0], null, true),
			rangeStartDate = Math.min(hoverDate.getTime(), self.selectedDates[0].getTime()),
			rangeEndDate = Math.max(hoverDate.getTime(), self.selectedDates[0].getTime()),
			containsDisabled = false;

		for (let t = rangeStartDate; t < rangeEndDate; t += self.utils.duration.DAY) {
			if (!isEnabled(new Date(t))) {
				containsDisabled = true;
				break;
			}
		}

		for (
			let timestamp = self.days.childNodes[0].dateObj.getTime(), i = 0;
			i < 42;
			i++, timestamp += self.utils.duration.DAY
		) {
			const outOfRange = timestamp < self.minRangeDate.getTime()
				|| timestamp > self.maxRangeDate.getTime(),
				dayElem = self.days.childNodes[i];

			if (outOfRange) {
				self.days.childNodes[i].classList.add("notAllowed");
				["inRange", "startRange", "endRange"].forEach(c => {
					dayElem.classList.remove(c)
				});
				continue;
			}

			else if (containsDisabled && !outOfRange)
				continue;

			["startRange", "inRange", "endRange", "notAllowed"].forEach(c => {
				dayElem.classList.remove(c)
			});

			const minRangeDate = Math.max(self.minRangeDate.getTime(), rangeStartDate),
				maxRangeDate = Math.min(self.maxRangeDate.getTime(), rangeEndDate);

			elem.classList.add(hoverDate < self.selectedDates[0] ? "startRange" : "endRange");

			if (initialDate < hoverDate && timestamp === initialDate.getTime())
				dayElem.classList.add("startRange");

			else if (initialDate > hoverDate && timestamp === initialDate.getTime())
				dayElem.classList.add("endRange");

			if (timestamp >= minRangeDate && timestamp <= maxRangeDate)
				dayElem.classList.add("inRange");
		}
	}

	function onResize() {
		if (self.isOpen && !self.config.static && !self.config.inline)
			positionCalendar();
	}

	function open(e) {
		if (self.isMobile) {
			if (e) {
				e.preventDefault();
				e.target.blur();
			}

			setTimeout(() => {
				self.mobileInput.click();
			}, 0);

			triggerEvent("Open");
			return;
		}

		if (self.isOpen || self._input.disabled || self.config.inline)
			return;

		self.isOpen = true;
		self.calendarContainer.classList.add("open");
		positionCalendar();
		self._input.classList.add("active");


		triggerEvent("Open");
	}

	function minMaxDateSetter(type) {
		return function(date) {
			const dateObj = self.config[`_${type}Date`] = self.parseDate(date);

			const inverseDateObj = self.config[`_${type === "min" ? "max" : "min"}Date`];
			const isValidDate = date && dateObj instanceof Date;

			if (isValidDate) {
				self[`${type}DateHasTime`] = dateObj.getHours()
					|| dateObj.getMinutes()
					|| dateObj.getSeconds();
			}

			if (self.selectedDates) {
				self.selectedDates = self.selectedDates.filter(d => isEnabled(d));
				if (!self.selectedDates.length && type === "min")
					setHoursFromDate(dateObj);
				updateValue();
			}

			if(self.daysContainer) {
				redraw();

				if(isValidDate)
					self.currentYearElement[type] = dateObj.getFullYear();
				else
					self.currentYearElement.removeAttribute(type);

				self.currentYearElement.disabled = inverseDateObj && dateObj &&
					inverseDateObj.getFullYear() === dateObj.getFullYear();
			}
		}
	}

	function parseConfig() {
		let boolOpts = [
			"utc", "wrap", "weekNumbers", "allowInput", "clickOpens", "time_24hr", "enableTime", "noCalendar", "altInput", "shorthandCurrentMonth", "inline", "static", "enableSeconds", "disableMobile"
		];

		let hooks = [
			"onChange", "onClose", "onDayCreate", "onKeyDown", "onMonthChange",
			"onOpen", "onParseConfig", "onReady", "onValueUpdate", "onYearChange"
		];

		self.config = Object.create(Flatpickr.defaultConfig);

		let userConfig = Object.assign(
			{},
			self.instanceConfig,
			JSON.parse(JSON.stringify(self.element.dataset || {}))
		);

		self.config.parseDate = userConfig.parseDate;
		self.config.formatDate = userConfig.formatDate;

		Object.assign(self.config, userConfig);

		if (!userConfig.dateFormat && userConfig.enableTime) {
			self.config.dateFormat = self.config.noCalendar
				? "H:i" + (self.config.enableSeconds ? ":S" : "")
				: Flatpickr.defaultConfig.dateFormat + " H:i" + (self.config.enableSeconds ? ":S" : "");
		}

		if (userConfig.altInput && userConfig.enableTime && !userConfig.altFormat) {
			self.config.altFormat = self.config.noCalendar
				? "h:i" + (self.config.enableSeconds ? ":S K" : " K")
				: Flatpickr.defaultConfig.altFormat + ` h:i${self.config.enableSeconds ? ":S" : ""} K`;
		}

		Object.defineProperty(self.config, "minDate", {
			get: function() {
				return this._minDate;
			},
			set: minMaxDateSetter("min")
		});

		Object.defineProperty(self.config, "maxDate", {
			get: function() {
				return this._maxDate;
			},
			set: minMaxDateSetter("max")
		});

		self.config.minDate = userConfig.minDate;
		self.config.maxDate = userConfig.maxDate;

		for (let i = 0; i < boolOpts.length; i++)
			self.config[boolOpts[i]] = (self.config[boolOpts[i]] === true) || self.config[boolOpts[i]] === "true";

		for (let i = hooks.length; i--;) {
			if (self.config[hooks[i]] !== undefined) {
				self.config[hooks[i]] = arrayify(
					self.config[hooks[i]] || []
				)
				.map(bindToInstance);
			}
		}

		for (let i = 0; i < self.config.plugins.length; i++) {
			const pluginConf = self.config.plugins[i](self) || {};
			for (let key in pluginConf) {

				if ((self.config[key] instanceof Array) || ~hooks.indexOf(key)) {
					self.config[key] = arrayify(pluginConf[key])
						.map(bindToInstance)
						.concat(self.config[key]);
				}

				else if (typeof userConfig[key] === "undefined")
					self.config[key] = pluginConf[key];
			}
		}


		triggerEvent("ParseConfig");
	}

	function setupLocale() {
		if (typeof self.config.locale !== "object" &&
			typeof Flatpickr.l10ns[self.config.locale] === "undefined"
		)
			console.warn(`flatpickr: invalid locale ${self.config.locale}`);

		self.l10n = Object.assign(
			Object.create(Flatpickr.l10ns.default),
			typeof self.config.locale === "object"
				? self.config.locale
				: self.config.locale !== "default"
					? Flatpickr.l10ns[self.config.locale] || {}
					: {}
		);
	}

	function positionCalendar() {
		if (self.calendarContainer === undefined)
			return;

		const calendarHeight = self.calendarContainer.offsetHeight,
			calendarWidth = self.calendarContainer.offsetWidth,
			configPos = self.config.position,
			inputBounds = self._positionElement.getBoundingClientRect(),
			distanceFromBottom = window.innerHeight - inputBounds.bottom,
			showOnTop = configPos === "above" || (
				configPos !== "below"
				&& distanceFromBottom < calendarHeight
				&& inputBounds.top > calendarHeight
			);

		let top = (window.pageYOffset + inputBounds.top) + (!showOnTop
			? (self._positionElement.offsetHeight + 2)
			: (- calendarHeight - 2)
		);

		toggleClass(self.calendarContainer, "arrowTop", !showOnTop);
		toggleClass(self.calendarContainer, "arrowBottom", showOnTop);

		if (self.config.inline)
			return;

		const left = window.pageXOffset + inputBounds.left;
		const right = window.document.body.offsetWidth - inputBounds.right;
		const rightMost = left + calendarWidth > window.document.body.offsetWidth;

		toggleClass(self.calendarContainer, "rightMost", rightMost);

		if (self.config.static)
			return;

		self.calendarContainer.style.top = `${top}px`;

		if (!rightMost) {
			self.calendarContainer.style.left = `${left}px`;
			self.calendarContainer.style.right = "auto";
		}

		else {
			self.calendarContainer.style.left = "auto";
			self.calendarContainer.style.right = `${right}px`;
		}
	}

	function redraw() {
		if (self.config.noCalendar || self.isMobile)
			return;

		buildWeekdays();
		updateNavigationCurrentMonth();
		buildDays();
	}

	function selectDate(e) {
		e.preventDefault();
		e.stopPropagation();

		if (
			!e.target.classList.contains("flatpickr-day") ||
			e.target.classList.contains("disabled") ||
			e.target.classList.contains("notAllowed")
		)
			return;

		const selectedDate
			= self.latestSelectedDateObj
			= new Date(e.target.dateObj.getTime());

		const shouldChangeMonth = selectedDate.getMonth() !== self.currentMonth
			&& self.config.mode !== "range";

		self.selectedDateElem = e.target;

		if (self.config.mode === "single")
			self.selectedDates = [selectedDate];

		else if (self.config.mode === "multiple") {
			const selectedIndex = isDateSelected(selectedDate);
			if (selectedIndex)
				self.selectedDates.splice(selectedIndex, 1);

			else
				self.selectedDates.push(selectedDate);
		}

		else if (self.config.mode === "range") {
			if (self.selectedDates.length === 2)
				self.clear();

			self.selectedDates.push(selectedDate);

			// unless selecting same date twice, sort ascendingly
			if (compareDates(selectedDate, self.selectedDates[0], true) !== 0)
				self.selectedDates.sort((a,b) => a.getTime() - b.getTime());
		}

		setHoursFromInputs();

		if (shouldChangeMonth) {
			const isNewYear = self.currentYear !== selectedDate.getFullYear();
			self.currentYear = selectedDate.getFullYear();
			self.currentMonth = selectedDate.getMonth();

			if (isNewYear)
				triggerEvent("YearChange");

			triggerEvent("MonthChange");
		}

		buildDays();

		if (self.minDateHasTime	&& self.config.enableTime
			&& compareDates(selectedDate, self.config.minDate) === 0
		)
			setHoursFromDate(self.config.minDate);

		updateValue();

		if (self.config.enableTime)
			setTimeout(() => self.showTimeInput = true, 50);

		if (self.config.mode === "range") {
			if(self.selectedDates.length === 1) {
				onMouseOver(e.target);

				self._hidePrevMonthArrow = self._hidePrevMonthArrow ||
					self.minRangeDate > self.days.childNodes[0].dateObj;

				self._hideNextMonthArrow = self._hideNextMonthArrow ||
					self.maxRangeDate < new Date(self.currentYear, self.currentMonth + 1, 1);
			}

			else
				updateNavigationCurrentMonth();
		}

		triggerEvent("Change");

		// maintain focus
		if (!shouldChangeMonth)
			focusOnDay(e.target.$i, 0);
		else
			afterDayAnim(() => self.selectedDateElem.focus());

		if (self.config.enableTime)
			setTimeout(() => self.hourElement.select(), 451);

		if (self.config.mode !== "multiple" && !self.config.enableTime && self.config.closeOnSelect)
			self.close();
	}

	function set(option, value) {
		self.config[option] = value;
		self.redraw();
		jumpToDate();
	}

	function setSelectedDate(inputDate, format) {
		if (inputDate instanceof Array)
			self.selectedDates = inputDate.map(d => self.parseDate(d, format));

		else if (inputDate instanceof Date || !isNaN(inputDate))
			self.selectedDates = [self.parseDate(inputDate, format)];

		else if (inputDate && inputDate.substring) {
			switch (self.config.mode) {
				case "single":
					self.selectedDates = [self.parseDate(inputDate, format)];
					break;

				case "multiple":
					self.selectedDates = inputDate
						.split("; ")
						.map(date => self.parseDate(date, format));
					break;

				case "range":
					self.selectedDates = inputDate
						.split(self.l10n.rangeSeparator)
						.map(date => self.parseDate(date, format));

					break;

				default: break;
			}
		}

		self.selectedDates = self.selectedDates.filter(
			d => d instanceof Date && isEnabled(d, false)
		);

		self.selectedDates.sort((a,b) => a.getTime() - b.getTime());
	}

	function setDate(date, triggerChange, format) {
		if (!date)
			return self.clear(triggerChange);

		setSelectedDate(date, format);

		self.showTimeInput = self.selectedDates.length > 0;
		self.latestSelectedDateObj = self.selectedDates[0];

		self.redraw();
		jumpToDate();

		setHoursFromDate();
		updateValue(triggerChange);

		if (triggerChange)
			triggerEvent("Change");
	}

	function setupDates() {
		function parseDateRules(arr) {
			for (let i = arr.length; i--;) {
				if (typeof arr[i] === "string" || +arr[i])
					arr[i] = self.parseDate(arr[i], null, true);

				else if (arr[i] && arr[i].from && arr[i].to) {
					arr[i].from = self.parseDate(arr[i].from);
					arr[i].to = self.parseDate(arr[i].to);
				}
			}

			return arr.filter(x => x); // remove falsy values
		}

		self.selectedDates = [];
		self.now = new Date();

		if (self.config.disable.length)
			self.config.disable = parseDateRules(self.config.disable);

		if (self.config.enable.length)
			self.config.enable = parseDateRules(self.config.enable);

		const preloadedDate = self.config.defaultDate || self.input.value;
		if (preloadedDate)
			setSelectedDate(preloadedDate, self.config.dateFormat);

		const initialDate = (self.selectedDates.length
			? self.selectedDates[0]
			: self.config.minDate && self.config.minDate.getTime() > self.now
				? self.config.minDate
				: self.config.maxDate && self.config.maxDate.getTime() < self.now
					? self.config.maxDate
					: self.now
		);

		self.currentYear = initialDate.getFullYear();
		self.currentMonth = initialDate.getMonth();

		if (self.selectedDates.length)
			self.latestSelectedDateObj = self.selectedDates[0];

		self.minDateHasTime = self.config.minDate && (self.config.minDate.getHours()
			|| self.config.minDate.getMinutes()
			|| self.config.minDate.getSeconds());

		self.maxDateHasTime = self.config.maxDate && (self.config.maxDate.getHours()
			|| self.config.maxDate.getMinutes()
			|| self.config.maxDate.getSeconds());

		Object.defineProperty(self, "latestSelectedDateObj", {
			get() {
				return self._selectedDateObj
					|| self.selectedDates[self.selectedDates.length - 1];
			},
			set(date) {
				self._selectedDateObj = date;
			}
		});

		if (!self.isMobile) {
			Object.defineProperty(self, "showTimeInput", {
				get () {
					return self._showTimeInput;
				},
				set (bool) {
					self._showTimeInput = bool;
					if (self.calendarContainer)
						toggleClass(self.calendarContainer, "showTimeInput", bool);
					positionCalendar();
				}
			});
		}
	}

	function setupHelperFunctions() {
		self.utils = {
			duration: {
				DAY: 86400000,
			},
			getDaysinMonth (month, yr) {
				month = typeof month === "undefined"
					? self.currentMonth
					: month;

				yr = typeof yr === "undefined"
					? self.currentYear
					: yr;

				if (month === 1 && (((yr % 4 === 0) && (yr % 100 !== 0)) || (yr % 400 === 0)))
					return 29;

				return self.l10n.daysInMonth[month];
			},

			monthToStr (monthNumber, shorthand) {
				shorthand = typeof shorthand === "undefined"
					? self.config.shorthandCurrentMonth
					: shorthand;

				return self.l10n.months[(`${shorthand ? "short" : "long"}hand`)][monthNumber];
			}
		};
	}

	/* istanbul ignore next */
	function setupFormats() {
		["D", "F", "J", "M", "W", "l"].forEach(f => {
			self.formats[f] = Flatpickr.prototype.formats[f].bind(self);
		});

		self.revFormat.F = Flatpickr.prototype.revFormat.F.bind(self);
		self.revFormat.M = Flatpickr.prototype.revFormat.M.bind(self);
	}

	function setupInputs() {
		self.input = self.config.wrap
			? self.element.querySelector("[data-input]")
			: self.element;

		/* istanbul ignore next */
		if (!self.input)
			return console.warn("Error: invalid input element specified", self.input);

		self.input._type = self.input.type;
		self.input.type = "text";

		self.input.classList.add("flatpickr-input");
		self._input = self.input;

		if (self.config.altInput) {
			// replicate self.element
			self.altInput = createElement(
				self.input.nodeName,
				self.input.className + " " + self.config.altInputClass
			);
			self._input = self.altInput;
			self.altInput.placeholder = self.input.placeholder;
			self.altInput.type = "text";
			self.input.type = "hidden";

			if (!self.config.static && self.input.parentNode)
				self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);
		}

		if (!self.config.allowInput)
			self._input.setAttribute("readonly", "readonly");

		self._positionElement = self.config.positionElement || self._input;
	}

	function setupMobile() {
		const inputType = self.config.enableTime
			? (self.config.noCalendar ? "time" : "datetime-local")
			: "date";

		self.mobileInput = createElement("input", self.input.className + " flatpickr-mobile");
		self.mobileInput.step = "any";
		self.mobileInput.tabIndex = 1;
		self.mobileInput.type = inputType;
		self.mobileInput.disabled = self.input.disabled;
		self.mobileInput.placeholder = self.input.placeholder;

		self.mobileFormatStr = inputType === "datetime-local"
			? "Y-m-d\\TH:i:S"
			: inputType === "date"
				? "Y-m-d"
				: "H:i:S";

		if (self.selectedDates.length) {
			self.mobileInput.defaultValue
			= self.mobileInput.value
			= self.formatDate(self.selectedDates[0], self.mobileFormatStr);
		}

		if (self.config.minDate)
			self.mobileInput.min = self.formatDate(self.config.minDate, "Y-m-d");

		if (self.config.maxDate)
			self.mobileInput.max = self.formatDate(self.config.maxDate, "Y-m-d");

		self.input.type = "hidden";
		if (self.config.altInput)
			self.altInput.type = "hidden";

		try {
			self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling);
		}
		catch (e) {
			//
		}

		self.mobileInput.addEventListener("change", e => {
			self.setDate(e.target.value, false, self.mobileFormatStr);
			triggerEvent("Change");
			triggerEvent("Close");
		});
	}

	function toggle() {
		if (self.isOpen)
			return self.close();
		self.open();
	}

	function triggerEvent(event, data) {
		const hooks = self.config["on" + event];

		if (hooks !== undefined && hooks.length > 0) {
			for (let i = 0; hooks[i] && i < hooks.length; i++)
				hooks[i](self.selectedDates, self._input.value, self, data);
		}

		if (event === "Change") {
			self.input.dispatchEvent(createEvent("change"));

			// many front-end frameworks bind to the input event
			self.input.dispatchEvent(createEvent("input"));
		}
	}

	/**
	 * Creates an Event, normalized across browsers
	 * @param {String} name the event name, e.g. "click"
	 * @return {Event} the created event
	 */
	function createEvent(name) {
		if (self._supportsEvents)
			return new Event(name, { bubbles: true });

		self._[`${name}Event`] = document.createEvent("Event");
		self._[`${name}Event`].initEvent(name, true, true);
		return self._[`${name}Event`];
	}

	function isDateSelected(date) {
		for (let i = 0; i < self.selectedDates.length; i++) {
			if (compareDates(self.selectedDates[i], date) === 0)
				return "" + i;
		}

		return false;
	}

	function isDateInRange(date){
		if (self.config.mode !== "range" || self.selectedDates.length < 2)
			return false;
		return compareDates(date,self.selectedDates[0]) >= 0
			&& compareDates(date,self.selectedDates[1]) <= 0;
	}

	function updateNavigationCurrentMonth() {
		if (self.config.noCalendar || self.isMobile || !self.monthNav)
			return;

		self.currentMonthElement.textContent = self.utils.monthToStr(self.currentMonth) + " ";
		self.currentYearElement.value = self.currentYear;

		self._hidePrevMonthArrow = self.config.minDate &&
				(self.currentYear === self.config.minDate.getFullYear()
					? self.currentMonth <= self.config.minDate.getMonth()
					: self.currentYear < self.config.minDate.getFullYear());

		self._hideNextMonthArrow = self.config.maxDate &&
			(self.currentYear === self.config.maxDate.getFullYear()
				? self.currentMonth + 1 > self.config.maxDate.getMonth()
				: self.currentYear > self.config.maxDate.getFullYear());
	}

	/**
	 * Updates the values of inputs associated with the calendar
	 * @return {void}
	 */
	function updateValue(triggerChange) {
		if (!self.selectedDates.length)
			return self.clear(triggerChange);

		if (self.isMobile) {
			self.mobileInput.value = self.selectedDates.length
				? self.formatDate(self.latestSelectedDateObj, self.mobileFormatStr)
				: "";
		}

		const joinChar = self.config.mode !== "range" ? "; " : self.l10n.rangeSeparator;

		self.input.value = self.selectedDates
			.map(dObj => self.formatDate(dObj, self.config.dateFormat))
			.join(joinChar);

		if (self.config.altInput) {
			self.altInput.value = self.selectedDates
				.map(dObj => self.formatDate(dObj, self.config.altFormat))
				.join(joinChar);
		}
		triggerEvent("ValueUpdate");
	}

	function mouseDelta(e) {
		return Math.max(-1, Math.min(1, (e.wheelDelta || -e.deltaY)));
	}

	function onMonthNavScroll(e) {
		e.preventDefault();
		const isYear = self.currentYearElement.parentNode.contains(e.target);

		if (e.target === self.currentMonthElement || isYear) {

			const delta = mouseDelta(e);

			if (isYear) {
				changeYear(self.currentYear + delta);
				e.target.value = self.currentYear;
			}
			else
				self.changeMonth(delta, true, false);
		}
	}

	function onMonthNavClick(e) {
		const isPrevMonth = self.prevMonthNav.contains(e.target);
		const isNextMonth = self.nextMonthNav.contains(e.target);

		if (isPrevMonth || isNextMonth)
			changeMonth(isPrevMonth ? -1 : 1);

		else if (e.target === self.currentYearElement) {
			e.preventDefault();
			self.currentYearElement.select();
		}

		else if (e.target.className === "arrowUp")
			self.changeYear(self.currentYear + 1);

		else if (e.target.className === "arrowDown")
			self.changeYear(self.currentYear - 1);
	}

	/**
	 * Creates an HTMLElement with given tag, class, and textual content
	 * @param {String} tag the HTML tag
	 * @param {String} className the new element's class name
	 * @param {String} content The new element's text content
	 * @return {HTMLElement} the created HTML element
	 */
	function createElement(tag, className, content) {
		const e = window.document.createElement(tag);
		className = className || "";
		content = content || "";

		e.className = className;

		if (content !== undefined)
			e.textContent = content;

		return e;
	}

	function arrayify(obj) {
		if (obj instanceof Array)
			return obj;
		return [obj];
	}

	function toggleClass(elem, className, bool) {
		if (bool)
			return elem.classList.add(className);
		elem.classList.remove(className);
	}

	/* istanbul ignore next */
	function debounce(func, wait, immediate) {
		let timeout;
		return function() {
			let context = this, args = arguments;
			clearTimeout(timeout);
			timeout = setTimeout(function() {
				timeout = null;
				if (!immediate) func.apply(context, args);
			}, wait);
			if (immediate && !timeout) func.apply(context, args);
		};
	}

	/**
	 * Compute the difference in dates, measured in ms
	 * @param {Date} date1
	 * @param {Date} date2
	 * @param {Boolean} timeless whether to reset times of both dates to 00:00
	 * @return {Number} the difference in ms
	 */
	function compareDates(date1, date2, timeless) {
		if (!(date1 instanceof Date) || !(date2 instanceof Date))
			return false;

		if (timeless !== false) {
			return new Date(date1.getTime()).setHours(0,0,0,0)
				- new Date(date2.getTime()).setHours(0,0,0,0);
		}

		return date1.getTime() - date2.getTime();
	}

	function timeWrapper(e) {
		e.preventDefault();

		const isKeyDown = e.type === "keydown",
			isWheel = e.type === "wheel",
			isIncrement = e.type === "increment",
			input = e.target;

		if (self.amPM && e.target === self.amPM)
			return e.target.textContent = ["AM", "PM"][(e.target.textContent === "AM") | 0];

		const min = Number(input.min),
			max = Number(input.max),
			step = Number(input.step),
			curValue = parseInt(input.value, 10),
			delta = e.delta || (!isKeyDown
				? Math.max(-1, Math.min(1, (e.wheelDelta || -e.deltaY))) || 0
				: e.which === 38 ? 1 : -1);

		let newValue = curValue + step * delta;

		if (typeof(input.value) !== "undefined" && input.value.length === 2) {
			const isHourElem = input === self.hourElement,
				isMinuteElem = input === self.minuteElement;

			if (newValue < min) {
				newValue = max + newValue + !isHourElem
					+ (isHourElem && !self.amPM);

				if (isMinuteElem)
					incrementNumInput(null, -1, self.hourElement)
			}

			else if (newValue > max) {
				newValue = input === self.hourElement
					? newValue - max - (!self.amPM)
					: min;

				if (isMinuteElem)
					incrementNumInput(null, 1, self.hourElement);
			}

			if (
				self.amPM && isHourElem && (step === 1
					? newValue + curValue === 23
					: Math.abs(newValue - curValue) > step)
			)
				self.amPM.textContent = self.amPM.textContent === "PM" ? "AM" : "PM";


			input.value = self.pad(newValue);
		}
	}

	init();
	return self;
}

/* istanbul ignore next */
Flatpickr.defaultConfig = {
	mode: "single",

	position: "auto",

	animate: window.navigator.userAgent.indexOf("MSIE") === -1,

	/* if true, dates will be parsed, formatted, and displayed in UTC.
	preloading date strings w/ timezones is recommended but not necessary */
	utc: false,

	// wrap: see https://chmln.github.io/flatpickr/examples/#flatpickr-external-elements
	wrap: false,

	// enables week numbers
	weekNumbers: false,

	// allow manual datetime input
	allowInput: false,

	/*
		clicking on input opens the date(time)picker.
		disable if you wish to open the calendar manually with .open()
	*/
	clickOpens: true,

	/*
		closes calendar after date selection,
		unless 'mode' is 'multiple' or enableTime is true
	*/
	closeOnSelect: true,

	// display time picker in 24 hour mode
	time_24hr: false,

	// enables the time picker functionality
	enableTime: false,

	// noCalendar: true will hide the calendar. use for a time picker along w/ enableTime
	noCalendar: false,

	// more date format chars at https://chmln.github.io/flatpickr/#dateformat
	dateFormat: "Y-m-d",

	// date format used in aria-label for days
	ariaDateFormat: "F j, Y",

	// altInput - see https://chmln.github.io/flatpickr/#altinput
	altInput: false,

	// the created altInput element will have this class.
	altInputClass: "form-control input",

	// same as dateFormat, but for altInput
	altFormat: "F j, Y", // defaults to e.g. June 10, 2016

	// defaultDate - either a datestring or a date object. used for datetimepicker"s initial value
	defaultDate: null,

	// the minimum date that user can pick (inclusive)
	minDate: null,

	// the maximum date that user can pick (inclusive)
	maxDate: null,

	// dateparser that transforms a given string to a date object
	parseDate: null,

	// dateformatter that transforms a given date object to a string, according to passed format
	formatDate: null,

	getWeek (givenDate) {
		const date = new Date(givenDate.getTime());
		const onejan = new Date(date.getFullYear(), 0, 1);
		return Math.ceil((((date - onejan) / 86400000) + onejan.getDay() + 1) / 7);
	},

	// see https://chmln.github.io/flatpickr/#disable
	enable: [],

	// see https://chmln.github.io/flatpickr/#disable
	disable: [],

	// display the short version of month names - e.g. Sep instead of September
	shorthandCurrentMonth: false,

	// displays calendar inline. see https://chmln.github.io/flatpickr/#inline-calendar
	inline: false,

	// position calendar inside wrapper and next to the input element
	// leave at false unless you know what you"re doing
	"static": false,

	// DOM node to append the calendar to in *static* mode
	appendTo: null,

	// code for previous/next icons. this is where you put your custom icon code e.g. fontawesome
	prevArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>",
	nextArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>",

	// enables seconds in the time picker
	enableSeconds: false,

	// step size used when scrolling/incrementing the hour element
	hourIncrement: 1,

	// step size used when scrolling/incrementing the minute element
	minuteIncrement: 5,

	// initial value in the hour element
	defaultHour: 12,

	// initial value in the minute element
	defaultMinute: 0,

	// disable native mobile datetime input support
	disableMobile: false,

	// default locale
	locale: "default",

	plugins: [],

	// called every time calendar is closed
	onClose: undefined, // function (dateObj, dateStr) {}

	// onChange callback when user selects a date or time
	onChange: undefined, // function (dateObj, dateStr) {}

	// called for every day element
	onDayCreate: undefined,

	// called every time the month is changed
	onMonthChange: undefined,

	// called every time calendar is opened
	onOpen: undefined, // function (dateObj, dateStr) {}

	// called after the configuration has been parsed
	onParseConfig: undefined,

	// called after calendar is ready
	onReady: undefined, // function (dateObj, dateStr) {}

	// called after input value updated
	onValueUpdate: undefined,

	// called every time the year is changed
	onYearChange: undefined,

	onKeyDown: undefined
};

/* istanbul ignore next */
Flatpickr.l10ns = {
	en: {
		weekdays: {
			shorthand: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
			longhand: [
				"Sunday", "Monday", "Tuesday", "Wednesday",
				"Thursday", "Friday", "Saturday"
			]
		},
		months: {
			shorthand: [
				"Jan", "Feb", "Mar", "Apr",
				"May", "Jun", "Jul", "Aug",
				"Sep", "Oct", "Nov", "Dec"
			],
			longhand: [
				"January", "February", "March",	"April",
				"May", "June", "July", "August",
				"September", "October", "November", "December"
			]
		},
		daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
		firstDayOfWeek: 0,
		ordinal: (nth) => {
			const s = nth % 100;
			if (s > 3 && s < 21) return "th";
			switch (s % 10) {
				case 1: return "st";
				case 2: return "nd";
				case 3: return "rd";
				default: return "th";
			}
		},
		rangeSeparator: " to ",
		weekAbbreviation: "Wk",
		scrollTitle: "Scroll to increment",
		toggleTitle: "Click to toggle"
	}
};

Flatpickr.l10ns.default = Object.create(Flatpickr.l10ns.en);
Flatpickr.localize = l10n => Object.assign(Flatpickr.l10ns.default, l10n || {});
Flatpickr.setDefaults = config => Object.assign(Flatpickr.defaultConfig, config || {});

Flatpickr.prototype = {
	formats: {
		// get the date in UTC
		Z: date => date.toISOString(),

		// weekday name, short, e.g. Thu
		D: function (date) {
			return this.l10n.weekdays.shorthand[this.formats.w(date)];
		},

		// full month name e.g. January
		F: function (date) {
			return this.utils.monthToStr(this.formats.n(date) - 1, false);
		},

		// hours with leading zero e.g. 03
		H: date => Flatpickr.prototype.pad(date.getHours()),

		// day (1-30) with ordinal suffix e.g. 1st, 2nd
		J: function (date) {
			return date.getDate() + this.l10n.ordinal(date.getDate())
		},

		// AM/PM
		K: date => date.getHours() > 11 ? "PM" : "AM",

		// shorthand month e.g. Jan, Sep, Oct, etc
		M: function (date) {
			return this.utils.monthToStr(date.getMonth(), true);
		},

		// seconds 00-59
		S: date => Flatpickr.prototype.pad(date.getSeconds()),

		// unix timestamp
		U: date => date.getTime() / 1000,

		W: function(date) {
			return this.config.getWeek(date);
		},

		// full year e.g. 2016
		Y: date => date.getFullYear(),

		// day in month, padded (01-30)
		d: date => Flatpickr.prototype.pad(date.getDate()),

		// hour from 1-12 (am/pm)
		h: date => date.getHours() % 12 ? date.getHours() % 12 : 12,

		// minutes, padded with leading zero e.g. 09
		i: date => Flatpickr.prototype.pad(date.getMinutes()),

		// day in month (1-30)
		j: date => date.getDate(),

		// weekday name, full, e.g. Thursday
		l: function (date) {
			return this.l10n.weekdays.longhand[date.getDay()];
		},

		// padded month number (01-12)
		m: date => Flatpickr.prototype.pad(date.getMonth() + 1),

		// the month number (1-12)
		n: date => date.getMonth() + 1,

		// seconds 0-59
		s: date => date.getSeconds(),

		// number of the day of the week
		w: date => date.getDay(),

		// last two digits of year e.g. 16 for 2016
		y: date => String(date.getFullYear()).substring(2)
	},

	/**
	 * Formats a given Date object into a string based on supplied format
	 * @param {Date} dateObj the date object
	 * @param {String} frmt a string composed of formatting tokens e.g. "Y-m-d"
	 * @return {String} The textual representation of the date e.g. 2017-02-03
	 */
	formatDate (dateObj, frmt) {
		if (this.config !== undefined && this.config.formatDate !== undefined)
			return this.config.formatDate(dateObj, frmt);

		return frmt.split("").map((c, i, arr) => this.formats[c] && arr[i - 1] !== "\\"
			? this.formats[c](dateObj)
			: c !== "\\" ? c : ""
		).join("");
	},

	revFormat: {
		D: () => {},
		F: function(dateObj, monthName) {
			dateObj.setMonth(this.l10n.months.longhand.indexOf(monthName));
		},
		H: (dateObj, hour) => {
			dateObj.setHours(parseFloat(hour))
		},
		J: (dateObj, day) => {
			dateObj.setDate(parseFloat(day))
		},
		K: (dateObj, amPM) => {
			const hours = dateObj.getHours();

			if (hours !== 12)
				dateObj.setHours(hours % 12 + 12 * /pm/i.test(amPM));
		},
		M: function(dateObj, shortMonth) {
			dateObj.setMonth(this.l10n.months.shorthand.indexOf(shortMonth));
		},
		S: (dateObj, seconds) => {
			dateObj.setSeconds(seconds);
		},
		U: (dateObj, unixSeconds) => new Date(parseFloat(unixSeconds) * 1000),

		W: function(dateObj, weekNumber){
			weekNumber = parseInt(weekNumber);
			return new Date(dateObj.getFullYear(), 0, 2 + (weekNumber - 1) * 7, 0, 0, 0, 0, 0);
		},
		Y: (dateObj, year) =>  {
			dateObj.setFullYear(year);
		},
		Z: (dateObj, ISODate) => new Date(ISODate),

		d: (dateObj, day) =>  {
			dateObj.setDate(parseFloat(day))
		},
		h: (dateObj, hour) =>  {
			dateObj.setHours(parseFloat(hour))
		},
		i: (dateObj, minutes) =>  {
			dateObj.setMinutes(parseFloat(minutes))
		},
		j: (dateObj, day) =>  {
			dateObj.setDate(parseFloat(day))
		},
		l: () =>  {},
		m: (dateObj, month) =>  {
			dateObj.setMonth(parseFloat(month) - 1)
		},
		n: (dateObj, month) =>  {
			dateObj.setMonth(parseFloat(month) - 1)
		},
		s: (dateObj, seconds) =>  {
			dateObj.setSeconds(parseFloat(seconds))
		},
		w: () =>  {},
		y: (dateObj, year) =>  {
			dateObj.setFullYear(2000 + parseFloat(year))
		},
	},

	tokenRegex: {
		D:"(\\w+)",
		F:"(\\w+)",
		H:"(\\d\\d|\\d)",
		J:"(\\d\\d|\\d)\\w+",
		K:"(\\w+)",
		M:"(\\w+)",
		S:"(\\d\\d|\\d)",
		U: "(.+)",
		W:"(\\d\\d|\\d)",
		Y:"(\\d{4})",
		Z:"(.+)",
		d:"(\\d\\d|\\d)",
		h:"(\\d\\d|\\d)",
		i:"(\\d\\d|\\d)",
		j:"(\\d\\d|\\d)",
		l:"(\\w+)",
		m:"(\\d\\d|\\d)",
		n:"(\\d\\d|\\d)",
		s:"(\\d\\d|\\d)",
		w: "(\\d\\d|\\d)",
		y:"(\\d{2})"
	},

	pad: number => `0${number}`.slice(-2),

	/**
	 * Parses a date(+time) string into a Date object
	 * @param {String} date the date string, e.g. 2017-02-03 14:45
	 * @param {String} givenFormat the date format, e.g. Y-m-d H:i
	 * @param {Boolean} timeless whether to reset the time of Date object
	 * @return {Date} the parsed Date object
	 */
	parseDate (date, givenFormat, timeless) {
		if (!date)
			return null;

		const date_orig = date;

		if (date instanceof Date) {
			date = new Date(date.getTime()); // create a copy
			date.fp_isUTC = date_orig.fp_isUTC;
		}

		else if (date.toFixed !== undefined) // timestamp
			date = new Date(date);

		else { // date string
			const format = givenFormat || (this.config || Flatpickr.defaultConfig).dateFormat;
			date = String(date).trim();

			if (date === "today") {
				date = new Date();
				timeless = true;
			}

			else if (/Z$/.test(date) || /GMT$/.test(date)) // datestrings w/ timezone
				date = new Date(date);

			else if (this.config && this.config.parseDate)
				date = this.config.parseDate(date, format);

			else {
				let parsedDate = !this.config || !this.config.noCalendar
					? new Date(new Date().getFullYear(), 0, 1, 0, 0, 0 ,0)
					: new Date(new Date().setHours(0,0,0,0));

				let matched;

				for (let i = 0, matchIndex = 0, regexStr = ""; i < format.length; i++) {
					const token = format[i];
					const isBackSlash = token === "\\";
					const escaped = format[i - 1] === "\\" || isBackSlash;

					if (this.tokenRegex[token] && !escaped) {
						regexStr += this.tokenRegex[token];
						const match = new RegExp(regexStr).exec(date);
						if (match && (matched = true)) {
							parsedDate =
								this.revFormat[token](parsedDate, match[++matchIndex])
								|| parsedDate;
						}
					}

					else if (!isBackSlash)
						regexStr += "."; // don't really care

				}

				date = matched	? parsedDate : null;
			}
		}

		/* istanbul ignore next */
		if (!(date instanceof Date)) {
			console.warn(`flatpickr: invalid date ${date_orig}`);
			console.info(this.element);
			return null;
		}

		if (this.config && this.config.utc && !date.fp_isUTC)
			date = date.fp_toUTC();

		if (timeless === true)
			date.setHours(0, 0, 0, 0);

		return date;
	}
};

/* istanbul ignore next */
function _flatpickr(nodeList, config) {
	const nodes = Array.prototype.slice.call(nodeList); // static list
	let instances = [];
	for (let i = 0; i < nodes.length; i++) {
		try {
			nodes[i]._flatpickr = new Flatpickr(nodes[i], config || {});
			instances.push(nodes[i]._flatpickr);
		}

		catch (e) {
			console.warn(e, e.stack);
		}
	}

	return instances.length === 1 ? instances[0] : instances;
}

/* istanbul ignore next */
if (typeof HTMLElement !== "undefined") { // browser env
	HTMLCollection.prototype.flatpickr =
	NodeList.prototype.flatpickr = function (config) {
		return _flatpickr(this, config);
	};

	HTMLElement.prototype.flatpickr = function (config) {
		return _flatpickr([this], config);
	};
}

/* istanbul ignore next */
function flatpickr(selector, config) {
	return _flatpickr(window.document.querySelectorAll(selector), config);
}

/* istanbul ignore next */
if (typeof jQuery !== "undefined") {
	jQuery.fn.flatpickr = function (config) {
		return _flatpickr(this, config);
	};
}

Date.prototype.fp_incr = function (days) {
	return new Date(
		this.getFullYear(),
		this.getMonth(),
		this.getDate() + parseInt(days, 10)
	);
};

Date.prototype.fp_isUTC = false;
Date.prototype.fp_toUTC = function () {
	const newDate = new Date(
		this.getUTCFullYear(),
		this.getUTCMonth(),
		this.getUTCDate(),
		this.getUTCHours(),
		this.getUTCMinutes(),
		this.getUTCSeconds()
	);

	newDate.fp_isUTC = true;
	return newDate;
};

if (typeof module !== "undefined")
	module.exports = Flatpickr;

Youez - 2016 - github.com/yon3zu
LinuXploit