PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/home/htlwork.com/www/awesomecandy/pub/static/frontend/Smartwave/porto/en_US/js/bundle/
Upload File :
Current File : /home/htlwork.com/www/awesomecandy/pub/static/frontend/Smartwave/porto/en_US/js/bundle/bundle7.js
require.config({"config": {
        "jsbuild":{"Mageplaza_Core/lib/fileUploader/jquery.fileupload-ui.js":"/*\n * jQuery File Upload User Interface Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      'jquery',\n      'Mageplaza_Core/lib/fileUploader/vendor/blueimp-tmpl/js/tmpl',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-image',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-audio',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-video',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-validate'\n    ], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(\n      require('jquery'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-tmpl/js/tmpl'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-image'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-audio'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-video'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-validate')\n    );\n  } else {\n    // Browser globals:\n    factory(window.jQuery, window.tmpl);\n  }\n})(function ($, tmpl) {\n  'use strict';\n\n  $.blueimp.fileupload.prototype._specialOptions.push(\n    'filesContainer',\n    'uploadTemplateId',\n    'downloadTemplateId'\n  );\n\n  // The UI version extends the file upload widget\n  // and adds complete user interface interaction:\n  $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n    options: {\n      // By default, files added to the widget are uploaded as soon\n      // as the user clicks on the start buttons. To enable automatic\n      // uploads, set the following option to true:\n      autoUpload: false,\n      // The class to show/hide UI elements:\n      showElementClass: 'in',\n      // The ID of the upload template:\n      uploadTemplateId: 'template-upload',\n      // The ID of the download template:\n      downloadTemplateId: 'template-download',\n      // The container for the list of files. If undefined, it is set to\n      // an element with class \"files\" inside of the widget element:\n      filesContainer: undefined,\n      // By default, files are appended to the files container.\n      // Set the following option to true, to prepend files instead:\n      prependFiles: false,\n      // The expected data type of the upload response, sets the dataType\n      // option of the $.ajax upload requests:\n      dataType: 'json',\n\n      // Error and info messages:\n      messages: {\n        unknownError: 'Unknown error'\n      },\n\n      // Function returning the current number of files,\n      // used by the maxNumberOfFiles validation:\n      getNumberOfFiles: function () {\n        return this.filesContainer.children().not('.processing').length;\n      },\n\n      // Callback to retrieve the list of files from the server response:\n      getFilesFromResponse: function (data) {\n        if (data.result && $.isArray(data.result.files)) {\n          return data.result.files;\n        }\n        return [];\n      },\n\n      // The add callback is invoked as soon as files are added to the fileupload\n      // widget (via file input selection, drag & drop or add API call).\n      // See the basic file upload widget for more information:\n      add: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var $this = $(this),\n          that = $this.data('blueimp-fileupload') || $this.data('fileupload'),\n          options = that.options;\n        data.context = that\n          ._renderUpload(data.files)\n          .data('data', data)\n          .addClass('processing');\n        options.filesContainer[options.prependFiles ? 'prepend' : 'append'](\n          data.context\n        );\n        that._forceReflow(data.context);\n        that._transition(data.context);\n        data\n          .process(function () {\n            return $this.fileupload('process', data);\n          })\n          .always(function () {\n            data.context\n              .each(function (index) {\n                $(this)\n                  .find('.size')\n                  .text(that._formatFileSize(data.files[index].size));\n              })\n              .removeClass('processing');\n            that._renderPreviews(data);\n          })\n          .done(function () {\n            data.context.find('.edit,.start').prop('disabled', false);\n            if (\n              that._trigger('added', e, data) !== false &&\n              (options.autoUpload || data.autoUpload) &&\n              data.autoUpload !== false\n            ) {\n              data.submit();\n            }\n          })\n          .fail(function () {\n            if (data.files.error) {\n              data.context.each(function (index) {\n                var error = data.files[index].error;\n                if (error) {\n                  $(this).find('.error').text(error);\n                }\n              });\n            }\n          });\n      },\n      // Callback for the start of each file upload request:\n      send: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n          $(this).data('blueimp-fileupload') || $(this).data('fileupload');\n        if (\n          data.context &&\n          data.dataType &&\n          data.dataType.substr(0, 6) === 'iframe'\n        ) {\n          // Iframe Transport does not support progress events.\n          // In lack of an indeterminate progress bar, we set\n          // the progress to 100%, showing the full animated bar:\n          data.context\n            .find('.progress')\n            .addClass(!$.support.transition && 'progress-animated')\n            .attr('aria-valuenow', 100)\n            .children()\n            .first()\n            .css('width', '100%');\n        }\n        return that._trigger('sent', e, data);\n      },\n      // Callback for successful uploads:\n      done: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n            $(this).data('blueimp-fileupload') || $(this).data('fileupload'),\n          getFilesFromResponse =\n            data.getFilesFromResponse || that.options.getFilesFromResponse,\n          files = getFilesFromResponse(data),\n          template,\n          deferred;\n        if (data.context) {\n          data.context.each(function (index) {\n            var file = files[index] || { error: 'Empty file upload result' };\n            deferred = that._addFinishedDeferreds();\n            that._transition($(this)).done(function () {\n              var node = $(this);\n              template = that._renderDownload([file]).replaceAll(node);\n              that._forceReflow(template);\n              that._transition(template).done(function () {\n                data.context = $(this);\n                that._trigger('completed', e, data);\n                that._trigger('finished', e, data);\n                deferred.resolve();\n              });\n            });\n          });\n        } else {\n          template = that\n            ._renderDownload(files)\n            [that.options.prependFiles ? 'prependTo' : 'appendTo'](\n              that.options.filesContainer\n            );\n          that._forceReflow(template);\n          deferred = that._addFinishedDeferreds();\n          that._transition(template).done(function () {\n            data.context = $(this);\n            that._trigger('completed', e, data);\n            that._trigger('finished', e, data);\n            deferred.resolve();\n          });\n        }\n      },\n      // Callback for failed (abort or error) uploads:\n      fail: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n            $(this).data('blueimp-fileupload') || $(this).data('fileupload'),\n          template,\n          deferred;\n        if (data.context) {\n          data.context.each(function (index) {\n            if (data.errorThrown !== 'abort') {\n              var file = data.files[index];\n              file.error =\n                file.error || data.errorThrown || data.i18n('unknownError');\n              deferred = that._addFinishedDeferreds();\n              that._transition($(this)).done(function () {\n                var node = $(this);\n                template = that._renderDownload([file]).replaceAll(node);\n                that._forceReflow(template);\n                that._transition(template).done(function () {\n                  data.context = $(this);\n                  that._trigger('failed', e, data);\n                  that._trigger('finished', e, data);\n                  deferred.resolve();\n                });\n              });\n            } else {\n              deferred = that._addFinishedDeferreds();\n              that._transition($(this)).done(function () {\n                $(this).remove();\n                that._trigger('failed', e, data);\n                that._trigger('finished', e, data);\n                deferred.resolve();\n              });\n            }\n          });\n        } else if (data.errorThrown !== 'abort') {\n          data.context = that\n            ._renderUpload(data.files)\n            [that.options.prependFiles ? 'prependTo' : 'appendTo'](\n              that.options.filesContainer\n            )\n            .data('data', data);\n          that._forceReflow(data.context);\n          deferred = that._addFinishedDeferreds();\n          that._transition(data.context).done(function () {\n            data.context = $(this);\n            that._trigger('failed', e, data);\n            that._trigger('finished', e, data);\n            deferred.resolve();\n          });\n        } else {\n          that._trigger('failed', e, data);\n          that._trigger('finished', e, data);\n          that._addFinishedDeferreds().resolve();\n        }\n      },\n      // Callback for upload progress events:\n      progress: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var progress = Math.floor((data.loaded / data.total) * 100);\n        if (data.context) {\n          data.context.each(function () {\n            $(this)\n              .find('.progress')\n              .attr('aria-valuenow', progress)\n              .children()\n              .first()\n              .css('width', progress + '%');\n          });\n        }\n      },\n      // Callback for global upload progress events:\n      progressall: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var $this = $(this),\n          progress = Math.floor((data.loaded / data.total) * 100),\n          globalProgressNode = $this.find('.fileupload-progress'),\n          extendedProgressNode = globalProgressNode.find('.progress-extended');\n        if (extendedProgressNode.length) {\n          extendedProgressNode.html(\n            (\n              $this.data('blueimp-fileupload') || $this.data('fileupload')\n            )._renderExtendedProgress(data)\n          );\n        }\n        globalProgressNode\n          .find('.progress')\n          .attr('aria-valuenow', progress)\n          .children()\n          .first()\n          .css('width', progress + '%');\n      },\n      // Callback for uploads start, equivalent to the global ajaxStart event:\n      start: function (e) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n          $(this).data('blueimp-fileupload') || $(this).data('fileupload');\n        that._resetFinishedDeferreds();\n        that\n          ._transition($(this).find('.fileupload-progress'))\n          .done(function () {\n            that._trigger('started', e);\n          });\n      },\n      // Callback for uploads stop, equivalent to the global ajaxStop event:\n      stop: function (e) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n            $(this).data('blueimp-fileupload') || $(this).data('fileupload'),\n          deferred = that._addFinishedDeferreds();\n        $.when.apply($, that._getFinishedDeferreds()).done(function () {\n          that._trigger('stopped', e);\n        });\n        that\n          ._transition($(this).find('.fileupload-progress'))\n          .done(function () {\n            $(this)\n              .find('.progress')\n              .attr('aria-valuenow', '0')\n              .children()\n              .first()\n              .css('width', '0%');\n            $(this).find('.progress-extended').html('&nbsp;');\n            deferred.resolve();\n          });\n      },\n      processstart: function (e) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        $(this).addClass('fileupload-processing');\n      },\n      processstop: function (e) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        $(this).removeClass('fileupload-processing');\n      },\n      // Callback for file deletion:\n      destroy: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n            $(this).data('blueimp-fileupload') || $(this).data('fileupload'),\n          removeNode = function () {\n            that._transition(data.context).done(function () {\n              $(this).remove();\n              that._trigger('destroyed', e, data);\n            });\n          };\n        if (data.url) {\n          data.dataType = data.dataType || that.options.dataType;\n          $.ajax(data)\n            .done(removeNode)\n            .fail(function () {\n              that._trigger('destroyfailed', e, data);\n            });\n        } else {\n          removeNode();\n        }\n      }\n    },\n\n    _resetFinishedDeferreds: function () {\n      this._finishedUploads = [];\n    },\n\n    _addFinishedDeferreds: function (deferred) {\n      // eslint-disable-next-line new-cap\n      var promise = deferred || $.Deferred();\n      this._finishedUploads.push(promise);\n      return promise;\n    },\n\n    _getFinishedDeferreds: function () {\n      return this._finishedUploads;\n    },\n\n    // Link handler, that allows to download files\n    // by drag & drop of the links to the desktop:\n    _enableDragToDesktop: function () {\n      var link = $(this),\n        url = link.prop('href'),\n        name = link.prop('download'),\n        type = 'application/octet-stream';\n      link.on('dragstart', function (e) {\n        try {\n          e.originalEvent.dataTransfer.setData(\n            'DownloadURL',\n            [type, name, url].join(':')\n          );\n        } catch (ignore) {\n          // Ignore exceptions\n        }\n      });\n    },\n\n    _formatFileSize: function (bytes) {\n      if (typeof bytes !== 'number') {\n        return '';\n      }\n      if (bytes >= 1000000000) {\n        return (bytes / 1000000000).toFixed(2) + ' GB';\n      }\n      if (bytes >= 1000000) {\n        return (bytes / 1000000).toFixed(2) + ' MB';\n      }\n      return (bytes / 1000).toFixed(2) + ' KB';\n    },\n\n    _formatBitrate: function (bits) {\n      if (typeof bits !== 'number') {\n        return '';\n      }\n      if (bits >= 1000000000) {\n        return (bits / 1000000000).toFixed(2) + ' Gbit/s';\n      }\n      if (bits >= 1000000) {\n        return (bits / 1000000).toFixed(2) + ' Mbit/s';\n      }\n      if (bits >= 1000) {\n        return (bits / 1000).toFixed(2) + ' kbit/s';\n      }\n      return bits.toFixed(2) + ' bit/s';\n    },\n\n    _formatTime: function (seconds) {\n      var date = new Date(seconds * 1000),\n        days = Math.floor(seconds / 86400);\n      days = days ? days + 'd ' : '';\n      return (\n        days +\n        ('0' + date.getUTCHours()).slice(-2) +\n        ':' +\n        ('0' + date.getUTCMinutes()).slice(-2) +\n        ':' +\n        ('0' + date.getUTCSeconds()).slice(-2)\n      );\n    },\n\n    _formatPercentage: function (floatValue) {\n      return (floatValue * 100).toFixed(2) + ' %';\n    },\n\n    _renderExtendedProgress: function (data) {\n      return (\n        this._formatBitrate(data.bitrate) +\n        ' | ' +\n        this._formatTime(((data.total - data.loaded) * 8) / data.bitrate) +\n        ' | ' +\n        this._formatPercentage(data.loaded / data.total) +\n        ' | ' +\n        this._formatFileSize(data.loaded) +\n        ' / ' +\n        this._formatFileSize(data.total)\n      );\n    },\n\n    _renderTemplate: function (func, files) {\n      if (!func) {\n        return $();\n      }\n      var result = func({\n        files: files,\n        formatFileSize: this._formatFileSize,\n        options: this.options\n      });\n      if (result instanceof $) {\n        return result;\n      }\n      return $(this.options.templatesContainer).html(result).children();\n    },\n\n    _renderPreviews: function (data) {\n      data.context.find('.preview').each(function (index, elm) {\n        $(elm).empty().append(data.files[index].preview);\n      });\n    },\n\n    _renderUpload: function (files) {\n      return this._renderTemplate(this.options.uploadTemplate, files);\n    },\n\n    _renderDownload: function (files) {\n      return this._renderTemplate(this.options.downloadTemplate, files)\n        .find('a[download]')\n        .each(this._enableDragToDesktop)\n        .end();\n    },\n\n    _editHandler: function (e) {\n      e.preventDefault();\n      if (!this.options.edit) return;\n      var that = this,\n        button = $(e.currentTarget),\n        template = button.closest('.template-upload'),\n        data = template.data('data'),\n        index = button.data().index;\n      this.options.edit(data.files[index]).then(function (file) {\n        if (!file) return;\n        data.files[index] = file;\n        data.context.addClass('processing');\n        template.find('.edit,.start').prop('disabled', true);\n        $(that.element)\n          .fileupload('process', data)\n          .always(function () {\n            template\n              .find('.size')\n              .text(that._formatFileSize(data.files[index].size));\n            data.context.removeClass('processing');\n            that._renderPreviews(data);\n          })\n          .done(function () {\n            template.find('.edit,.start').prop('disabled', false);\n          })\n          .fail(function () {\n            template.find('.edit').prop('disabled', false);\n            var error = data.files[index].error;\n            if (error) {\n              template.find('.error').text(error);\n            }\n          });\n      });\n    },\n\n    _startHandler: function (e) {\n      e.preventDefault();\n      var button = $(e.currentTarget),\n        template = button.closest('.template-upload'),\n        data = template.data('data');\n      button.prop('disabled', true);\n      if (data && data.submit) {\n        data.submit();\n      }\n    },\n\n    _cancelHandler: function (e) {\n      e.preventDefault();\n      var template = $(e.currentTarget).closest(\n          '.template-upload,.template-download'\n        ),\n        data = template.data('data') || {};\n      data.context = data.context || template;\n      if (data.abort) {\n        data.abort();\n      } else {\n        data.errorThrown = 'abort';\n        this._trigger('fail', e, data);\n      }\n    },\n\n    _deleteHandler: function (e) {\n      e.preventDefault();\n      var button = $(e.currentTarget);\n      this._trigger(\n        'destroy',\n        e,\n        $.extend(\n          {\n            context: button.closest('.template-download'),\n            type: 'DELETE'\n          },\n          button.data()\n        )\n      );\n    },\n\n    _forceReflow: function (node) {\n      return $.support.transition && node.length && node[0].offsetWidth;\n    },\n\n    _transition: function (node) {\n      // eslint-disable-next-line new-cap\n      var dfd = $.Deferred();\n      if (\n        $.support.transition &&\n        node.hasClass('fade') &&\n        node.is(':visible')\n      ) {\n        var transitionEndHandler = function (e) {\n          // Make sure we don't respond to other transition events\n          // in the container element, e.g. from button elements:\n          if (e.target === node[0]) {\n            node.off($.support.transition.end, transitionEndHandler);\n            dfd.resolveWith(node);\n          }\n        };\n        node\n          .on($.support.transition.end, transitionEndHandler)\n          .toggleClass(this.options.showElementClass);\n      } else {\n        node.toggleClass(this.options.showElementClass);\n        dfd.resolveWith(node);\n      }\n      return dfd;\n    },\n\n    _initButtonBarEventHandlers: function () {\n      var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),\n        filesList = this.options.filesContainer;\n      this._on(fileUploadButtonBar.find('.start'), {\n        click: function (e) {\n          e.preventDefault();\n          filesList.find('.start').trigger('click');\n        }\n      });\n      this._on(fileUploadButtonBar.find('.cancel'), {\n        click: function (e) {\n          e.preventDefault();\n          filesList.find('.cancel').trigger('click');\n        }\n      });\n      this._on(fileUploadButtonBar.find('.delete'), {\n        click: function (e) {\n          e.preventDefault();\n          filesList\n            .find('.toggle:checked')\n            .closest('.template-download')\n            .find('.delete')\n            .trigger('click');\n          fileUploadButtonBar.find('.toggle').prop('checked', false);\n        }\n      });\n      this._on(fileUploadButtonBar.find('.toggle'), {\n        change: function (e) {\n          filesList\n            .find('.toggle')\n            .prop('checked', $(e.currentTarget).is(':checked'));\n        }\n      });\n    },\n\n    _destroyButtonBarEventHandlers: function () {\n      this._off(\n        this.element\n          .find('.fileupload-buttonbar')\n          .find('.start, .cancel, .delete'),\n        'click'\n      );\n      this._off(this.element.find('.fileupload-buttonbar .toggle'), 'change.');\n    },\n\n    _initEventHandlers: function () {\n      this._super();\n      this._on(this.options.filesContainer, {\n        'click .edit': this._editHandler,\n        'click .start': this._startHandler,\n        'click .cancel': this._cancelHandler,\n        'click .delete': this._deleteHandler\n      });\n      this._initButtonBarEventHandlers();\n    },\n\n    _destroyEventHandlers: function () {\n      this._destroyButtonBarEventHandlers();\n      this._off(this.options.filesContainer, 'click');\n      this._super();\n    },\n\n    _enableFileInputButton: function () {\n      this.element\n        .find('.fileinput-button input')\n        .prop('disabled', false)\n        .parent()\n        .removeClass('disabled');\n    },\n\n    _disableFileInputButton: function () {\n      this.element\n        .find('.fileinput-button input')\n        .prop('disabled', true)\n        .parent()\n        .addClass('disabled');\n    },\n\n    _initTemplates: function () {\n      var options = this.options;\n      options.templatesContainer = this.document[0].createElement(\n        options.filesContainer.prop('nodeName')\n      );\n      if (tmpl) {\n        if (options.uploadTemplateId) {\n          options.uploadTemplate = tmpl(options.uploadTemplateId);\n        }\n        if (options.downloadTemplateId) {\n          options.downloadTemplate = tmpl(options.downloadTemplateId);\n        }\n      }\n    },\n\n    _initFilesContainer: function () {\n      var options = this.options;\n      if (options.filesContainer === undefined) {\n        options.filesContainer = this.element.find('.files');\n      } else if (!(options.filesContainer instanceof $)) {\n        options.filesContainer = $(options.filesContainer);\n      }\n    },\n\n    _initSpecialOptions: function () {\n      this._super();\n      this._initFilesContainer();\n      // this._initTemplates();\n    },\n\n    _create: function () {\n      this._super();\n      this._resetFinishedDeferreds();\n      if (!$.support.fileInput) {\n        this._disableFileInputButton();\n      }\n    },\n\n    enable: function () {\n      var wasDisabled = false;\n      if (this.options.disabled) {\n        wasDisabled = true;\n      }\n      this._super();\n      if (wasDisabled) {\n        this.element.find('input, button').prop('disabled', false);\n        this._enableFileInputButton();\n      }\n    },\n\n    disable: function () {\n      if (!this.options.disabled) {\n        this.element.find('input, button').prop('disabled', true);\n        this._disableFileInputButton();\n      }\n      this._super();\n    }\n  });\n});\n","Mageplaza_Core/lib/fileUploader/jquery.fileuploader.js":"/**\n * Custom Uploader\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      'jquery',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-image',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-audio',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-video',\n      'Mageplaza_Core/lib/fileUploader/jquery.iframe-transport',\n    ], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(\n      require('jquery'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-image'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-audio'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-video'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.iframe-transport')\n    );\n  } else {\n    // Browser globals:\n    factory(window.jQuery);\n  }\n})();\n","Mageplaza_Core/lib/fileUploader/vendor/jquery.ui.widget.js":"/*! jQuery UI - v1.12.1+0b7246b6eeadfa9e2696e22f3230f6452f8129dc - 2020-02-20\n * http://jqueryui.com\n * Includes: widget.js\n * Copyright jQuery Foundation and other contributors; Licensed MIT */\n\n/* global define, require */\n/* eslint-disable no-param-reassign, new-cap, jsdoc/require-jsdoc */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS\n    factory(require('jquery'));\n  } else {\n    // Browser globals\n    factory(window.jQuery);\n  }\n})(function ($) {\n  ('use strict');\n\n  $.ui = $.ui || {};\n\n  $.ui.version = '1.12.1';\n\n  /*!\n   * jQuery UI Widget 1.12.1\n   * http://jqueryui.com\n   *\n   * Copyright jQuery Foundation and other contributors\n   * Released under the MIT license.\n   * http://jquery.org/license\n   */\n\n  //>>label: Widget\n  //>>group: Core\n  //>>description: Provides a factory for creating stateful widgets with a common API.\n  //>>docs: http://api.jqueryui.com/jQuery.widget/\n  //>>demos: http://jqueryui.com/widget/\n\n  // Support: jQuery 1.9.x or older\n  // $.expr[ \":\" ] is deprecated.\n  if (!$.expr.pseudos) {\n    $.expr.pseudos = $.expr[':'];\n  }\n\n  // Support: jQuery 1.11.x or older\n  // $.unique has been renamed to $.uniqueSort\n  if (!$.uniqueSort) {\n    $.uniqueSort = $.unique;\n  }\n\n  var widgetUuid = 0;\n  var widgetHasOwnProperty = Array.prototype.hasOwnProperty;\n  var widgetSlice = Array.prototype.slice;\n\n  $.cleanData = (function (orig) {\n    return function (elems) {\n      var events, elem, i;\n      // eslint-disable-next-line eqeqeq\n      for (i = 0; (elem = elems[i]) != null; i++) {\n        // Only trigger remove when necessary to save time\n        events = $._data(elem, 'events');\n        if (events && events.remove) {\n          $(elem).triggerHandler('remove');\n        }\n      }\n      orig(elems);\n    };\n  })($.cleanData);\n\n  $.widget = function (name, base, prototype) {\n    var existingConstructor, constructor, basePrototype;\n\n    // ProxiedPrototype allows the provided prototype to remain unmodified\n    // so that it can be used as a mixin for multiple widgets (#8876)\n    var proxiedPrototype = {};\n\n    var namespace = name.split('.')[0];\n    name = name.split('.')[1];\n    var fullName = namespace + '-' + name;\n\n    if (!prototype) {\n      prototype = base;\n      base = $.Widget;\n    }\n\n    if ($.isArray(prototype)) {\n      prototype = $.extend.apply(null, [{}].concat(prototype));\n    }\n\n    // Create selector for plugin\n    $.expr.pseudos[fullName.toLowerCase()] = function (elem) {\n      return !!$.data(elem, fullName);\n    };\n\n    $[namespace] = $[namespace] || {};\n    existingConstructor = $[namespace][name];\n    constructor = $[namespace][name] = function (options, element) {\n      // Allow instantiation without \"new\" keyword\n      if (!this._createWidget) {\n        return new constructor(options, element);\n      }\n\n      // Allow instantiation without initializing for simple inheritance\n      // must use \"new\" keyword (the code above always passes args)\n      if (arguments.length) {\n        this._createWidget(options, element);\n      }\n    };\n\n    // Extend with the existing constructor to carry over any static properties\n    $.extend(constructor, existingConstructor, {\n      version: prototype.version,\n\n      // Copy the object used to create the prototype in case we need to\n      // redefine the widget later\n      _proto: $.extend({}, prototype),\n\n      // Track widgets that inherit from this widget in case this widget is\n      // redefined after a widget inherits from it\n      _childConstructors: []\n    });\n\n    basePrototype = new base();\n\n    // We need to make the options hash a property directly on the new instance\n    // otherwise we'll modify the options hash on the prototype that we're\n    // inheriting from\n    basePrototype.options = $.widget.extend({}, basePrototype.options);\n    $.each(prototype, function (prop, value) {\n      if (!$.isFunction(value)) {\n        proxiedPrototype[prop] = value;\n        return;\n      }\n      proxiedPrototype[prop] = (function () {\n        function _super() {\n          return base.prototype[prop].apply(this, arguments);\n        }\n\n        function _superApply(args) {\n          return base.prototype[prop].apply(this, args);\n        }\n\n        return function () {\n          var __super = this._super;\n          var __superApply = this._superApply;\n          var returnValue;\n\n          this._super = _super;\n          this._superApply = _superApply;\n\n          returnValue = value.apply(this, arguments);\n\n          this._super = __super;\n          this._superApply = __superApply;\n\n          return returnValue;\n        };\n      })();\n    });\n    constructor.prototype = $.widget.extend(\n      basePrototype,\n      {\n        // TODO: remove support for widgetEventPrefix\n        // always use the name + a colon as the prefix, e.g., draggable:start\n        // don't prefix for widgets that aren't DOM-based\n        widgetEventPrefix: existingConstructor\n          ? basePrototype.widgetEventPrefix || name\n          : name\n      },\n      proxiedPrototype,\n      {\n        constructor: constructor,\n        namespace: namespace,\n        widgetName: name,\n        widgetFullName: fullName\n      }\n    );\n\n    // If this widget is being redefined then we need to find all widgets that\n    // are inheriting from it and redefine all of them so that they inherit from\n    // the new version of this widget. We're essentially trying to replace one\n    // level in the prototype chain.\n    if (existingConstructor) {\n      $.each(existingConstructor._childConstructors, function (i, child) {\n        var childPrototype = child.prototype;\n\n        // Redefine the child widget using the same prototype that was\n        // originally used, but inherit from the new version of the base\n        $.widget(\n          childPrototype.namespace + '.' + childPrototype.widgetName,\n          constructor,\n          child._proto\n        );\n      });\n\n      // Remove the list of existing child constructors from the old constructor\n      // so the old child constructors can be garbage collected\n      delete existingConstructor._childConstructors;\n    } else {\n      base._childConstructors.push(constructor);\n    }\n\n    $.widget.bridge(name, constructor);\n\n    return constructor;\n  };\n\n  $.widget.extend = function (target) {\n    var input = widgetSlice.call(arguments, 1);\n    var inputIndex = 0;\n    var inputLength = input.length;\n    var key;\n    var value;\n\n    for (; inputIndex < inputLength; inputIndex++) {\n      for (key in input[inputIndex]) {\n        value = input[inputIndex][key];\n        if (\n          widgetHasOwnProperty.call(input[inputIndex], key) &&\n          value !== undefined\n        ) {\n          // Clone objects\n          if ($.isPlainObject(value)) {\n            target[key] = $.isPlainObject(target[key])\n              ? $.widget.extend({}, target[key], value)\n              : // Don't extend strings, arrays, etc. with objects\n                $.widget.extend({}, value);\n\n            // Copy everything else by reference\n          } else {\n            target[key] = value;\n          }\n        }\n      }\n    }\n    return target;\n  };\n\n  $.widget.bridge = function (name, object) {\n    var fullName = object.prototype.widgetFullName || name;\n    $.fn[name] = function (options) {\n      var isMethodCall = typeof options === 'string';\n      var args = widgetSlice.call(arguments, 1);\n      var returnValue = this;\n\n      if (isMethodCall) {\n        // If this is an empty collection, we need to have the instance method\n        // return undefined instead of the jQuery instance\n        if (!this.length && options === 'instance') {\n          returnValue = undefined;\n        } else {\n          this.each(function () {\n            var methodValue;\n            var instance = $.data(this, fullName);\n\n            if (options === 'instance') {\n              returnValue = instance;\n              return false;\n            }\n\n            if (!instance) {\n              return $.error(\n                'cannot call methods on ' +\n                  name +\n                  ' prior to initialization; ' +\n                  \"attempted to call method '\" +\n                  options +\n                  \"'\"\n              );\n            }\n\n            if (!$.isFunction(instance[options]) || options.charAt(0) === '_') {\n              return $.error(\n                \"no such method '\" +\n                  options +\n                  \"' for \" +\n                  name +\n                  ' widget instance'\n              );\n            }\n\n            methodValue = instance[options].apply(instance, args);\n\n            if (methodValue !== instance && methodValue !== undefined) {\n              returnValue =\n                methodValue && methodValue.jquery\n                  ? returnValue.pushStack(methodValue.get())\n                  : methodValue;\n              return false;\n            }\n          });\n        }\n      } else {\n        // Allow multiple hashes to be passed on init\n        if (args.length) {\n          options = $.widget.extend.apply(null, [options].concat(args));\n        }\n\n        this.each(function () {\n          var instance = $.data(this, fullName);\n          if (instance) {\n            instance.option(options || {});\n            if (instance._init) {\n              instance._init();\n            }\n          } else {\n            $.data(this, fullName, new object(options, this));\n          }\n        });\n      }\n\n      return returnValue;\n    };\n  };\n\n  $.Widget = function (/* options, element */) {};\n  $.Widget._childConstructors = [];\n\n  $.Widget.prototype = {\n    widgetName: 'widget',\n    widgetEventPrefix: '',\n    defaultElement: '<div>',\n\n    options: {\n      classes: {},\n      disabled: false,\n\n      // Callbacks\n      create: null\n    },\n\n    _createWidget: function (options, element) {\n      element = $(element || this.defaultElement || this)[0];\n      this.element = $(element);\n      this.uuid = widgetUuid++;\n      this.eventNamespace = '.' + this.widgetName + this.uuid;\n\n      this.bindings = $();\n      this.hoverable = $();\n      this.focusable = $();\n      this.classesElementLookup = {};\n\n      if (element !== this) {\n        $.data(element, this.widgetFullName, this);\n        this._on(true, this.element, {\n          remove: function (event) {\n            if (event.target === element) {\n              this.destroy();\n            }\n          }\n        });\n        this.document = $(\n          element.style\n            ? // Element within the document\n              element.ownerDocument\n            : // Element is window or document\n              element.document || element\n        );\n        this.window = $(\n          this.document[0].defaultView || this.document[0].parentWindow\n        );\n      }\n\n      this.options = $.widget.extend(\n        {},\n        this.options,\n        this._getCreateOptions(),\n        options\n      );\n\n      this._create();\n\n      if (this.options.disabled) {\n        this._setOptionDisabled(this.options.disabled);\n      }\n\n      this._trigger('create', null, this._getCreateEventData());\n      this._init();\n    },\n\n    _getCreateOptions: function () {\n      return {};\n    },\n\n    _getCreateEventData: $.noop,\n\n    _create: $.noop,\n\n    _init: $.noop,\n\n    destroy: function () {\n      var that = this;\n\n      this._destroy();\n      $.each(this.classesElementLookup, function (key, value) {\n        that._removeClass(value, key);\n      });\n\n      // We can probably remove the unbind calls in 2.0\n      // all event bindings should go through this._on()\n      this.element.off(this.eventNamespace).removeData(this.widgetFullName);\n      this.widget().off(this.eventNamespace).removeAttr('aria-disabled');\n\n      // Clean up events and states\n      this.bindings.off(this.eventNamespace);\n    },\n\n    _destroy: $.noop,\n\n    widget: function () {\n      return this.element;\n    },\n\n    option: function (key, value) {\n      var options = key;\n      var parts;\n      var curOption;\n      var i;\n\n      if (arguments.length === 0) {\n        // Don't return a reference to the internal hash\n        return $.widget.extend({}, this.options);\n      }\n\n      if (typeof key === 'string') {\n        // Handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n        options = {};\n        parts = key.split('.');\n        key = parts.shift();\n        if (parts.length) {\n          curOption = options[key] = $.widget.extend({}, this.options[key]);\n          for (i = 0; i < parts.length - 1; i++) {\n            curOption[parts[i]] = curOption[parts[i]] || {};\n            curOption = curOption[parts[i]];\n          }\n          key = parts.pop();\n          if (arguments.length === 1) {\n            return curOption[key] === undefined ? null : curOption[key];\n          }\n          curOption[key] = value;\n        } else {\n          if (arguments.length === 1) {\n            return this.options[key] === undefined ? null : this.options[key];\n          }\n          options[key] = value;\n        }\n      }\n\n      this._setOptions(options);\n\n      return this;\n    },\n\n    _setOptions: function (options) {\n      var key;\n\n      for (key in options) {\n        this._setOption(key, options[key]);\n      }\n\n      return this;\n    },\n\n    _setOption: function (key, value) {\n      if (key === 'classes') {\n        this._setOptionClasses(value);\n      }\n\n      this.options[key] = value;\n\n      if (key === 'disabled') {\n        this._setOptionDisabled(value);\n      }\n\n      return this;\n    },\n\n    _setOptionClasses: function (value) {\n      var classKey, elements, currentElements;\n\n      for (classKey in value) {\n        currentElements = this.classesElementLookup[classKey];\n        if (\n          value[classKey] === this.options.classes[classKey] ||\n          !currentElements ||\n          !currentElements.length\n        ) {\n          continue;\n        }\n\n        // We are doing this to create a new jQuery object because the _removeClass() call\n        // on the next line is going to destroy the reference to the current elements being\n        // tracked. We need to save a copy of this collection so that we can add the new classes\n        // below.\n        elements = $(currentElements.get());\n        this._removeClass(currentElements, classKey);\n\n        // We don't use _addClass() here, because that uses this.options.classes\n        // for generating the string of classes. We want to use the value passed in from\n        // _setOption(), this is the new value of the classes option which was passed to\n        // _setOption(). We pass this value directly to _classes().\n        elements.addClass(\n          this._classes({\n            element: elements,\n            keys: classKey,\n            classes: value,\n            add: true\n          })\n        );\n      }\n    },\n\n    _setOptionDisabled: function (value) {\n      this._toggleClass(\n        this.widget(),\n        this.widgetFullName + '-disabled',\n        null,\n        !!value\n      );\n\n      // If the widget is becoming disabled, then nothing is interactive\n      if (value) {\n        this._removeClass(this.hoverable, null, 'ui-state-hover');\n        this._removeClass(this.focusable, null, 'ui-state-focus');\n      }\n    },\n\n    enable: function () {\n      return this._setOptions({ disabled: false });\n    },\n\n    disable: function () {\n      return this._setOptions({ disabled: true });\n    },\n\n    _classes: function (options) {\n      var full = [];\n      var that = this;\n\n      options = $.extend(\n        {\n          element: this.element,\n          classes: this.options.classes || {}\n        },\n        options\n      );\n\n      function bindRemoveEvent() {\n        options.element.each(function (_, element) {\n          var isTracked = $.map(that.classesElementLookup, function (elements) {\n            return elements;\n          }).some(function (elements) {\n            return elements.is(element);\n          });\n\n          if (!isTracked) {\n            that._on($(element), {\n              remove: '_untrackClassesElement'\n            });\n          }\n        });\n      }\n\n      function processClassString(classes, checkOption) {\n        var current, i;\n        for (i = 0; i < classes.length; i++) {\n          current = that.classesElementLookup[classes[i]] || $();\n          if (options.add) {\n            bindRemoveEvent();\n            current = $(\n              $.uniqueSort(current.get().concat(options.element.get()))\n            );\n          } else {\n            current = $(current.not(options.element).get());\n          }\n          that.classesElementLookup[classes[i]] = current;\n          full.push(classes[i]);\n          if (checkOption && options.classes[classes[i]]) {\n            full.push(options.classes[classes[i]]);\n          }\n        }\n      }\n\n      if (options.keys) {\n        processClassString(options.keys.match(/\\S+/g) || [], true);\n      }\n      if (options.extra) {\n        processClassString(options.extra.match(/\\S+/g) || []);\n      }\n\n      return full.join(' ');\n    },\n\n    _untrackClassesElement: function (event) {\n      var that = this;\n      $.each(that.classesElementLookup, function (key, value) {\n        if ($.inArray(event.target, value) !== -1) {\n          that.classesElementLookup[key] = $(value.not(event.target).get());\n        }\n      });\n\n      this._off($(event.target));\n    },\n\n    _removeClass: function (element, keys, extra) {\n      return this._toggleClass(element, keys, extra, false);\n    },\n\n    _addClass: function (element, keys, extra) {\n      return this._toggleClass(element, keys, extra, true);\n    },\n\n    _toggleClass: function (element, keys, extra, add) {\n      add = typeof add === 'boolean' ? add : extra;\n      var shift = typeof element === 'string' || element === null,\n        options = {\n          extra: shift ? keys : extra,\n          keys: shift ? element : keys,\n          element: shift ? this.element : element,\n          add: add\n        };\n      options.element.toggleClass(this._classes(options), add);\n      return this;\n    },\n\n    _on: function (suppressDisabledCheck, element, handlers) {\n      var delegateElement;\n      var instance = this;\n\n      // No suppressDisabledCheck flag, shuffle arguments\n      if (typeof suppressDisabledCheck !== 'boolean') {\n        handlers = element;\n        element = suppressDisabledCheck;\n        suppressDisabledCheck = false;\n      }\n\n      // No element argument, shuffle and use this.element\n      if (!handlers) {\n        handlers = element;\n        element = this.element;\n        delegateElement = this.widget();\n      } else {\n        element = delegateElement = $(element);\n        this.bindings = this.bindings.add(element);\n      }\n\n      $.each(handlers, function (event, handler) {\n        function handlerProxy() {\n          // Allow widgets to customize the disabled handling\n          // - disabled as an array instead of boolean\n          // - disabled class as method for disabling individual parts\n          if (\n            !suppressDisabledCheck &&\n            (instance.options.disabled === true ||\n              $(this).hasClass('ui-state-disabled'))\n          ) {\n            return;\n          }\n          return (\n            typeof handler === 'string' ? instance[handler] : handler\n          ).apply(instance, arguments);\n        }\n\n        // Copy the guid so direct unbinding works\n        if (typeof handler !== 'string') {\n          handlerProxy.guid = handler.guid =\n            handler.guid || handlerProxy.guid || $.guid++;\n        }\n\n        var match = event.match(/^([\\w:-]*)\\s*(.*)$/);\n        var eventName = match[1] + instance.eventNamespace;\n        var selector = match[2];\n\n        if (selector) {\n          delegateElement.on(eventName, selector, handlerProxy);\n        } else {\n          element.on(eventName, handlerProxy);\n        }\n      });\n    },\n\n    _off: function (element, eventName) {\n      eventName =\n        (eventName || '').split(' ').join(this.eventNamespace + ' ') +\n        this.eventNamespace;\n      element.off(eventName);\n\n      // Clear the stack to avoid memory leaks (#10056)\n      this.bindings = $(this.bindings.not(element).get());\n      this.focusable = $(this.focusable.not(element).get());\n      this.hoverable = $(this.hoverable.not(element).get());\n    },\n\n    _delay: function (handler, delay) {\n      var instance = this;\n      function handlerProxy() {\n        return (\n          typeof handler === 'string' ? instance[handler] : handler\n        ).apply(instance, arguments);\n      }\n      return setTimeout(handlerProxy, delay || 0);\n    },\n\n    _hoverable: function (element) {\n      this.hoverable = this.hoverable.add(element);\n      this._on(element, {\n        mouseenter: function (event) {\n          this._addClass($(event.currentTarget), null, 'ui-state-hover');\n        },\n        mouseleave: function (event) {\n          this._removeClass($(event.currentTarget), null, 'ui-state-hover');\n        }\n      });\n    },\n\n    _focusable: function (element) {\n      this.focusable = this.focusable.add(element);\n      this._on(element, {\n        focusin: function (event) {\n          this._addClass($(event.currentTarget), null, 'ui-state-focus');\n        },\n        focusout: function (event) {\n          this._removeClass($(event.currentTarget), null, 'ui-state-focus');\n        }\n      });\n    },\n\n    _trigger: function (type, event, data) {\n      var prop, orig;\n      var callback = this.options[type];\n\n      data = data || {};\n      event = $.Event(event);\n      event.type = (\n        type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type\n      ).toLowerCase();\n\n      // The original event may come from any element\n      // so we need to reset the target on the new event\n      event.target = this.element[0];\n\n      // Copy original event properties over to the new event\n      orig = event.originalEvent;\n      if (orig) {\n        for (prop in orig) {\n          if (!(prop in event)) {\n            event[prop] = orig[prop];\n          }\n        }\n      }\n\n      this.element.trigger(event, data);\n      return !(\n        ($.isFunction(callback) &&\n          callback.apply(this.element[0], [event].concat(data)) === false) ||\n        event.isDefaultPrevented()\n      );\n    }\n  };\n\n  $.each({ show: 'fadeIn', hide: 'fadeOut' }, function (method, defaultEffect) {\n    $.Widget.prototype['_' + method] = function (element, options, callback) {\n      if (typeof options === 'string') {\n        options = { effect: options };\n      }\n\n      var hasOptions;\n      var effectName = !options\n        ? method\n        : options === true || typeof options === 'number'\n        ? defaultEffect\n        : options.effect || defaultEffect;\n\n      options = options || {};\n      if (typeof options === 'number') {\n        options = { duration: options };\n      }\n\n      hasOptions = !$.isEmptyObject(options);\n      options.complete = callback;\n\n      if (options.delay) {\n        element.delay(options.delay);\n      }\n\n      if (hasOptions && $.effects && $.effects.effect[effectName]) {\n        element[method](options);\n      } else if (effectName !== method && element[effectName]) {\n        element[effectName](options.duration, options.easing, callback);\n      } else {\n        element.queue(function (next) {\n          $(this)[method]();\n          if (callback) {\n            callback.call(element[0]);\n          }\n          next();\n        });\n      }\n    };\n  });\n});\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-canvas-to-blob/js/canvas-to-blob.js":"/*\n * JavaScript Canvas to Blob\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on stackoverflow user Stoive's code snippet:\n * http://stackoverflow.com/q/4998908\n */\n\n/* global define, Uint8Array, ArrayBuffer, module */\n\n;(function (window) {\n  'use strict'\n\n  var CanvasPrototype =\n    window.HTMLCanvasElement && window.HTMLCanvasElement.prototype\n  var hasBlobConstructor =\n    window.Blob &&\n    (function () {\n      try {\n        return Boolean(new Blob())\n      } catch (e) {\n        return false\n      }\n    })()\n  var hasArrayBufferViewSupport =\n    hasBlobConstructor &&\n    window.Uint8Array &&\n    (function () {\n      try {\n        return new Blob([new Uint8Array(100)]).size === 100\n      } catch (e) {\n        return false\n      }\n    })()\n  var BlobBuilder =\n    window.BlobBuilder ||\n    window.WebKitBlobBuilder ||\n    window.MozBlobBuilder ||\n    window.MSBlobBuilder\n  var dataURIPattern = /^data:((.*?)(;charset=.*?)?)(;base64)?,/\n  var dataURLtoBlob =\n    (hasBlobConstructor || BlobBuilder) &&\n    window.atob &&\n    window.ArrayBuffer &&\n    window.Uint8Array &&\n    function (dataURI) {\n      var matches,\n        mediaType,\n        isBase64,\n        dataString,\n        byteString,\n        arrayBuffer,\n        intArray,\n        i,\n        bb\n      // Parse the dataURI components as per RFC 2397\n      matches = dataURI.match(dataURIPattern)\n      if (!matches) {\n        throw new Error('invalid data URI')\n      }\n      // Default to text/plain;charset=US-ASCII\n      mediaType = matches[2]\n        ? matches[1]\n        : 'text/plain' + (matches[3] || ';charset=US-ASCII')\n      isBase64 = !!matches[4]\n      dataString = dataURI.slice(matches[0].length)\n      if (isBase64) {\n        // Convert base64 to raw binary data held in a string:\n        byteString = atob(dataString)\n      } else {\n        // Convert base64/URLEncoded data component to raw binary:\n        byteString = decodeURIComponent(dataString)\n      }\n      // Write the bytes of the string to an ArrayBuffer:\n      arrayBuffer = new ArrayBuffer(byteString.length)\n      intArray = new Uint8Array(arrayBuffer)\n      for (i = 0; i < byteString.length; i += 1) {\n        intArray[i] = byteString.charCodeAt(i)\n      }\n      // Write the ArrayBuffer (or ArrayBufferView) to a blob:\n      if (hasBlobConstructor) {\n        return new Blob([hasArrayBufferViewSupport ? intArray : arrayBuffer], {\n          type: mediaType\n        })\n      }\n      bb = new BlobBuilder()\n      bb.append(arrayBuffer)\n      return bb.getBlob(mediaType)\n    }\n  if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {\n    if (CanvasPrototype.mozGetAsFile) {\n      CanvasPrototype.toBlob = function (callback, type, quality) {\n        var self = this\n        setTimeout(function () {\n          if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {\n            callback(dataURLtoBlob(self.toDataURL(type, quality)))\n          } else {\n            callback(self.mozGetAsFile('blob', type))\n          }\n        })\n      }\n    } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {\n      if (CanvasPrototype.msToBlob) {\n        CanvasPrototype.toBlob = function (callback, type, quality) {\n          var self = this\n          setTimeout(function () {\n            if (\n              ((type && type !== 'image/png') || quality) &&\n              CanvasPrototype.toDataURL &&\n              dataURLtoBlob\n            ) {\n              callback(dataURLtoBlob(self.toDataURL(type, quality)))\n            } else {\n              callback(self.msToBlob(type))\n            }\n          })\n        }\n      } else {\n        CanvasPrototype.toBlob = function (callback, type, quality) {\n          var self = this\n          setTimeout(function () {\n            callback(dataURLtoBlob(self.toDataURL(type, quality)))\n          })\n        }\n      }\n    }\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return dataURLtoBlob\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = dataURLtoBlob\n  } else {\n    window.dataURLtoBlob = dataURLtoBlob\n  }\n})(window)\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-scale.js":"/*\n * JavaScript Load Image Scaling\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var originalTransform = loadImage.transform\n\n  loadImage.createCanvas = function (width, height, offscreen) {\n    if (offscreen && loadImage.global.OffscreenCanvas) {\n      return new OffscreenCanvas(width, height)\n    }\n    var canvas = document.createElement('canvas')\n    canvas.width = width\n    canvas.height = height\n    return canvas\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    originalTransform.call(\n      loadImage,\n      loadImage.scale(img, options, data),\n      options,\n      callback,\n      file,\n      data\n    )\n  }\n\n  // Transform image coordinates, allows to override e.g.\n  // the canvas orientation based on the orientation option,\n  // gets canvas, options and data passed as arguments:\n  loadImage.transformCoordinates = function () {}\n\n  // Returns transformed options, allows to override e.g.\n  // maxWidth, maxHeight and crop options based on the aspectRatio.\n  // gets img, options, data passed as arguments:\n  loadImage.getTransformedOptions = function (img, options) {\n    var aspectRatio = options.aspectRatio\n    var newOptions\n    var i\n    var width\n    var height\n    if (!aspectRatio) {\n      return options\n    }\n    newOptions = {}\n    for (i in options) {\n      if (Object.prototype.hasOwnProperty.call(options, i)) {\n        newOptions[i] = options[i]\n      }\n    }\n    newOptions.crop = true\n    width = img.naturalWidth || img.width\n    height = img.naturalHeight || img.height\n    if (width / height > aspectRatio) {\n      newOptions.maxWidth = height * aspectRatio\n      newOptions.maxHeight = height\n    } else {\n      newOptions.maxWidth = width\n      newOptions.maxHeight = width / aspectRatio\n    }\n    return newOptions\n  }\n\n  // Canvas render method, allows to implement a different rendering algorithm:\n  loadImage.drawImage = function (\n    img,\n    canvas,\n    sourceX,\n    sourceY,\n    sourceWidth,\n    sourceHeight,\n    destWidth,\n    destHeight,\n    options\n  ) {\n    var ctx = canvas.getContext('2d')\n    if (options.imageSmoothingEnabled === false) {\n      ctx.msImageSmoothingEnabled = false\n      ctx.imageSmoothingEnabled = false\n    } else if (options.imageSmoothingQuality) {\n      ctx.imageSmoothingQuality = options.imageSmoothingQuality\n    }\n    ctx.drawImage(\n      img,\n      sourceX,\n      sourceY,\n      sourceWidth,\n      sourceHeight,\n      0,\n      0,\n      destWidth,\n      destHeight\n    )\n    return ctx\n  }\n\n  // Determines if the target image should be a canvas element:\n  loadImage.requiresCanvas = function (options) {\n    return options.canvas || options.crop || !!options.aspectRatio\n  }\n\n  // Scales and/or crops the given image (img or canvas HTML element)\n  // using the given options:\n  loadImage.scale = function (img, options, data) {\n    // eslint-disable-next-line no-param-reassign\n    options = options || {}\n    // eslint-disable-next-line no-param-reassign\n    data = data || {}\n    var useCanvas =\n      img.getContext ||\n      (loadImage.requiresCanvas(options) &&\n        !!loadImage.global.HTMLCanvasElement)\n    var width = img.naturalWidth || img.width\n    var height = img.naturalHeight || img.height\n    var destWidth = width\n    var destHeight = height\n    var maxWidth\n    var maxHeight\n    var minWidth\n    var minHeight\n    var sourceWidth\n    var sourceHeight\n    var sourceX\n    var sourceY\n    var pixelRatio\n    var downsamplingRatio\n    var tmp\n    var canvas\n    /**\n     * Scales up image dimensions\n     */\n    function scaleUp() {\n      var scale = Math.max(\n        (minWidth || destWidth) / destWidth,\n        (minHeight || destHeight) / destHeight\n      )\n      if (scale > 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    /**\n     * Scales down image dimensions\n     */\n    function scaleDown() {\n      var scale = Math.min(\n        (maxWidth || destWidth) / destWidth,\n        (maxHeight || destHeight) / destHeight\n      )\n      if (scale < 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    if (useCanvas) {\n      // eslint-disable-next-line no-param-reassign\n      options = loadImage.getTransformedOptions(img, options, data)\n      sourceX = options.left || 0\n      sourceY = options.top || 0\n      if (options.sourceWidth) {\n        sourceWidth = options.sourceWidth\n        if (options.right !== undefined && options.left === undefined) {\n          sourceX = width - sourceWidth - options.right\n        }\n      } else {\n        sourceWidth = width - sourceX - (options.right || 0)\n      }\n      if (options.sourceHeight) {\n        sourceHeight = options.sourceHeight\n        if (options.bottom !== undefined && options.top === undefined) {\n          sourceY = height - sourceHeight - options.bottom\n        }\n      } else {\n        sourceHeight = height - sourceY - (options.bottom || 0)\n      }\n      destWidth = sourceWidth\n      destHeight = sourceHeight\n    }\n    maxWidth = options.maxWidth\n    maxHeight = options.maxHeight\n    minWidth = options.minWidth\n    minHeight = options.minHeight\n    if (useCanvas && maxWidth && maxHeight && options.crop) {\n      destWidth = maxWidth\n      destHeight = maxHeight\n      tmp = sourceWidth / sourceHeight - maxWidth / maxHeight\n      if (tmp < 0) {\n        sourceHeight = (maxHeight * sourceWidth) / maxWidth\n        if (options.top === undefined && options.bottom === undefined) {\n          sourceY = (height - sourceHeight) / 2\n        }\n      } else if (tmp > 0) {\n        sourceWidth = (maxWidth * sourceHeight) / maxHeight\n        if (options.left === undefined && options.right === undefined) {\n          sourceX = (width - sourceWidth) / 2\n        }\n      }\n    } else {\n      if (options.contain || options.cover) {\n        minWidth = maxWidth = maxWidth || minWidth\n        minHeight = maxHeight = maxHeight || minHeight\n      }\n      if (options.cover) {\n        scaleDown()\n        scaleUp()\n      } else {\n        scaleUp()\n        scaleDown()\n      }\n    }\n    if (useCanvas) {\n      pixelRatio = options.pixelRatio\n      if (\n        pixelRatio > 1 &&\n        // Check if the image has not yet had the device pixel ratio applied:\n        !(\n          img.style.width &&\n          Math.floor(parseFloat(img.style.width, 10)) ===\n            Math.floor(width / pixelRatio)\n        )\n      ) {\n        destWidth *= pixelRatio\n        destHeight *= pixelRatio\n      }\n      // Check if workaround for Chromium orientation crop bug is required:\n      // https://bugs.chromium.org/p/chromium/issues/detail?id=1074354\n      if (\n        loadImage.orientationCropBug &&\n        !img.getContext &&\n        (sourceX || sourceY || sourceWidth !== width || sourceHeight !== height)\n      ) {\n        // Write the complete source image to an intermediate canvas first:\n        tmp = img\n        // eslint-disable-next-line no-param-reassign\n        img = loadImage.createCanvas(width, height, true)\n        loadImage.drawImage(\n          tmp,\n          img,\n          0,\n          0,\n          width,\n          height,\n          width,\n          height,\n          options\n        )\n      }\n      downsamplingRatio = options.downsamplingRatio\n      if (\n        downsamplingRatio > 0 &&\n        downsamplingRatio < 1 &&\n        destWidth < sourceWidth &&\n        destHeight < sourceHeight\n      ) {\n        while (sourceWidth * downsamplingRatio > destWidth) {\n          canvas = loadImage.createCanvas(\n            sourceWidth * downsamplingRatio,\n            sourceHeight * downsamplingRatio,\n            true\n          )\n          loadImage.drawImage(\n            img,\n            canvas,\n            sourceX,\n            sourceY,\n            sourceWidth,\n            sourceHeight,\n            canvas.width,\n            canvas.height,\n            options\n          )\n          sourceX = 0\n          sourceY = 0\n          sourceWidth = canvas.width\n          sourceHeight = canvas.height\n          // eslint-disable-next-line no-param-reassign\n          img = canvas\n        }\n      }\n      canvas = loadImage.createCanvas(destWidth, destHeight)\n      loadImage.transformCoordinates(canvas, options, data)\n      if (pixelRatio > 1) {\n        canvas.style.width = canvas.width / pixelRatio + 'px'\n      }\n      loadImage\n        .drawImage(\n          img,\n          canvas,\n          sourceX,\n          sourceY,\n          sourceWidth,\n          sourceHeight,\n          destWidth,\n          destHeight,\n          options\n        )\n        .setTransform(1, 0, 0, 1, 0, 0) // reset to the identity matrix\n      return canvas\n    }\n    img.width = destWidth\n    img.height = destHeight\n    return img\n  }\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif.js":"/*\n * JavaScript Load Image Exif Parser\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require, DataView */\n\n/* eslint-disable no-console */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'), require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  /**\n   * Exif tag map\n   *\n   * @name ExifMap\n   * @class\n   * @param {number|string} tagCode IFD tag code\n   */\n  function ExifMap(tagCode) {\n    if (tagCode) {\n      Object.defineProperty(this, 'map', {\n        value: this.ifds[tagCode].map\n      })\n      Object.defineProperty(this, 'tags', {\n        value: (this.tags && this.tags[tagCode]) || {}\n      })\n    }\n  }\n\n  ExifMap.prototype.map = {\n    Orientation: 0x0112,\n    Thumbnail: 'ifd1',\n    Blob: 0x0201, // Alias for JPEGInterchangeFormat\n    Exif: 0x8769,\n    GPSInfo: 0x8825,\n    Interoperability: 0xa005\n  }\n\n  ExifMap.prototype.ifds = {\n    ifd1: { name: 'Thumbnail', map: ExifMap.prototype.map },\n    0x8769: { name: 'Exif', map: {} },\n    0x8825: { name: 'GPSInfo', map: {} },\n    0xa005: { name: 'Interoperability', map: {} }\n  }\n\n  /**\n   * Retrieves exif tag value\n   *\n   * @param {number|string} id Exif tag code or name\n   * @returns {object} Exif tag value\n   */\n  ExifMap.prototype.get = function (id) {\n    return this[id] || this[this.map[id]]\n  }\n\n  /**\n   * Returns the Exif Thumbnail data as Blob.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} offset Thumbnail data offset\n   * @param {number} length Thumbnail data length\n   * @returns {undefined|Blob} Returns the Thumbnail Blob or undefined\n   */\n  function getExifThumbnail(dataView, offset, length) {\n    if (!length) return\n    if (offset + length > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid thumbnail data.')\n      return\n    }\n    return new Blob(\n      [loadImage.bufferSlice.call(dataView.buffer, offset, offset + length)],\n      {\n        type: 'image/jpeg'\n      }\n    )\n  }\n\n  var ExifTagTypes = {\n    // byte, 8-bit unsigned int:\n    1: {\n      getValue: function (dataView, dataOffset) {\n        return dataView.getUint8(dataOffset)\n      },\n      size: 1\n    },\n    // ascii, 8-bit byte:\n    2: {\n      getValue: function (dataView, dataOffset) {\n        return String.fromCharCode(dataView.getUint8(dataOffset))\n      },\n      size: 1,\n      ascii: true\n    },\n    // short, 16 bit int:\n    3: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getUint16(dataOffset, littleEndian)\n      },\n      size: 2\n    },\n    // long, 32 bit int:\n    4: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getUint32(dataOffset, littleEndian)\n      },\n      size: 4\n    },\n    // rational = two long values, first is numerator, second is denominator:\n    5: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return (\n          dataView.getUint32(dataOffset, littleEndian) /\n          dataView.getUint32(dataOffset + 4, littleEndian)\n        )\n      },\n      size: 8\n    },\n    // slong, 32 bit signed int:\n    9: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getInt32(dataOffset, littleEndian)\n      },\n      size: 4\n    },\n    // srational, two slongs, first is numerator, second is denominator:\n    10: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return (\n          dataView.getInt32(dataOffset, littleEndian) /\n          dataView.getInt32(dataOffset + 4, littleEndian)\n        )\n      },\n      size: 8\n    }\n  }\n  // undefined, 8-bit byte, value depending on field:\n  ExifTagTypes[7] = ExifTagTypes[1]\n\n  /**\n   * Returns Exif tag value.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} tiffOffset TIFF offset\n   * @param {number} offset Tag offset\n   * @param {number} type Tag type\n   * @param {number} length Tag length\n   * @param {boolean} littleEndian Little endian encoding\n   * @returns {object} Tag value\n   */\n  function getExifValue(\n    dataView,\n    tiffOffset,\n    offset,\n    type,\n    length,\n    littleEndian\n  ) {\n    var tagType = ExifTagTypes[type]\n    var tagSize\n    var dataOffset\n    var values\n    var i\n    var str\n    var c\n    if (!tagType) {\n      console.log('Invalid Exif data: Invalid tag type.')\n      return\n    }\n    tagSize = tagType.size * length\n    // Determine if the value is contained in the dataOffset bytes,\n    // or if the value at the dataOffset is a pointer to the actual data:\n    dataOffset =\n      tagSize > 4\n        ? tiffOffset + dataView.getUint32(offset + 8, littleEndian)\n        : offset + 8\n    if (dataOffset + tagSize > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid data offset.')\n      return\n    }\n    if (length === 1) {\n      return tagType.getValue(dataView, dataOffset, littleEndian)\n    }\n    values = []\n    for (i = 0; i < length; i += 1) {\n      values[i] = tagType.getValue(\n        dataView,\n        dataOffset + i * tagType.size,\n        littleEndian\n      )\n    }\n    if (tagType.ascii) {\n      str = ''\n      // Concatenate the chars:\n      for (i = 0; i < values.length; i += 1) {\n        c = values[i]\n        // Ignore the terminating NULL byte(s):\n        if (c === '\\u0000') {\n          break\n        }\n        str += c\n      }\n      return str\n    }\n    return values\n  }\n\n  /**\n   * Determines if the given tag should be included.\n   *\n   * @param {object} includeTags Map of tags to include\n   * @param {object} excludeTags Map of tags to exclude\n   * @param {number|string} tagCode Tag code to check\n   * @returns {boolean} True if the tag should be included\n   */\n  function shouldIncludeTag(includeTags, excludeTags, tagCode) {\n    return (\n      (!includeTags || includeTags[tagCode]) &&\n      (!excludeTags || excludeTags[tagCode] !== true)\n    )\n  }\n\n  /**\n   * Parses Exif tags.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} tiffOffset TIFF offset\n   * @param {number} dirOffset Directory offset\n   * @param {boolean} littleEndian Little endian encoding\n   * @param {ExifMap} tags Map to store parsed exif tags\n   * @param {ExifMap} tagOffsets Map to store parsed exif tag offsets\n   * @param {object} includeTags Map of tags to include\n   * @param {object} excludeTags Map of tags to exclude\n   * @returns {number} Next directory offset\n   */\n  function parseExifTags(\n    dataView,\n    tiffOffset,\n    dirOffset,\n    littleEndian,\n    tags,\n    tagOffsets,\n    includeTags,\n    excludeTags\n  ) {\n    var tagsNumber, dirEndOffset, i, tagOffset, tagNumber, tagValue\n    if (dirOffset + 6 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid directory offset.')\n      return\n    }\n    tagsNumber = dataView.getUint16(dirOffset, littleEndian)\n    dirEndOffset = dirOffset + 2 + 12 * tagsNumber\n    if (dirEndOffset + 4 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid directory size.')\n      return\n    }\n    for (i = 0; i < tagsNumber; i += 1) {\n      tagOffset = dirOffset + 2 + 12 * i\n      tagNumber = dataView.getUint16(tagOffset, littleEndian)\n      if (!shouldIncludeTag(includeTags, excludeTags, tagNumber)) continue\n      tagValue = getExifValue(\n        dataView,\n        tiffOffset,\n        tagOffset,\n        dataView.getUint16(tagOffset + 2, littleEndian), // tag type\n        dataView.getUint32(tagOffset + 4, littleEndian), // tag length\n        littleEndian\n      )\n      tags[tagNumber] = tagValue\n      if (tagOffsets) {\n        tagOffsets[tagNumber] = tagOffset\n      }\n    }\n    // Return the offset to the next directory:\n    return dataView.getUint32(dirEndOffset, littleEndian)\n  }\n\n  /**\n   * Parses tags in a given IFD (Image File Directory).\n   *\n   * @param {object} data Data object to store exif tags and offsets\n   * @param {number|string} tagCode IFD tag code\n   * @param {DataView} dataView Data view interface\n   * @param {number} tiffOffset TIFF offset\n   * @param {boolean} littleEndian Little endian encoding\n   * @param {object} includeTags Map of tags to include\n   * @param {object} excludeTags Map of tags to exclude\n   */\n  function parseExifIFD(\n    data,\n    tagCode,\n    dataView,\n    tiffOffset,\n    littleEndian,\n    includeTags,\n    excludeTags\n  ) {\n    var dirOffset = data.exif[tagCode]\n    if (dirOffset) {\n      data.exif[tagCode] = new ExifMap(tagCode)\n      if (data.exifOffsets) {\n        data.exifOffsets[tagCode] = new ExifMap(tagCode)\n      }\n      parseExifTags(\n        dataView,\n        tiffOffset,\n        tiffOffset + dirOffset,\n        littleEndian,\n        data.exif[tagCode],\n        data.exifOffsets && data.exifOffsets[tagCode],\n        includeTags && includeTags[tagCode],\n        excludeTags && excludeTags[tagCode]\n      )\n    }\n  }\n\n  loadImage.parseExifData = function (dataView, offset, length, data, options) {\n    if (options.disableExif) {\n      return\n    }\n    var includeTags = options.includeExifTags\n    var excludeTags = options.excludeExifTags || {\n      0x8769: {\n        // ExifIFDPointer\n        0x927c: true // MakerNote\n      }\n    }\n    var tiffOffset = offset + 10\n    var littleEndian\n    var dirOffset\n    var thumbnailIFD\n    // Check for the ASCII code for \"Exif\" (0x45786966):\n    if (dataView.getUint32(offset + 4) !== 0x45786966) {\n      // No Exif data, might be XMP data instead\n      return\n    }\n    if (tiffOffset + 8 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid segment size.')\n      return\n    }\n    // Check for the two null bytes:\n    if (dataView.getUint16(offset + 8) !== 0x0000) {\n      console.log('Invalid Exif data: Missing byte alignment offset.')\n      return\n    }\n    // Check the byte alignment:\n    switch (dataView.getUint16(tiffOffset)) {\n      case 0x4949:\n        littleEndian = true\n        break\n      case 0x4d4d:\n        littleEndian = false\n        break\n      default:\n        console.log('Invalid Exif data: Invalid byte alignment marker.')\n        return\n    }\n    // Check for the TIFF tag marker (0x002A):\n    if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002a) {\n      console.log('Invalid Exif data: Missing TIFF marker.')\n      return\n    }\n    // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:\n    dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian)\n    // Create the exif object to store the tags:\n    data.exif = new ExifMap()\n    if (!options.disableExifOffsets) {\n      data.exifOffsets = new ExifMap()\n      data.exifTiffOffset = tiffOffset\n      data.exifLittleEndian = littleEndian\n    }\n    // Parse the tags of the main image directory (IFD0) and retrieve the\n    // offset to the next directory (IFD1), usually the thumbnail directory:\n    dirOffset = parseExifTags(\n      dataView,\n      tiffOffset,\n      tiffOffset + dirOffset,\n      littleEndian,\n      data.exif,\n      data.exifOffsets,\n      includeTags,\n      excludeTags\n    )\n    if (dirOffset && shouldIncludeTag(includeTags, excludeTags, 'ifd1')) {\n      data.exif.ifd1 = dirOffset\n      if (data.exifOffsets) {\n        data.exifOffsets.ifd1 = tiffOffset + dirOffset\n      }\n    }\n    Object.keys(data.exif.ifds).forEach(function (tagCode) {\n      parseExifIFD(\n        data,\n        tagCode,\n        dataView,\n        tiffOffset,\n        littleEndian,\n        includeTags,\n        excludeTags\n      )\n    })\n    thumbnailIFD = data.exif.ifd1\n    // Check for JPEG Thumbnail offset and data length:\n    if (thumbnailIFD && thumbnailIFD[0x0201]) {\n      thumbnailIFD[0x0201] = getExifThumbnail(\n        dataView,\n        tiffOffset + thumbnailIFD[0x0201],\n        thumbnailIFD[0x0202] // Thumbnail data length\n      )\n    }\n  }\n\n  // Registers the Exif parser for the APP1 JPEG metadata segment:\n  loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseExifData)\n\n  loadImage.exifWriters = {\n    // Orientation writer:\n    0x0112: function (buffer, data, value) {\n      var orientationOffset = data.exifOffsets[0x0112]\n      if (!orientationOffset) return buffer\n      var view = new DataView(buffer, orientationOffset + 8, 2)\n      view.setUint16(0, value, data.exifLittleEndian)\n      return buffer\n    }\n  }\n\n  loadImage.writeExifData = function (buffer, data, id, value) {\n    loadImage.exifWriters[data.exif.map[id]](buffer, data, value)\n  }\n\n  loadImage.ExifMap = ExifMap\n\n  // Adds the following properties to the parseMetaData callback data:\n  // - exif: The parsed Exif tags\n  // - exifOffsets: The parsed Exif tag offsets\n  // - exifTiffOffset: TIFF header offset (used for offset pointers)\n  // - exifLittleEndian: little endian order if true, big endian if false\n\n  // Adds the following options to the parseMetaData method:\n  // - disableExif: Disables Exif parsing when true.\n  // - disableExifOffsets: Disables storing Exif tag offsets when true.\n  // - includeExifTags: A map of Exif tags to include for parsing.\n  // - excludeExifTags: A map of Exif tags to exclude from parsing.\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image.js":"/*\n * JavaScript Load Image\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, Promise */\n\n;(function ($) {\n  'use strict'\n\n  var urlAPI = $.URL || $.webkitURL\n\n  /**\n   * Creates an object URL for a given File object.\n   *\n   * @param {Blob} blob Blob object\n   * @returns {string|boolean} Returns object URL if API exists, else false.\n   */\n  function createObjectURL(blob) {\n    return urlAPI ? urlAPI.createObjectURL(blob) : false\n  }\n\n  /**\n   * Revokes a given object URL.\n   *\n   * @param {string} url Blob object URL\n   * @returns {undefined|boolean} Returns undefined if API exists, else false.\n   */\n  function revokeObjectURL(url) {\n    return urlAPI ? urlAPI.revokeObjectURL(url) : false\n  }\n\n  /**\n   * Helper function to revoke an object URL\n   *\n   * @param {string} url Blob Object URL\n   * @param {object} [options] Options object\n   */\n  function revokeHelper(url, options) {\n    if (url && url.slice(0, 5) === 'blob:' && !(options && options.noRevoke)) {\n      revokeObjectURL(url)\n    }\n  }\n\n  /**\n   * Loads a given File object via FileReader interface.\n   *\n   * @param {Blob} file Blob object\n   * @param {Function} onload Load event callback\n   * @param {Function} [onerror] Error/Abort event callback\n   * @param {string} [method=readAsDataURL] FileReader method\n   * @returns {FileReader|boolean} Returns FileReader if API exists, else false.\n   */\n  function readFile(file, onload, onerror, method) {\n    if (!$.FileReader) return false\n    var reader = new FileReader()\n    reader.onload = function () {\n      onload.call(reader, this.result)\n    }\n    if (onerror) {\n      reader.onabort = reader.onerror = function () {\n        onerror.call(reader, this.error)\n      }\n    }\n    var readerMethod = reader[method || 'readAsDataURL']\n    if (readerMethod) {\n      readerMethod.call(reader, file)\n      return reader\n    }\n  }\n\n  /**\n   * Cross-frame instanceof check.\n   *\n   * @param {string} type Instance type\n   * @param {object} obj Object instance\n   * @returns {boolean} Returns true if the object is of the given instance.\n   */\n  function isInstanceOf(type, obj) {\n    // Cross-frame instanceof check\n    return Object.prototype.toString.call(obj) === '[object ' + type + ']'\n  }\n\n  /**\n   * @typedef { HTMLImageElement|HTMLCanvasElement } Result\n   */\n\n  /**\n   * Loads an image for a given File object.\n   *\n   * @param {Blob|string} file Blob object or image URL\n   * @param {Function|object} [callback] Image load event callback or options\n   * @param {object} [options] Options object\n   * @returns {HTMLImageElement|FileReader|Promise<Result>} Object\n   */\n  function loadImage(file, callback, options) {\n    /**\n     * Promise executor\n     *\n     * @param {Function} resolve Resolution function\n     * @param {Function} reject Rejection function\n     * @returns {HTMLImageElement|FileReader} Object\n     */\n    function executor(resolve, reject) {\n      var img = document.createElement('img')\n      var url\n      /**\n       * Callback for the fetchBlob call.\n       *\n       * @param {HTMLImageElement|HTMLCanvasElement} img Error object\n       * @param {object} data Data object\n       * @returns {undefined} Undefined\n       */\n      function resolveWrapper(img, data) {\n        if (resolve === reject) {\n          // Not using Promises\n          if (resolve) resolve(img, data)\n          return\n        } else if (img instanceof Error) {\n          reject(img)\n          return\n        }\n        data = data || {} // eslint-disable-line no-param-reassign\n        data.image = img\n        resolve(data)\n      }\n      /**\n       * Callback for the fetchBlob call.\n       *\n       * @param {Blob} blob Blob object\n       * @param {Error} err Error object\n       */\n      function fetchBlobCallback(blob, err) {\n        if (err && $.console) console.log(err) // eslint-disable-line no-console\n        if (blob && isInstanceOf('Blob', blob)) {\n          file = blob // eslint-disable-line no-param-reassign\n          url = createObjectURL(file)\n        } else {\n          url = file\n          if (options && options.crossOrigin) {\n            img.crossOrigin = options.crossOrigin\n          }\n        }\n        img.src = url\n      }\n      img.onerror = function (event) {\n        revokeHelper(url, options)\n        if (reject) reject.call(img, event)\n      }\n      img.onload = function () {\n        revokeHelper(url, options)\n        var data = {\n          originalWidth: img.naturalWidth || img.width,\n          originalHeight: img.naturalHeight || img.height\n        }\n        try {\n          loadImage.transform(img, options, resolveWrapper, file, data)\n        } catch (error) {\n          if (reject) reject(error)\n        }\n      }\n      if (typeof file === 'string') {\n        if (loadImage.requiresMetaData(options)) {\n          loadImage.fetchBlob(file, fetchBlobCallback, options)\n        } else {\n          fetchBlobCallback()\n        }\n        return img\n      } else if (isInstanceOf('Blob', file) || isInstanceOf('File', file)) {\n        url = createObjectURL(file)\n        if (url) {\n          img.src = url\n          return img\n        }\n        return readFile(\n          file,\n          function (url) {\n            img.src = url\n          },\n          reject\n        )\n      }\n    }\n    if ($.Promise && typeof callback !== 'function') {\n      options = callback // eslint-disable-line no-param-reassign\n      return new Promise(executor)\n    }\n    return executor(callback, callback)\n  }\n\n  // Determines if metadata should be loaded automatically.\n  // Requires the load image meta extension to load metadata.\n  loadImage.requiresMetaData = function (options) {\n    return options && options.meta\n  }\n\n  // If the callback given to this function returns a blob, it is used as image\n  // source instead of the original url and overrides the file argument used in\n  // the onload and onerror event callbacks:\n  loadImage.fetchBlob = function (url, callback) {\n    callback()\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    callback(img, data)\n  }\n\n  loadImage.global = $\n  loadImage.readFile = readFile\n  loadImage.isInstanceOf = isInstanceOf\n  loadImage.createObjectURL = createObjectURL\n  loadImage.revokeObjectURL = revokeObjectURL\n\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return loadImage\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = loadImage\n  } else {\n    $.loadImage = loadImage\n  }\n})((typeof window !== 'undefined' && window) || this)\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif-map.js":"/*\n * JavaScript Load Image Exif Map\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Exif tags mapping based on\n * https://github.com/jseidelin/exif-js\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'), require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var ExifMapProto = loadImage.ExifMap.prototype\n\n  ExifMapProto.tags = {\n    // =================\n    // TIFF tags (IFD0):\n    // =================\n    0x0100: 'ImageWidth',\n    0x0101: 'ImageHeight',\n    0x0102: 'BitsPerSample',\n    0x0103: 'Compression',\n    0x0106: 'PhotometricInterpretation',\n    0x0112: 'Orientation',\n    0x0115: 'SamplesPerPixel',\n    0x011c: 'PlanarConfiguration',\n    0x0212: 'YCbCrSubSampling',\n    0x0213: 'YCbCrPositioning',\n    0x011a: 'XResolution',\n    0x011b: 'YResolution',\n    0x0128: 'ResolutionUnit',\n    0x0111: 'StripOffsets',\n    0x0116: 'RowsPerStrip',\n    0x0117: 'StripByteCounts',\n    0x0201: 'JPEGInterchangeFormat',\n    0x0202: 'JPEGInterchangeFormatLength',\n    0x012d: 'TransferFunction',\n    0x013e: 'WhitePoint',\n    0x013f: 'PrimaryChromaticities',\n    0x0211: 'YCbCrCoefficients',\n    0x0214: 'ReferenceBlackWhite',\n    0x0132: 'DateTime',\n    0x010e: 'ImageDescription',\n    0x010f: 'Make',\n    0x0110: 'Model',\n    0x0131: 'Software',\n    0x013b: 'Artist',\n    0x8298: 'Copyright',\n    0x8769: {\n      // ExifIFDPointer\n      0x9000: 'ExifVersion', // EXIF version\n      0xa000: 'FlashpixVersion', // Flashpix format version\n      0xa001: 'ColorSpace', // Color space information tag\n      0xa002: 'PixelXDimension', // Valid width of meaningful image\n      0xa003: 'PixelYDimension', // Valid height of meaningful image\n      0xa500: 'Gamma',\n      0x9101: 'ComponentsConfiguration', // Information about channels\n      0x9102: 'CompressedBitsPerPixel', // Compressed bits per pixel\n      0x927c: 'MakerNote', // Any desired information written by the manufacturer\n      0x9286: 'UserComment', // Comments by user\n      0xa004: 'RelatedSoundFile', // Name of related sound file\n      0x9003: 'DateTimeOriginal', // Date and time when the original image was generated\n      0x9004: 'DateTimeDigitized', // Date and time when the image was stored digitally\n      0x9010: 'OffsetTime', // Time zone when the image file was last changed\n      0x9011: 'OffsetTimeOriginal', // Time zone when the image was stored digitally\n      0x9012: 'OffsetTimeDigitized', // Time zone when the image was stored digitally\n      0x9290: 'SubSecTime', // Fractions of seconds for DateTime\n      0x9291: 'SubSecTimeOriginal', // Fractions of seconds for DateTimeOriginal\n      0x9292: 'SubSecTimeDigitized', // Fractions of seconds for DateTimeDigitized\n      0x829a: 'ExposureTime', // Exposure time (in seconds)\n      0x829d: 'FNumber',\n      0x8822: 'ExposureProgram', // Exposure program\n      0x8824: 'SpectralSensitivity', // Spectral sensitivity\n      0x8827: 'PhotographicSensitivity', // EXIF 2.3, ISOSpeedRatings in EXIF 2.2\n      0x8828: 'OECF', // Optoelectric conversion factor\n      0x8830: 'SensitivityType',\n      0x8831: 'StandardOutputSensitivity',\n      0x8832: 'RecommendedExposureIndex',\n      0x8833: 'ISOSpeed',\n      0x8834: 'ISOSpeedLatitudeyyy',\n      0x8835: 'ISOSpeedLatitudezzz',\n      0x9201: 'ShutterSpeedValue', // Shutter speed\n      0x9202: 'ApertureValue', // Lens aperture\n      0x9203: 'BrightnessValue', // Value of brightness\n      0x9204: 'ExposureBias', // Exposure bias\n      0x9205: 'MaxApertureValue', // Smallest F number of lens\n      0x9206: 'SubjectDistance', // Distance to subject in meters\n      0x9207: 'MeteringMode', // Metering mode\n      0x9208: 'LightSource', // Kind of light source\n      0x9209: 'Flash', // Flash status\n      0x9214: 'SubjectArea', // Location and area of main subject\n      0x920a: 'FocalLength', // Focal length of the lens in mm\n      0xa20b: 'FlashEnergy', // Strobe energy in BCPS\n      0xa20c: 'SpatialFrequencyResponse',\n      0xa20e: 'FocalPlaneXResolution', // Number of pixels in width direction per FPRUnit\n      0xa20f: 'FocalPlaneYResolution', // Number of pixels in height direction per FPRUnit\n      0xa210: 'FocalPlaneResolutionUnit', // Unit for measuring the focal plane resolution\n      0xa214: 'SubjectLocation', // Location of subject in image\n      0xa215: 'ExposureIndex', // Exposure index selected on camera\n      0xa217: 'SensingMethod', // Image sensor type\n      0xa300: 'FileSource', // Image source (3 == DSC)\n      0xa301: 'SceneType', // Scene type (1 == directly photographed)\n      0xa302: 'CFAPattern', // Color filter array geometric pattern\n      0xa401: 'CustomRendered', // Special processing\n      0xa402: 'ExposureMode', // Exposure mode\n      0xa403: 'WhiteBalance', // 1 = auto white balance, 2 = manual\n      0xa404: 'DigitalZoomRatio', // Digital zoom ratio\n      0xa405: 'FocalLengthIn35mmFilm',\n      0xa406: 'SceneCaptureType', // Type of scene\n      0xa407: 'GainControl', // Degree of overall image gain adjustment\n      0xa408: 'Contrast', // Direction of contrast processing applied by camera\n      0xa409: 'Saturation', // Direction of saturation processing applied by camera\n      0xa40a: 'Sharpness', // Direction of sharpness processing applied by camera\n      0xa40b: 'DeviceSettingDescription',\n      0xa40c: 'SubjectDistanceRange', // Distance to subject\n      0xa420: 'ImageUniqueID', // Identifier assigned uniquely to each image\n      0xa430: 'CameraOwnerName',\n      0xa431: 'BodySerialNumber',\n      0xa432: 'LensSpecification',\n      0xa433: 'LensMake',\n      0xa434: 'LensModel',\n      0xa435: 'LensSerialNumber'\n    },\n    0x8825: {\n      // GPSInfoIFDPointer\n      0x0000: 'GPSVersionID',\n      0x0001: 'GPSLatitudeRef',\n      0x0002: 'GPSLatitude',\n      0x0003: 'GPSLongitudeRef',\n      0x0004: 'GPSLongitude',\n      0x0005: 'GPSAltitudeRef',\n      0x0006: 'GPSAltitude',\n      0x0007: 'GPSTimeStamp',\n      0x0008: 'GPSSatellites',\n      0x0009: 'GPSStatus',\n      0x000a: 'GPSMeasureMode',\n      0x000b: 'GPSDOP',\n      0x000c: 'GPSSpeedRef',\n      0x000d: 'GPSSpeed',\n      0x000e: 'GPSTrackRef',\n      0x000f: 'GPSTrack',\n      0x0010: 'GPSImgDirectionRef',\n      0x0011: 'GPSImgDirection',\n      0x0012: 'GPSMapDatum',\n      0x0013: 'GPSDestLatitudeRef',\n      0x0014: 'GPSDestLatitude',\n      0x0015: 'GPSDestLongitudeRef',\n      0x0016: 'GPSDestLongitude',\n      0x0017: 'GPSDestBearingRef',\n      0x0018: 'GPSDestBearing',\n      0x0019: 'GPSDestDistanceRef',\n      0x001a: 'GPSDestDistance',\n      0x001b: 'GPSProcessingMethod',\n      0x001c: 'GPSAreaInformation',\n      0x001d: 'GPSDateStamp',\n      0x001e: 'GPSDifferential',\n      0x001f: 'GPSHPositioningError'\n    },\n    0xa005: {\n      // InteroperabilityIFDPointer\n      0x0001: 'InteroperabilityIndex'\n    }\n  }\n\n  // IFD1 directory can contain any IFD0 tags:\n  ExifMapProto.tags.ifd1 = ExifMapProto.tags\n\n  ExifMapProto.stringValues = {\n    ExposureProgram: {\n      0: 'Undefined',\n      1: 'Manual',\n      2: 'Normal program',\n      3: 'Aperture priority',\n      4: 'Shutter priority',\n      5: 'Creative program',\n      6: 'Action program',\n      7: 'Portrait mode',\n      8: 'Landscape mode'\n    },\n    MeteringMode: {\n      0: 'Unknown',\n      1: 'Average',\n      2: 'CenterWeightedAverage',\n      3: 'Spot',\n      4: 'MultiSpot',\n      5: 'Pattern',\n      6: 'Partial',\n      255: 'Other'\n    },\n    LightSource: {\n      0: 'Unknown',\n      1: 'Daylight',\n      2: 'Fluorescent',\n      3: 'Tungsten (incandescent light)',\n      4: 'Flash',\n      9: 'Fine weather',\n      10: 'Cloudy weather',\n      11: 'Shade',\n      12: 'Daylight fluorescent (D 5700 - 7100K)',\n      13: 'Day white fluorescent (N 4600 - 5400K)',\n      14: 'Cool white fluorescent (W 3900 - 4500K)',\n      15: 'White fluorescent (WW 3200 - 3700K)',\n      17: 'Standard light A',\n      18: 'Standard light B',\n      19: 'Standard light C',\n      20: 'D55',\n      21: 'D65',\n      22: 'D75',\n      23: 'D50',\n      24: 'ISO studio tungsten',\n      255: 'Other'\n    },\n    Flash: {\n      0x0000: 'Flash did not fire',\n      0x0001: 'Flash fired',\n      0x0005: 'Strobe return light not detected',\n      0x0007: 'Strobe return light detected',\n      0x0009: 'Flash fired, compulsory flash mode',\n      0x000d: 'Flash fired, compulsory flash mode, return light not detected',\n      0x000f: 'Flash fired, compulsory flash mode, return light detected',\n      0x0010: 'Flash did not fire, compulsory flash mode',\n      0x0018: 'Flash did not fire, auto mode',\n      0x0019: 'Flash fired, auto mode',\n      0x001d: 'Flash fired, auto mode, return light not detected',\n      0x001f: 'Flash fired, auto mode, return light detected',\n      0x0020: 'No flash function',\n      0x0041: 'Flash fired, red-eye reduction mode',\n      0x0045: 'Flash fired, red-eye reduction mode, return light not detected',\n      0x0047: 'Flash fired, red-eye reduction mode, return light detected',\n      0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',\n      0x004d: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',\n      0x004f: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',\n      0x0059: 'Flash fired, auto mode, red-eye reduction mode',\n      0x005d: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',\n      0x005f: 'Flash fired, auto mode, return light detected, red-eye reduction mode'\n    },\n    SensingMethod: {\n      1: 'Undefined',\n      2: 'One-chip color area sensor',\n      3: 'Two-chip color area sensor',\n      4: 'Three-chip color area sensor',\n      5: 'Color sequential area sensor',\n      7: 'Trilinear sensor',\n      8: 'Color sequential linear sensor'\n    },\n    SceneCaptureType: {\n      0: 'Standard',\n      1: 'Landscape',\n      2: 'Portrait',\n      3: 'Night scene'\n    },\n    SceneType: {\n      1: 'Directly photographed'\n    },\n    CustomRendered: {\n      0: 'Normal process',\n      1: 'Custom process'\n    },\n    WhiteBalance: {\n      0: 'Auto white balance',\n      1: 'Manual white balance'\n    },\n    GainControl: {\n      0: 'None',\n      1: 'Low gain up',\n      2: 'High gain up',\n      3: 'Low gain down',\n      4: 'High gain down'\n    },\n    Contrast: {\n      0: 'Normal',\n      1: 'Soft',\n      2: 'Hard'\n    },\n    Saturation: {\n      0: 'Normal',\n      1: 'Low saturation',\n      2: 'High saturation'\n    },\n    Sharpness: {\n      0: 'Normal',\n      1: 'Soft',\n      2: 'Hard'\n    },\n    SubjectDistanceRange: {\n      0: 'Unknown',\n      1: 'Macro',\n      2: 'Close view',\n      3: 'Distant view'\n    },\n    FileSource: {\n      3: 'DSC'\n    },\n    ComponentsConfiguration: {\n      0: '',\n      1: 'Y',\n      2: 'Cb',\n      3: 'Cr',\n      4: 'R',\n      5: 'G',\n      6: 'B'\n    },\n    Orientation: {\n      1: 'Original',\n      2: 'Horizontal flip',\n      3: 'Rotate 180\u00b0 CCW',\n      4: 'Vertical flip',\n      5: 'Vertical flip + Rotate 90\u00b0 CW',\n      6: 'Rotate 90\u00b0 CW',\n      7: 'Horizontal flip + Rotate 90\u00b0 CW',\n      8: 'Rotate 90\u00b0 CCW'\n    }\n  }\n\n  ExifMapProto.getText = function (name) {\n    var value = this.get(name)\n    switch (name) {\n      case 'LightSource':\n      case 'Flash':\n      case 'MeteringMode':\n      case 'ExposureProgram':\n      case 'SensingMethod':\n      case 'SceneCaptureType':\n      case 'SceneType':\n      case 'CustomRendered':\n      case 'WhiteBalance':\n      case 'GainControl':\n      case 'Contrast':\n      case 'Saturation':\n      case 'Sharpness':\n      case 'SubjectDistanceRange':\n      case 'FileSource':\n      case 'Orientation':\n        return this.stringValues[name][value]\n      case 'ExifVersion':\n      case 'FlashpixVersion':\n        if (!value) return\n        return String.fromCharCode(value[0], value[1], value[2], value[3])\n      case 'ComponentsConfiguration':\n        if (!value) return\n        return (\n          this.stringValues[name][value[0]] +\n          this.stringValues[name][value[1]] +\n          this.stringValues[name][value[2]] +\n          this.stringValues[name][value[3]]\n        )\n      case 'GPSVersionID':\n        if (!value) return\n        return value[0] + '.' + value[1] + '.' + value[2] + '.' + value[3]\n    }\n    return String(value)\n  }\n\n  ExifMapProto.getAll = function () {\n    var map = {}\n    var prop\n    var obj\n    var name\n    for (prop in this) {\n      if (Object.prototype.hasOwnProperty.call(this, prop)) {\n        obj = this[prop]\n        if (obj && obj.getAll) {\n          map[this.ifds[prop].name] = obj.getAll()\n        } else {\n          name = this.tags[prop]\n          if (name) map[name] = this.getText(name)\n        }\n      }\n    }\n    return map\n  }\n\n  ExifMapProto.getName = function (tagCode) {\n    var name = this.tags[tagCode]\n    if (typeof name === 'object') return this.ifds[tagCode].name\n    return name\n  }\n\n  // Extend the map of tag names to tag codes:\n  ;(function () {\n    var tags = ExifMapProto.tags\n    var prop\n    var ifd\n    var subTags\n    // Map the tag names to tags:\n    for (prop in tags) {\n      if (Object.prototype.hasOwnProperty.call(tags, prop)) {\n        ifd = ExifMapProto.ifds[prop]\n        if (ifd) {\n          subTags = tags[prop]\n          for (prop in subTags) {\n            if (Object.prototype.hasOwnProperty.call(subTags, prop)) {\n              ifd.map[subTags[prop]] = Number(prop)\n            }\n          }\n        } else {\n          ExifMapProto.map[tags[prop]] = Number(prop)\n        }\n      }\n    }\n  })()\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc-map.js":"/*\n * JavaScript Load Image IPTC Map\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * Copyright 2018, Dave Bevan\n *\n * IPTC tags mapping based on\n * https://iptc.org/standards/photo-metadata\n * https://exiftool.org/TagNames/IPTC.html\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'), require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var IptcMapProto = loadImage.IptcMap.prototype\n\n  IptcMapProto.tags = {\n    0: 'ApplicationRecordVersion',\n    3: 'ObjectTypeReference',\n    4: 'ObjectAttributeReference',\n    5: 'ObjectName',\n    7: 'EditStatus',\n    8: 'EditorialUpdate',\n    10: 'Urgency',\n    12: 'SubjectReference',\n    15: 'Category',\n    20: 'SupplementalCategories',\n    22: 'FixtureIdentifier',\n    25: 'Keywords',\n    26: 'ContentLocationCode',\n    27: 'ContentLocationName',\n    30: 'ReleaseDate',\n    35: 'ReleaseTime',\n    37: 'ExpirationDate',\n    38: 'ExpirationTime',\n    40: 'SpecialInstructions',\n    42: 'ActionAdvised',\n    45: 'ReferenceService',\n    47: 'ReferenceDate',\n    50: 'ReferenceNumber',\n    55: 'DateCreated',\n    60: 'TimeCreated',\n    62: 'DigitalCreationDate',\n    63: 'DigitalCreationTime',\n    65: 'OriginatingProgram',\n    70: 'ProgramVersion',\n    75: 'ObjectCycle',\n    80: 'Byline',\n    85: 'BylineTitle',\n    90: 'City',\n    92: 'Sublocation',\n    95: 'State',\n    100: 'CountryCode',\n    101: 'Country',\n    103: 'OriginalTransmissionReference',\n    105: 'Headline',\n    110: 'Credit',\n    115: 'Source',\n    116: 'CopyrightNotice',\n    118: 'Contact',\n    120: 'Caption',\n    121: 'LocalCaption',\n    122: 'Writer',\n    125: 'RasterizedCaption',\n    130: 'ImageType',\n    131: 'ImageOrientation',\n    135: 'LanguageIdentifier',\n    150: 'AudioType',\n    151: 'AudioSamplingRate',\n    152: 'AudioSamplingResolution',\n    153: 'AudioDuration',\n    154: 'AudioOutcue',\n    184: 'JobID',\n    185: 'MasterDocumentID',\n    186: 'ShortDocumentID',\n    187: 'UniqueDocumentID',\n    188: 'OwnerID',\n    200: 'ObjectPreviewFileFormat',\n    201: 'ObjectPreviewFileVersion',\n    202: 'ObjectPreviewData',\n    221: 'Prefs',\n    225: 'ClassifyState',\n    228: 'SimilarityIndex',\n    230: 'DocumentNotes',\n    231: 'DocumentHistory',\n    232: 'ExifCameraInfo',\n    255: 'CatalogSets'\n  }\n\n  IptcMapProto.stringValues = {\n    10: {\n      0: '0 (reserved)',\n      1: '1 (most urgent)',\n      2: '2',\n      3: '3',\n      4: '4',\n      5: '5 (normal urgency)',\n      6: '6',\n      7: '7',\n      8: '8 (least urgent)',\n      9: '9 (user-defined priority)'\n    },\n    75: {\n      a: 'Morning',\n      b: 'Both Morning and Evening',\n      p: 'Evening'\n    },\n    131: {\n      L: 'Landscape',\n      P: 'Portrait',\n      S: 'Square'\n    }\n  }\n\n  IptcMapProto.getText = function (id) {\n    var value = this.get(id)\n    var tagCode = this.map[id]\n    var stringValue = this.stringValues[tagCode]\n    if (stringValue) return stringValue[value]\n    return String(value)\n  }\n\n  IptcMapProto.getAll = function () {\n    var map = {}\n    var prop\n    var name\n    for (prop in this) {\n      if (Object.prototype.hasOwnProperty.call(this, prop)) {\n        name = this.tags[prop]\n        if (name) map[name] = this.getText(name)\n      }\n    }\n    return map\n  }\n\n  IptcMapProto.getName = function (tagCode) {\n    return this.tags[tagCode]\n  }\n\n  // Extend the map of tag names to tag codes:\n  ;(function () {\n    var tags = IptcMapProto.tags\n    var map = IptcMapProto.map || {}\n    var prop\n    // Map the tag names to tags:\n    for (prop in tags) {\n      if (Object.prototype.hasOwnProperty.call(tags, prop)) {\n        map[tags[prop]] = Number(prop)\n      }\n    }\n  })()\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc.js":"/*\n * JavaScript Load Image IPTC Parser\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * Copyright 2018, Dave Bevan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require, DataView */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'), require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  /**\n   * IPTC tag map\n   *\n   * @name IptcMap\n   * @class\n   */\n  function IptcMap() {}\n\n  IptcMap.prototype.map = {\n    ObjectName: 5\n  }\n\n  IptcMap.prototype.types = {\n    0: 'Uint16', // ApplicationRecordVersion\n    200: 'Uint16', // ObjectPreviewFileFormat\n    201: 'Uint16', // ObjectPreviewFileVersion\n    202: 'binary' // ObjectPreviewData\n  }\n\n  /**\n   * Retrieves IPTC tag value\n   *\n   * @param {number|string} id IPTC tag code or name\n   * @returns {object} IPTC tag value\n   */\n  IptcMap.prototype.get = function (id) {\n    return this[id] || this[this.map[id]]\n  }\n\n  /**\n   * Retrieves string for the given DataView and range\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} offset Offset start\n   * @param {number} length Offset length\n   * @returns {string} String value\n   */\n  function getStringValue(dataView, offset, length) {\n    var outstr = ''\n    var end = offset + length\n    for (var n = offset; n < end; n += 1) {\n      outstr += String.fromCharCode(dataView.getUint8(n))\n    }\n    return outstr\n  }\n\n  /**\n   * Retrieves tag value for the given DataView and range\n   *\n   * @param {number} tagCode tag code\n   * @param {IptcMap} map IPTC tag map\n   * @param {DataView} dataView Data view interface\n   * @param {number} offset Range start\n   * @param {number} length Range length\n   * @returns {object} Tag value\n   */\n  function getTagValue(tagCode, map, dataView, offset, length) {\n    if (map.types[tagCode] === 'binary') {\n      return new Blob([dataView.buffer.slice(offset, offset + length)])\n    }\n    if (map.types[tagCode] === 'Uint16') {\n      return dataView.getUint16(offset)\n    }\n    return getStringValue(dataView, offset, length)\n  }\n\n  /**\n   * Combines IPTC value with existing ones.\n   *\n   * @param {object} value Existing IPTC field value\n   * @param {object} newValue New IPTC field value\n   * @returns {object} Resulting IPTC field value\n   */\n  function combineTagValues(value, newValue) {\n    if (value === undefined) return newValue\n    if (value instanceof Array) {\n      value.push(newValue)\n      return value\n    }\n    return [value, newValue]\n  }\n\n  /**\n   * Parses IPTC tags.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} segmentOffset Segment offset\n   * @param {number} segmentLength Segment length\n   * @param {object} data Data export object\n   * @param {object} includeTags Map of tags to include\n   * @param {object} excludeTags Map of tags to exclude\n   */\n  function parseIptcTags(\n    dataView,\n    segmentOffset,\n    segmentLength,\n    data,\n    includeTags,\n    excludeTags\n  ) {\n    var value, tagSize, tagCode\n    var segmentEnd = segmentOffset + segmentLength\n    var offset = segmentOffset\n    while (offset < segmentEnd) {\n      if (\n        dataView.getUint8(offset) === 0x1c && // tag marker\n        dataView.getUint8(offset + 1) === 0x02 // record number, only handles v2\n      ) {\n        tagCode = dataView.getUint8(offset + 2)\n        if (\n          (!includeTags || includeTags[tagCode]) &&\n          (!excludeTags || !excludeTags[tagCode])\n        ) {\n          tagSize = dataView.getInt16(offset + 3)\n          value = getTagValue(tagCode, data.iptc, dataView, offset + 5, tagSize)\n          data.iptc[tagCode] = combineTagValues(data.iptc[tagCode], value)\n          if (data.iptcOffsets) {\n            data.iptcOffsets[tagCode] = offset\n          }\n        }\n      }\n      offset += 1\n    }\n  }\n\n  /**\n   * Tests if field segment starts at offset.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} offset Segment offset\n   * @returns {boolean} True if '8BIM<EOT><EOT>' exists at offset\n   */\n  function isSegmentStart(dataView, offset) {\n    return (\n      dataView.getUint32(offset) === 0x3842494d && // Photoshop segment start\n      dataView.getUint16(offset + 4) === 0x0404 // IPTC segment start\n    )\n  }\n\n  /**\n   * Returns header length.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} offset Segment offset\n   * @returns {number} Header length\n   */\n  function getHeaderLength(dataView, offset) {\n    var length = dataView.getUint8(offset + 7)\n    if (length % 2 !== 0) length += 1\n    // Check for pre photoshop 6 format\n    if (length === 0) {\n      // Always 4\n      length = 4\n    }\n    return length\n  }\n\n  loadImage.parseIptcData = function (dataView, offset, length, data, options) {\n    if (options.disableIptc) {\n      return\n    }\n    var markerLength = offset + length\n    while (offset + 8 < markerLength) {\n      if (isSegmentStart(dataView, offset)) {\n        var headerLength = getHeaderLength(dataView, offset)\n        var segmentOffset = offset + 8 + headerLength\n        if (segmentOffset > markerLength) {\n          // eslint-disable-next-line no-console\n          console.log('Invalid IPTC data: Invalid segment offset.')\n          break\n        }\n        var segmentLength = dataView.getUint16(offset + 6 + headerLength)\n        if (offset + segmentLength > markerLength) {\n          // eslint-disable-next-line no-console\n          console.log('Invalid IPTC data: Invalid segment size.')\n          break\n        }\n        // Create the iptc object to store the tags:\n        data.iptc = new IptcMap()\n        if (!options.disableIptcOffsets) {\n          data.iptcOffsets = new IptcMap()\n        }\n        parseIptcTags(\n          dataView,\n          segmentOffset,\n          segmentLength,\n          data,\n          options.includeIptcTags,\n          options.excludeIptcTags || { 202: true } // ObjectPreviewData\n        )\n        return\n      }\n      // eslint-disable-next-line no-param-reassign\n      offset += 1\n    }\n  }\n\n  // Registers this IPTC parser for the APP13 JPEG metadata segment:\n  loadImage.metaDataParsers.jpeg[0xffed].push(loadImage.parseIptcData)\n\n  loadImage.IptcMap = IptcMap\n\n  // Adds the following properties to the parseMetaData callback data:\n  // - iptc: The iptc tags, parsed by the parseIptcData method\n\n  // Adds the following options to the parseMetaData method:\n  // - disableIptc: Disables IPTC parsing when true.\n  // - disableIptcOffsets: Disables storing IPTC tag offsets when true.\n  // - includeIptcTags: A map of IPTC tags to include for parsing.\n  // - excludeIptcTags: A map of IPTC tags to exclude from parsing.\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-orientation.js":"/*\n * JavaScript Load Image Orientation\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/*\nExif orientation values to correctly display the letter F:\n\n    1             2\n  \u2588\u2588\u2588\u2588\u2588\u2588        \u2588\u2588\u2588\u2588\u2588\u2588\n  \u2588\u2588                \u2588\u2588\n  \u2588\u2588\u2588\u2588            \u2588\u2588\u2588\u2588\n  \u2588\u2588                \u2588\u2588\n  \u2588\u2588                \u2588\u2588\n\n    3             4\n      \u2588\u2588        \u2588\u2588\n      \u2588\u2588        \u2588\u2588\n    \u2588\u2588\u2588\u2588        \u2588\u2588\u2588\u2588\n      \u2588\u2588        \u2588\u2588\n  \u2588\u2588\u2588\u2588\u2588\u2588        \u2588\u2588\u2588\u2588\u2588\u2588\n\n    5             6\n\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588    \u2588\u2588\n\u2588\u2588  \u2588\u2588        \u2588\u2588  \u2588\u2588\n\u2588\u2588            \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\n\n    7             8\n        \u2588\u2588    \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\n    \u2588\u2588  \u2588\u2588        \u2588\u2588  \u2588\u2588\n\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588            \u2588\u2588\n\n*/\n\n/* global define, module, require */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-scale', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-scale'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta')\n    )\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var originalTransform = loadImage.transform\n  var originalRequiresCanvas = loadImage.requiresCanvas\n  var originalRequiresMetaData = loadImage.requiresMetaData\n  var originalTransformCoordinates = loadImage.transformCoordinates\n  var originalGetTransformedOptions = loadImage.getTransformedOptions\n\n  ;(function ($) {\n    // Guard for non-browser environments (e.g. server-side rendering):\n    if (!$.global.document) return\n    // black+white 3x2 JPEG, with the following meta information set:\n    // - EXIF Orientation: 6 (Rotated 90\u00b0 CCW)\n    // Image data layout (B=black, F=white):\n    // BFF\n    // BBB\n    var testImageURL =\n      'data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' +\n      'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' +\n      'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' +\n      'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAIAAwMBEQACEQEDEQH/x' +\n      'ABRAAEAAAAAAAAAAAAAAAAAAAAKEAEBAQADAQEAAAAAAAAAAAAGBQQDCAkCBwEBAAAAAAA' +\n      'AAAAAAAAAAAAAABEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AG8T9NfSMEVMhQ' +\n      'voP3fFiRZ+MTHDifa/95OFSZU5OzRzxkyejv8ciEfhSceSXGjS8eSdLnZc2HDm4M3BxcXw' +\n      'H/9k='\n    var img = document.createElement('img')\n    img.onload = function () {\n      // Check if the browser supports automatic image orientation:\n      $.orientation = img.width === 2 && img.height === 3\n      if ($.orientation) {\n        var canvas = $.createCanvas(1, 1, true)\n        var ctx = canvas.getContext('2d')\n        ctx.drawImage(img, 1, 1, 1, 1, 0, 0, 1, 1)\n        // Check if the source image coordinates (sX, sY, sWidth, sHeight) are\n        // correctly applied to the auto-orientated image, which should result\n        // in a white opaque pixel (e.g. in Safari).\n        // Browsers that show a transparent pixel (e.g. Chromium) fail to crop\n        // auto-oriented images correctly and require a workaround, e.g.\n        // drawing the complete source image to an intermediate canvas first.\n        // See https://bugs.chromium.org/p/chromium/issues/detail?id=1074354\n        $.orientationCropBug =\n          ctx.getImageData(0, 0, 1, 1).data.toString() !== '255,255,255,255'\n      }\n    }\n    img.src = testImageURL\n  })(loadImage)\n\n  /**\n   * Determines if the orientation requires a canvas element.\n   *\n   * @param {object} [options] Options object\n   * @param {boolean} [withMetaData] Is metadata required for orientation\n   * @returns {boolean} Returns true if orientation requires canvas/meta\n   */\n  function requiresCanvasOrientation(options, withMetaData) {\n    var orientation = options && options.orientation\n    return (\n      // Exif orientation for browsers without automatic image orientation:\n      (orientation === true && !loadImage.orientation) ||\n      // Orientation reset for browsers with automatic image orientation:\n      (orientation === 1 && loadImage.orientation) ||\n      // Orientation to defined value, requires meta for orientation reset only:\n      ((!withMetaData || loadImage.orientation) &&\n        orientation > 1 &&\n        orientation < 9)\n    )\n  }\n\n  /**\n   * Determines if the image requires an orientation change.\n   *\n   * @param {number} [orientation] Defined orientation value\n   * @param {number} [autoOrientation] Auto-orientation based on Exif data\n   * @returns {boolean} Returns true if an orientation change is required\n   */\n  function requiresOrientationChange(orientation, autoOrientation) {\n    return (\n      orientation !== autoOrientation &&\n      ((orientation === 1 && autoOrientation > 1 && autoOrientation < 9) ||\n        (orientation > 1 && orientation < 9))\n    )\n  }\n\n  /**\n   * Determines orientation combinations that require a rotation by 180\u00b0.\n   *\n   * The following is a list of combinations that return true:\n   *\n   * 2 (flip) => 5 (rot90,flip), 7 (rot90,flip), 6 (rot90), 8 (rot90)\n   * 4 (flip) => 5 (rot90,flip), 7 (rot90,flip), 6 (rot90), 8 (rot90)\n   *\n   * 5 (rot90,flip) => 2 (flip), 4 (flip), 6 (rot90), 8 (rot90)\n   * 7 (rot90,flip) => 2 (flip), 4 (flip), 6 (rot90), 8 (rot90)\n   *\n   * 6 (rot90) => 2 (flip), 4 (flip), 5 (rot90,flip), 7 (rot90,flip)\n   * 8 (rot90) => 2 (flip), 4 (flip), 5 (rot90,flip), 7 (rot90,flip)\n   *\n   * @param {number} [orientation] Defined orientation value\n   * @param {number} [autoOrientation] Auto-orientation based on Exif data\n   * @returns {boolean} Returns true if rotation by 180\u00b0 is required\n   */\n  function requiresRot180(orientation, autoOrientation) {\n    if (autoOrientation > 1 && autoOrientation < 9) {\n      switch (orientation) {\n        case 2:\n        case 4:\n          return autoOrientation > 4\n        case 5:\n        case 7:\n          return autoOrientation % 2 === 0\n        case 6:\n        case 8:\n          return (\n            autoOrientation === 2 ||\n            autoOrientation === 4 ||\n            autoOrientation === 5 ||\n            autoOrientation === 7\n          )\n      }\n    }\n    return false\n  }\n\n  // Determines if the target image should be a canvas element:\n  loadImage.requiresCanvas = function (options) {\n    return (\n      requiresCanvasOrientation(options) ||\n      originalRequiresCanvas.call(loadImage, options)\n    )\n  }\n\n  // Determines if metadata should be loaded automatically:\n  loadImage.requiresMetaData = function (options) {\n    return (\n      requiresCanvasOrientation(options, true) ||\n      originalRequiresMetaData.call(loadImage, options)\n    )\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    originalTransform.call(\n      loadImage,\n      img,\n      options,\n      function (img, data) {\n        if (data) {\n          var autoOrientation =\n            loadImage.orientation && data.exif && data.exif.get('Orientation')\n          if (autoOrientation > 4 && autoOrientation < 9) {\n            // Automatic image orientation switched image dimensions\n            var originalWidth = data.originalWidth\n            var originalHeight = data.originalHeight\n            data.originalWidth = originalHeight\n            data.originalHeight = originalWidth\n          }\n        }\n        callback(img, data)\n      },\n      file,\n      data\n    )\n  }\n\n  // Transforms coordinate and dimension options\n  // based on the given orientation option:\n  loadImage.getTransformedOptions = function (img, opts, data) {\n    var options = originalGetTransformedOptions.call(loadImage, img, opts)\n    var exifOrientation = data.exif && data.exif.get('Orientation')\n    var orientation = options.orientation\n    var autoOrientation = loadImage.orientation && exifOrientation\n    if (orientation === true) orientation = exifOrientation\n    if (!requiresOrientationChange(orientation, autoOrientation)) {\n      return options\n    }\n    var top = options.top\n    var right = options.right\n    var bottom = options.bottom\n    var left = options.left\n    var newOptions = {}\n    for (var i in options) {\n      if (Object.prototype.hasOwnProperty.call(options, i)) {\n        newOptions[i] = options[i]\n      }\n    }\n    newOptions.orientation = orientation\n    if (\n      (orientation > 4 && !(autoOrientation > 4)) ||\n      (orientation < 5 && autoOrientation > 4)\n    ) {\n      // Image dimensions and target dimensions are switched\n      newOptions.maxWidth = options.maxHeight\n      newOptions.maxHeight = options.maxWidth\n      newOptions.minWidth = options.minHeight\n      newOptions.minHeight = options.minWidth\n      newOptions.sourceWidth = options.sourceHeight\n      newOptions.sourceHeight = options.sourceWidth\n    }\n    if (autoOrientation > 1) {\n      // Browsers which correctly apply source image coordinates to\n      // auto-oriented images\n      switch (autoOrientation) {\n        case 2:\n          // Horizontal flip\n          right = options.left\n          left = options.right\n          break\n        case 3:\n          // 180\u00b0 Rotate CCW\n          top = options.bottom\n          right = options.left\n          bottom = options.top\n          left = options.right\n          break\n        case 4:\n          // Vertical flip\n          top = options.bottom\n          bottom = options.top\n          break\n        case 5:\n          // Horizontal flip + 90\u00b0 Rotate CCW\n          top = options.left\n          right = options.bottom\n          bottom = options.right\n          left = options.top\n          break\n        case 6:\n          // 90\u00b0 Rotate CCW\n          top = options.left\n          right = options.top\n          bottom = options.right\n          left = options.bottom\n          break\n        case 7:\n          // Vertical flip + 90\u00b0 Rotate CCW\n          top = options.right\n          right = options.top\n          bottom = options.left\n          left = options.bottom\n          break\n        case 8:\n          // 90\u00b0 Rotate CW\n          top = options.right\n          right = options.bottom\n          bottom = options.left\n          left = options.top\n          break\n      }\n      // Some orientation combinations require additional rotation by 180\u00b0:\n      if (requiresRot180(orientation, autoOrientation)) {\n        var tmpTop = top\n        var tmpRight = right\n        top = bottom\n        right = left\n        bottom = tmpTop\n        left = tmpRight\n      }\n    }\n    newOptions.top = top\n    newOptions.right = right\n    newOptions.bottom = bottom\n    newOptions.left = left\n    // Account for defined browser orientation:\n    switch (orientation) {\n      case 2:\n        // Horizontal flip\n        newOptions.right = left\n        newOptions.left = right\n        break\n      case 3:\n        // 180\u00b0 Rotate CCW\n        newOptions.top = bottom\n        newOptions.right = left\n        newOptions.bottom = top\n        newOptions.left = right\n        break\n      case 4:\n        // Vertical flip\n        newOptions.top = bottom\n        newOptions.bottom = top\n        break\n      case 5:\n        // Vertical flip + 90\u00b0 Rotate CW\n        newOptions.top = left\n        newOptions.right = bottom\n        newOptions.bottom = right\n        newOptions.left = top\n        break\n      case 6:\n        // 90\u00b0 Rotate CW\n        newOptions.top = right\n        newOptions.right = bottom\n        newOptions.bottom = left\n        newOptions.left = top\n        break\n      case 7:\n        // Horizontal flip + 90\u00b0 Rotate CW\n        newOptions.top = right\n        newOptions.right = top\n        newOptions.bottom = left\n        newOptions.left = bottom\n        break\n      case 8:\n        // 90\u00b0 Rotate CCW\n        newOptions.top = left\n        newOptions.right = top\n        newOptions.bottom = right\n        newOptions.left = bottom\n        break\n    }\n    return newOptions\n  }\n\n  // Transform image orientation based on the given EXIF orientation option:\n  loadImage.transformCoordinates = function (canvas, options, data) {\n    originalTransformCoordinates.call(loadImage, canvas, options, data)\n    var orientation = options.orientation\n    var autoOrientation =\n      loadImage.orientation && data.exif && data.exif.get('Orientation')\n    if (!requiresOrientationChange(orientation, autoOrientation)) {\n      return\n    }\n    var ctx = canvas.getContext('2d')\n    var width = canvas.width\n    var height = canvas.height\n    var sourceWidth = width\n    var sourceHeight = height\n    if (\n      (orientation > 4 && !(autoOrientation > 4)) ||\n      (orientation < 5 && autoOrientation > 4)\n    ) {\n      // Image dimensions and target dimensions are switched\n      canvas.width = height\n      canvas.height = width\n    }\n    if (orientation > 4) {\n      // Destination and source dimensions are switched\n      sourceWidth = height\n      sourceHeight = width\n    }\n    // Reset automatic browser orientation:\n    switch (autoOrientation) {\n      case 2:\n        // Horizontal flip\n        ctx.translate(sourceWidth, 0)\n        ctx.scale(-1, 1)\n        break\n      case 3:\n        // 180\u00b0 Rotate CCW\n        ctx.translate(sourceWidth, sourceHeight)\n        ctx.rotate(Math.PI)\n        break\n      case 4:\n        // Vertical flip\n        ctx.translate(0, sourceHeight)\n        ctx.scale(1, -1)\n        break\n      case 5:\n        // Horizontal flip + 90\u00b0 Rotate CCW\n        ctx.rotate(-0.5 * Math.PI)\n        ctx.scale(-1, 1)\n        break\n      case 6:\n        // 90\u00b0 Rotate CCW\n        ctx.rotate(-0.5 * Math.PI)\n        ctx.translate(-sourceWidth, 0)\n        break\n      case 7:\n        // Vertical flip + 90\u00b0 Rotate CCW\n        ctx.rotate(-0.5 * Math.PI)\n        ctx.translate(-sourceWidth, sourceHeight)\n        ctx.scale(1, -1)\n        break\n      case 8:\n        // 90\u00b0 Rotate CW\n        ctx.rotate(0.5 * Math.PI)\n        ctx.translate(0, -sourceHeight)\n        break\n    }\n    // Some orientation combinations require additional rotation by 180\u00b0:\n    if (requiresRot180(orientation, autoOrientation)) {\n      ctx.translate(sourceWidth, sourceHeight)\n      ctx.rotate(Math.PI)\n    }\n    switch (orientation) {\n      case 2:\n        // Horizontal flip\n        ctx.translate(width, 0)\n        ctx.scale(-1, 1)\n        break\n      case 3:\n        // 180\u00b0 Rotate CCW\n        ctx.translate(width, height)\n        ctx.rotate(Math.PI)\n        break\n      case 4:\n        // Vertical flip\n        ctx.translate(0, height)\n        ctx.scale(1, -1)\n        break\n      case 5:\n        // Vertical flip + 90\u00b0 Rotate CW\n        ctx.rotate(0.5 * Math.PI)\n        ctx.scale(1, -1)\n        break\n      case 6:\n        // 90\u00b0 Rotate CW\n        ctx.rotate(0.5 * Math.PI)\n        ctx.translate(0, -height)\n        break\n      case 7:\n        // Horizontal flip + 90\u00b0 Rotate CW\n        ctx.rotate(0.5 * Math.PI)\n        ctx.translate(width, -height)\n        ctx.scale(-1, 1)\n        break\n      case 8:\n        // 90\u00b0 Rotate CCW\n        ctx.rotate(-0.5 * Math.PI)\n        ctx.translate(-width, 0)\n        break\n    }\n  }\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/index.js":"/* global module, require */\n\nmodule.exports = require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image')\n\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-scale')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-fetch')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif-map')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc-map')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-orientation')\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-fetch.js":"/*\n * JavaScript Load Image Fetch\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2017, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require, Promise */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var global = loadImage.global\n\n  if (\n    global.fetch &&\n    global.Request &&\n    global.Response &&\n    global.Response.prototype.blob\n  ) {\n    loadImage.fetchBlob = function (url, callback, options) {\n      /**\n       * Fetch response handler.\n       *\n       * @param {Response} response Fetch response\n       * @returns {Blob} Fetched Blob.\n       */\n      function responseHandler(response) {\n        return response.blob()\n      }\n      if (global.Promise && typeof callback !== 'function') {\n        return fetch(new Request(url, callback)).then(responseHandler)\n      }\n      fetch(new Request(url, options))\n        .then(responseHandler)\n        .then(callback)\n        [\n          // Avoid parsing error in IE<9, where catch is a reserved word.\n          // eslint-disable-next-line dot-notation\n          'catch'\n        ](function (err) {\n          callback(null, err)\n        })\n    }\n  } else if (\n    global.XMLHttpRequest &&\n    // https://xhr.spec.whatwg.org/#the-responsetype-attribute\n    new XMLHttpRequest().responseType === ''\n  ) {\n    loadImage.fetchBlob = function (url, callback, options) {\n      /**\n       * Promise executor\n       *\n       * @param {Function} resolve Resolution function\n       * @param {Function} reject Rejection function\n       */\n      function executor(resolve, reject) {\n        options = options || {} // eslint-disable-line no-param-reassign\n        var req = new XMLHttpRequest()\n        req.open(options.method || 'GET', url)\n        if (options.headers) {\n          Object.keys(options.headers).forEach(function (key) {\n            req.setRequestHeader(key, options.headers[key])\n          })\n        }\n        req.withCredentials = options.credentials === 'include'\n        req.responseType = 'blob'\n        req.onload = function () {\n          resolve(req.response)\n        }\n        req.onerror = req.onabort = req.ontimeout = function (err) {\n          if (resolve === reject) {\n            // Not using Promises\n            reject(null, err)\n          } else {\n            reject(err)\n          }\n        }\n        req.send(options.body)\n      }\n      if (global.Promise && typeof callback !== 'function') {\n        options = callback // eslint-disable-line no-param-reassign\n        return new Promise(executor)\n      }\n      return executor(callback, callback)\n    }\n  }\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta.js":"/*\n * JavaScript Load Image Meta\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Image metadata handling implementation\n * based on the help and contribution of\n * Achim St\u00f6hr.\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require, Promise, DataView, Uint8Array, ArrayBuffer */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var global = loadImage.global\n  var originalTransform = loadImage.transform\n\n  var blobSlice =\n    global.Blob &&\n    (Blob.prototype.slice ||\n      Blob.prototype.webkitSlice ||\n      Blob.prototype.mozSlice)\n\n  var bufferSlice =\n    (global.ArrayBuffer && ArrayBuffer.prototype.slice) ||\n    function (begin, end) {\n      // Polyfill for IE10, which does not support ArrayBuffer.slice\n      // eslint-disable-next-line no-param-reassign\n      end = end || this.byteLength - begin\n      var arr1 = new Uint8Array(this, begin, end)\n      var arr2 = new Uint8Array(end)\n      arr2.set(arr1)\n      return arr2.buffer\n    }\n\n  var metaDataParsers = {\n    jpeg: {\n      0xffe1: [], // APP1 marker\n      0xffed: [] // APP13 marker\n    }\n  }\n\n  /**\n   * Parses image metadata and calls the callback with an object argument\n   * with the following property:\n   * - imageHead: The complete image head as ArrayBuffer\n   * The options argument accepts an object and supports the following\n   * properties:\n   * - maxMetaDataSize: Defines the maximum number of bytes to parse.\n   * - disableImageHead: Disables creating the imageHead property.\n   *\n   * @param {Blob} file Blob object\n   * @param {Function} [callback] Callback function\n   * @param {object} [options] Parsing options\n   * @param {object} [data] Result data object\n   * @returns {Promise<object>|undefined} Returns Promise if no callback given.\n   */\n  function parseMetaData(file, callback, options, data) {\n    var that = this\n    /**\n     * Promise executor\n     *\n     * @param {Function} resolve Resolution function\n     * @param {Function} reject Rejection function\n     * @returns {undefined} Undefined\n     */\n    function executor(resolve, reject) {\n      if (\n        !(\n          global.DataView &&\n          blobSlice &&\n          file &&\n          file.size >= 12 &&\n          file.type === 'image/jpeg'\n        )\n      ) {\n        // Nothing to parse\n        return resolve(data)\n      }\n      // 256 KiB should contain all EXIF/ICC/IPTC segments:\n      var maxMetaDataSize = options.maxMetaDataSize || 262144\n      if (\n        !loadImage.readFile(\n          blobSlice.call(file, 0, maxMetaDataSize),\n          function (buffer) {\n            // Note on endianness:\n            // Since the marker and length bytes in JPEG files are always\n            // stored in big endian order, we can leave the endian parameter\n            // of the DataView methods undefined, defaulting to big endian.\n            var dataView = new DataView(buffer)\n            // Check for the JPEG marker (0xffd8):\n            if (dataView.getUint16(0) !== 0xffd8) {\n              return reject(\n                new Error('Invalid JPEG file: Missing JPEG marker.')\n              )\n            }\n            var offset = 2\n            var maxOffset = dataView.byteLength - 4\n            var headLength = offset\n            var markerBytes\n            var markerLength\n            var parsers\n            var i\n            while (offset < maxOffset) {\n              markerBytes = dataView.getUint16(offset)\n              // Search for APPn (0xffeN) and COM (0xfffe) markers,\n              // which contain application-specific metadata like\n              // Exif, ICC and IPTC data and text comments:\n              if (\n                (markerBytes >= 0xffe0 && markerBytes <= 0xffef) ||\n                markerBytes === 0xfffe\n              ) {\n                // The marker bytes (2) are always followed by\n                // the length bytes (2), indicating the length of the\n                // marker segment, which includes the length bytes,\n                // but not the marker bytes, so we add 2:\n                markerLength = dataView.getUint16(offset + 2) + 2\n                if (offset + markerLength > dataView.byteLength) {\n                  // eslint-disable-next-line no-console\n                  console.log('Invalid JPEG metadata: Invalid segment size.')\n                  break\n                }\n                parsers = metaDataParsers.jpeg[markerBytes]\n                if (parsers && !options.disableMetaDataParsers) {\n                  for (i = 0; i < parsers.length; i += 1) {\n                    parsers[i].call(\n                      that,\n                      dataView,\n                      offset,\n                      markerLength,\n                      data,\n                      options\n                    )\n                  }\n                }\n                offset += markerLength\n                headLength = offset\n              } else {\n                // Not an APPn or COM marker, probably safe to\n                // assume that this is the end of the metadata\n                break\n              }\n            }\n            // Meta length must be longer than JPEG marker (2)\n            // plus APPn marker (2), followed by length bytes (2):\n            if (!options.disableImageHead && headLength > 6) {\n              data.imageHead = bufferSlice.call(buffer, 0, headLength)\n            }\n            resolve(data)\n          },\n          reject,\n          'readAsArrayBuffer'\n        )\n      ) {\n        // No support for the FileReader interface, nothing to parse\n        resolve(data)\n      }\n    }\n    options = options || {} // eslint-disable-line no-param-reassign\n    if (global.Promise && typeof callback !== 'function') {\n      options = callback || {} // eslint-disable-line no-param-reassign\n      data = options // eslint-disable-line no-param-reassign\n      return new Promise(executor)\n    }\n    data = data || {} // eslint-disable-line no-param-reassign\n    return executor(callback, callback)\n  }\n\n  /**\n   * Replaces the head of a JPEG Blob\n   *\n   * @param {Blob} blob Blob object\n   * @param {ArrayBuffer} oldHead Old JPEG head\n   * @param {ArrayBuffer} newHead New JPEG head\n   * @returns {Blob} Combined Blob\n   */\n  function replaceJPEGHead(blob, oldHead, newHead) {\n    if (!blob || !oldHead || !newHead) return null\n    return new Blob([newHead, blobSlice.call(blob, oldHead.byteLength)], {\n      type: 'image/jpeg'\n    })\n  }\n\n  /**\n   * Replaces the image head of a JPEG blob with the given one.\n   * Returns a Promise or calls the callback with the new Blob.\n   *\n   * @param {Blob} blob Blob object\n   * @param {ArrayBuffer} head New JPEG head\n   * @param {Function} [callback] Callback function\n   * @returns {Promise<Blob|null>|undefined} Combined Blob\n   */\n  function replaceHead(blob, head, callback) {\n    var options = { maxMetaDataSize: 256, disableMetaDataParsers: true }\n    if (!callback && global.Promise) {\n      return parseMetaData(blob, options).then(function (data) {\n        return replaceJPEGHead(blob, data.imageHead, head)\n      })\n    }\n    parseMetaData(\n      blob,\n      function (data) {\n        callback(replaceJPEGHead(blob, data.imageHead, head))\n      },\n      options\n    )\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    if (loadImage.requiresMetaData(options)) {\n      data = data || {} // eslint-disable-line no-param-reassign\n      parseMetaData(\n        file,\n        function (result) {\n          if (result !== data) {\n            // eslint-disable-next-line no-console\n            if (global.console) console.log(result)\n            result = data // eslint-disable-line no-param-reassign\n          }\n          originalTransform.call(\n            loadImage,\n            img,\n            options,\n            callback,\n            file,\n            result\n          )\n        },\n        options,\n        data\n      )\n    } else {\n      originalTransform.apply(loadImage, arguments)\n    }\n  }\n\n  loadImage.blobSlice = blobSlice\n  loadImage.bufferSlice = bufferSlice\n  loadImage.replaceHead = replaceHead\n  loadImage.parseMetaData = parseMetaData\n  loadImage.metaDataParsers = metaDataParsers\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-tmpl/js/tmpl.js":"/*\n * JavaScript Templates\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Inspired by John Resig's JavaScript Micro-Templating:\n * http://ejohn.org/blog/javascript-micro-templating/\n */\n\n/* global define */\n\n/* eslint-disable strict */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (str, data) {\n    var f = !/[^\\w\\-.:]/.test(str)\n      ? (tmpl.cache[str] = tmpl.cache[str] || tmpl(tmpl.load(str)))\n      : new Function( // eslint-disable-line no-new-func\n          tmpl.arg + ',tmpl',\n          'var _e=tmpl.encode' +\n            tmpl.helper +\n            \",_s='\" +\n            str.replace(tmpl.regexp, tmpl.func) +\n            \"';return _s;\"\n        )\n    return data\n      ? f(data, tmpl)\n      : function (data) {\n          return f(data, tmpl)\n        }\n  }\n  tmpl.cache = {}\n  tmpl.load = function (id) {\n    return document.getElementById(id).innerHTML\n  }\n  tmpl.regexp = /([\\s'\\\\])(?!(?:[^{]|\\{(?!%))*%\\})|(?:\\{%(=|#)([\\s\\S]+?)%\\})|(\\{%)|(%\\})/g\n  tmpl.func = function (s, p1, p2, p3, p4, p5) {\n    if (p1) {\n      // whitespace, quote and backspace in HTML context\n      return (\n        {\n          '\\n': '\\\\n',\n          '\\r': '\\\\r',\n          '\\t': '\\\\t',\n          ' ': ' '\n        }[p1] || '\\\\' + p1\n      )\n    }\n    if (p2) {\n      // interpolation: {%=prop%}, or unescaped: {%#prop%}\n      if (p2 === '=') {\n        return \"'+_e(\" + p3 + \")+'\"\n      }\n      return \"'+(\" + p3 + \"==null?'':\" + p3 + \")+'\"\n    }\n    if (p4) {\n      // evaluation start tag: {%\n      return \"';\"\n    }\n    if (p5) {\n      // evaluation end tag: %}\n      return \"_s+='\"\n    }\n  }\n  tmpl.encReg = /[<>&\"'\\x00]/g // eslint-disable-line no-control-regex\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    // eslint-disable-next-line eqeqeq\n    return (s == null ? '' : '' + s).replace(tmpl.encReg, function (c) {\n      return tmpl.encMap[c] || ''\n    })\n  }\n  tmpl.arg = 'o'\n  tmpl.helper =\n    \",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}\" +\n    ',include=function(s,d){_s+=tmpl(s,d);}'\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n})(this)\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-tmpl/js/runtime.js":"/*\n * JavaScript Templates Runtime\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n/* eslint-disable strict */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (id, data) {\n    var f = tmpl.cache[id]\n    return data\n      ? f(data, tmpl)\n      : function (data) {\n          return f(data, tmpl)\n        }\n  }\n  tmpl.cache = {}\n  tmpl.encReg = /[<>&\"'\\x00]/g // eslint-disable-line no-control-regex\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    // eslint-disable-next-line eqeqeq\n    return (s == null ? '' : '' + s).replace(tmpl.encReg, function (c) {\n      return tmpl.encMap[c] || ''\n    })\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n})(this)\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-tmpl/js/compile.js":"#!/usr/bin/env node\n/*\n * JavaScript Templates Compiler\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* eslint-disable strict */\n/* eslint-disable no-console */\n\n;(function () {\n  'use strict'\n  var path = require('path')\n  var tmpl = require(path.join(__dirname, 'tmpl.js'))\n  var fs = require('fs')\n  // Retrieve the content of the minimal runtime:\n  var runtime = fs.readFileSync(path.join(__dirname, 'runtime.js'), 'utf8')\n  // A regular expression to parse templates from script tags in a HTML page:\n  var regexp = /<script( id=\"([\\w-]+)\")? type=\"text\\/x-tmpl\"( id=\"([\\w-]+)\")?>([\\s\\S]+?)<\\/script>/gi\n  // A regular expression to match the helper function names:\n  var helperRegexp = new RegExp(\n    tmpl.helper.match(/\\w+(?=\\s*=\\s*function\\s*\\()/g).join('\\\\s*\\\\(|') +\n      '\\\\s*\\\\('\n  )\n  // A list to store the function bodies:\n  var list = []\n  var code\n  // Extend the Templating engine with a print method for the generated functions:\n  tmpl.print = function (str) {\n    // Only add helper functions if they are used inside of the template:\n    var helper = helperRegexp.test(str) ? tmpl.helper : ''\n    var body = str.replace(tmpl.regexp, tmpl.func)\n    if (helper || /_e\\s*\\(/.test(body)) {\n      helper = '_e=tmpl.encode' + helper + ','\n    }\n    return (\n      'function(' +\n      tmpl.arg +\n      ',tmpl){' +\n      ('var ' + helper + \"_s='\" + body + \"';return _s;\")\n        .split(\"_s+='';\")\n        .join('') +\n      '}'\n    )\n  }\n  // Loop through the command line arguments:\n  process.argv.forEach(function (file, index) {\n    var listLength = list.length\n    var stats\n    var content\n    var result\n    var id\n    // Skip the first two arguments, which are \"node\" and the script:\n    if (index > 1) {\n      stats = fs.statSync(file)\n      if (!stats.isFile()) {\n        console.error(file + ' is not a file.')\n        return\n      }\n      content = fs.readFileSync(file, 'utf8')\n      // eslint-disable-next-line no-constant-condition\n      while (true) {\n        // Find templates in script tags:\n        result = regexp.exec(content)\n        if (!result) {\n          break\n        }\n        id = result[2] || result[4]\n        list.push(\"'\" + id + \"':\" + tmpl.print(result[5]))\n      }\n      if (listLength === list.length) {\n        // No template script tags found, use the complete content:\n        id = path.basename(file, path.extname(file))\n        list.push(\"'\" + id + \"':\" + tmpl.print(content))\n      }\n    }\n  })\n  if (!list.length) {\n    console.error('Missing input file.')\n    return\n  }\n  // Combine the generated functions as cache of the minimal runtime:\n  code = runtime.replace('{}', '{' + list.join(',') + '}')\n  // Print the resulting code to the console output:\n  console.log(code)\n})()\n","Mageplaza_Core/lib/fileUploader/cors/jquery.xdr-transport.js":"/*\n * jQuery XDomainRequest Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on Julian Aubourg's ajaxHooks xdr.js:\n * https://github.com/jaubourg/ajaxHooks/\n */\n\n/* global define, require, XDomainRequest */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(require('jquery'));\n  } else {\n    // Browser globals:\n    factory(window.jQuery);\n  }\n})(function ($) {\n  'use strict';\n  if (window.XDomainRequest && !$.support.cors) {\n    $.ajaxTransport(function (s) {\n      if (s.crossDomain && s.async) {\n        if (s.timeout) {\n          s.xdrTimeout = s.timeout;\n          delete s.timeout;\n        }\n        var xdr;\n        return {\n          send: function (headers, completeCallback) {\n            var addParamChar = /\\?/.test(s.url) ? '&' : '?';\n            /**\n             * Callback wrapper function\n             *\n             * @param {number} status HTTP status code\n             * @param {string} statusText HTTP status text\n             * @param {object} [responses] Content-type specific responses\n             * @param {string} [responseHeaders] Response headers string\n             */\n            function callback(status, statusText, responses, responseHeaders) {\n              xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;\n              xdr = null;\n              completeCallback(status, statusText, responses, responseHeaders);\n            }\n            xdr = new XDomainRequest();\n            // XDomainRequest only supports GET and POST:\n            if (s.type === 'DELETE') {\n              s.url = s.url + addParamChar + '_method=DELETE';\n              s.type = 'POST';\n            } else if (s.type === 'PUT') {\n              s.url = s.url + addParamChar + '_method=PUT';\n              s.type = 'POST';\n            } else if (s.type === 'PATCH') {\n              s.url = s.url + addParamChar + '_method=PATCH';\n              s.type = 'POST';\n            }\n            xdr.open(s.type, s.url);\n            xdr.onload = function () {\n              callback(\n                200,\n                'OK',\n                { text: xdr.responseText },\n                'Content-Type: ' + xdr.contentType\n              );\n            };\n            xdr.onerror = function () {\n              callback(404, 'Not Found');\n            };\n            if (s.xdrTimeout) {\n              xdr.ontimeout = function () {\n                callback(0, 'timeout');\n              };\n              xdr.timeout = s.xdrTimeout;\n            }\n            xdr.send((s.hasContent && s.data) || null);\n          },\n          abort: function () {\n            if (xdr) {\n              xdr.onerror = $.noop();\n              xdr.abort();\n            }\n          }\n        };\n      }\n    });\n  }\n});\n","Mageplaza_Core/lib/fileUploader/cors/jquery.postmessage-transport.js":"/*\n * jQuery postMessage Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(require('jquery'));\n  } else {\n    // Browser globals:\n    factory(window.jQuery);\n  }\n})(function ($) {\n  'use strict';\n\n  var counter = 0,\n    names = [\n      'accepts',\n      'cache',\n      'contents',\n      'contentType',\n      'crossDomain',\n      'data',\n      'dataType',\n      'headers',\n      'ifModified',\n      'mimeType',\n      'password',\n      'processData',\n      'timeout',\n      'traditional',\n      'type',\n      'url',\n      'username'\n    ],\n    convert = function (p) {\n      return p;\n    };\n\n  $.ajaxSetup({\n    converters: {\n      'postmessage text': convert,\n      'postmessage json': convert,\n      'postmessage html': convert\n    }\n  });\n\n  $.ajaxTransport('postmessage', function (options) {\n    if (options.postMessage && window.postMessage) {\n      var iframe,\n        loc = $('<a></a>').prop('href', options.postMessage)[0],\n        target = loc.protocol + '//' + loc.host,\n        xhrUpload = options.xhr().upload;\n      // IE always includes the port for the host property of a link\n      // element, but not in the location.host or origin property for the\n      // default http port 80 and https port 443, so we strip it:\n      if (/^(http:\\/\\/.+:80)|(https:\\/\\/.+:443)$/.test(target)) {\n        target = target.replace(/:(80|443)$/, '');\n      }\n      return {\n        send: function (_, completeCallback) {\n          counter += 1;\n          var message = {\n              id: 'postmessage-transport-' + counter\n            },\n            eventName = 'message.' + message.id;\n          iframe = $(\n            '<iframe style=\"display:none;\" src=\"' +\n              options.postMessage +\n              '\" name=\"' +\n              message.id +\n              '\"></iframe>'\n          )\n            .on('load', function () {\n              $.each(names, function (i, name) {\n                message[name] = options[name];\n              });\n              message.dataType = message.dataType.replace('postmessage ', '');\n              $(window).on(eventName, function (event) {\n                var e = event.originalEvent;\n                var data = e.data;\n                var ev;\n                if (e.origin === target && data.id === message.id) {\n                  if (data.type === 'progress') {\n                    ev = document.createEvent('Event');\n                    ev.initEvent(data.type, false, true);\n                    $.extend(ev, data);\n                    xhrUpload.dispatchEvent(ev);\n                  } else {\n                    completeCallback(\n                      data.status,\n                      data.statusText,\n                      { postmessage: data.result },\n                      data.headers\n                    );\n                    iframe.remove();\n                    $(window).off(eventName);\n                  }\n                }\n              });\n              iframe[0].contentWindow.postMessage(message, target);\n            })\n            .appendTo(document.body);\n        },\n        abort: function () {\n          if (iframe) {\n            iframe.remove();\n          }\n        }\n      };\n    }\n  });\n});\n","Magento_Cookie/js/require-cookie.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/alert',\n    'jquery-ui-modules/widget',\n    'mage/mage',\n    'mage/translate'\n], function ($, alert) {\n    'use strict';\n\n    $.widget('mage.requireCookie', {\n        options: {\n            event: 'click',\n            noCookieUrl: 'enable-cookies',\n            triggers: ['.action.login', '.action.submit'],\n            isRedirectCmsPage: true\n        },\n\n        /**\n         * Constructor\n         * @private\n         */\n        _create: function () {\n            this._bind();\n        },\n\n        /**\n         * This method binds elements found in this widget.\n         * @private\n         */\n        _bind: function () {\n            var events = {};\n\n            $.each(this.options.triggers, function (index, value) {\n                events['click ' + value] = '_checkCookie';\n            });\n            this._on(events);\n        },\n\n        /**\n         * This method set the url for the redirect.\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _checkCookie: function (event) {\n            if (navigator.cookieEnabled) {\n                return;\n            }\n\n            event.preventDefault();\n\n            if (this.options.isRedirectCmsPage) {\n                window.location = this.options.noCookieUrl;\n            } else {\n                alert({\n                    content: $.mage.__('Cookies are disabled in your browser.')\n                });\n            }\n        }\n    });\n\n    return $.mage.requireCookie;\n});\n","Magento_Cookie/js/notices.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'mage/cookies'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.cookieNotices', {\n        /** @inheritdoc */\n        _create: function () {\n            if ($.mage.cookies.get(this.options.cookieName)) {\n                this.element.hide();\n            } else {\n                this.element.show();\n            }\n            $(this.options.cookieAllowButtonSelector).on('click', $.proxy(function () {\n                var cookieExpires = new Date(new Date().getTime() + this.options.cookieLifetime * 1000);\n\n                $.mage.cookies.set(this.options.cookieName, JSON.stringify(this.options.cookieValue), {\n                    expires: cookieExpires\n                });\n\n                if ($.mage.cookies.get(this.options.cookieName)) {\n                    this.element.hide();\n                    $(document).trigger('user:allowed:save:cookie');\n                } else {\n                    window.location.href = this.options.noCookiesUrl;\n                }\n            }, this));\n        }\n    });\n\n    return $.mage.cookieNotices;\n});\n","Magento_Shipping/js/view/checkout/shipping/shipping-policy.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Shipping/js/model/config'\n\n], function (Component, config) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_Shipping/checkout/shipping/shipping-policy'\n        },\n        config: config()\n    });\n});\n","Magento_Shipping/js/model/config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    return function () {\n        return window.checkoutConfig.shippingPolicy;\n    };\n});\n","Magento_PageCache/js/page-cache.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'domReady',\n    'consoleLogger',\n    'Magento_PageCache/js/form-key-provider',\n    'jquery-ui-modules/widget',\n    'mage/cookies'\n], function ($, domReady, consoleLogger, formKeyInit) {\n    'use strict';\n\n    /**\n     * Helper. Generate random string\n     * TODO: Merge with mage/utils\n     * @param {String} chars - list of symbols\n     * @param {Number} length - length for need string\n     * @returns {String}\n     */\n    function generateRandomString(chars, length) {\n        var result = '';\n\n        length = length > 0 ? length : 1;\n\n        while (length--) {\n            result += chars[Math.round(Math.random() * (chars.length - 1))];\n        }\n\n        return result;\n    }\n\n    /**\n     * Nodes tree to flat list converter\n     * @returns {Array}\n     */\n    $.fn.comments = function () {\n        var elements = [],\n            contents,\n            elementContents;\n\n        /**\n         * @param {jQuery} element - Comment holder\n         */\n        (function lookup(element) {\n            var iframeHostName;\n\n            // prevent cross origin iframe content reading\n            if ($(element).prop('tagName') === 'IFRAME') {\n                iframeHostName = $('<a>').prop('href', $(element).prop('src'))\n                    .prop('hostname');\n\n                if (window.location.hostname !== iframeHostName) {\n                    return [];\n                }\n            }\n\n            /**\n             * Rewrite jQuery contents().\n             *\n             * @param {jQuery} elem\n             */\n            contents = function (elem) {\n                return $.map(elem, function (el) {\n                    try {\n                        return el.nodeName.toLowerCase() === 'iframe' ?\n                            el.contentDocument || (el.contentWindow ? el.contentWindow.document : []) :\n                            $.merge([], el.childNodes);\n                    } catch (e) {\n                        consoleLogger.error(e);\n\n                        return [];\n                    }\n                });\n            };\n\n            elementContents = contents($(element));\n\n            $.each(elementContents, function (index, el) {\n                switch (el.nodeType) {\n                    case 1: // ELEMENT_NODE\n                        lookup(el);\n                        break;\n\n                    case 8: // COMMENT_NODE\n                        elements.push(el);\n                        break;\n\n                    case 9: // DOCUMENT_NODE\n                        lookup($(el).find('body'));\n                        break;\n                }\n            });\n        })(this);\n\n        return elements;\n    };\n\n    /**\n     * FormKey Widget - this widget is generating from key, saves it to cookie and\n     * @deprecated see Magento/PageCache/view/frontend/web/js/form-key-provider.js\n     */\n    $.widget('mage.formKey', {\n        options: {\n            inputSelector: 'input[name=\"form_key\"]',\n            allowedCharacters: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',\n            length: 16\n        },\n\n        /**\n         * Creates widget 'mage.formKey'\n         * @private\n         */\n        _create: function () {\n            var formKey = $.mage.cookies.get('form_key'),\n                options = {\n                    secure: window.cookiesConfig ? window.cookiesConfig.secure : false\n                };\n\n            if (!formKey) {\n                formKey = generateRandomString(this.options.allowedCharacters, this.options.length);\n                $.mage.cookies.set('form_key', formKey, options);\n            }\n            $(this.options.inputSelector).val(formKey);\n        }\n    });\n\n    /**\n     * PageCache Widget\n     * Handles additional ajax request for rendering user private content.\n     */\n    $.widget('mage.pageCache', {\n        options: {\n            url: '/',\n            patternPlaceholderOpen: /^ BLOCK (.+) $/,\n            patternPlaceholderClose: /^ \\/BLOCK (.+) $/,\n            versionCookieName: 'private_content_version',\n            handles: []\n        },\n\n        /**\n         * Creates widget 'mage.pageCache'\n         * @private\n         */\n        _create: function () {\n            var placeholders,\n                version = $.mage.cookies.get(this.options.versionCookieName);\n\n            if (!version) {\n                return;\n            }\n            placeholders = this._searchPlaceholders(this.element.comments());\n\n            if (placeholders && placeholders.length) {\n                this._ajax(placeholders, version);\n            }\n        },\n\n        /**\n         * Parse page for placeholders.\n         * @param {Array} elements\n         * @returns {Array}\n         * @private\n         */\n        _searchPlaceholders: function (elements) {\n            var placeholders = [],\n                tmp = {},\n                ii,\n                len,\n                el, matches, name;\n\n            if (!(elements && elements.length)) {\n                return placeholders;\n            }\n\n            for (ii = 0, len = elements.length; ii < len; ii++) {\n                el = elements[ii];\n                matches = this.options.patternPlaceholderOpen.exec(el.nodeValue);\n                name = null;\n\n                if (matches) {\n                    name = matches[1];\n                    tmp[name] = {\n                        name: name,\n                        openElement: el\n                    };\n                } else {\n                    matches = this.options.patternPlaceholderClose.exec(el.nodeValue);\n\n                    if (matches) { //eslint-disable-line max-depth\n                        name = matches[1];\n\n                        if (tmp[name]) { //eslint-disable-line max-depth\n                            tmp[name].closeElement = el;\n                            placeholders.push(tmp[name]);\n                            delete tmp[name];\n                        }\n                    }\n                }\n            }\n\n            return placeholders;\n        },\n\n        /**\n         * Parse for page and replace placeholders\n         * @param {Object} placeholder\n         * @param {Object} html\n         * @protected\n         */\n        _replacePlaceholder: function (placeholder, html) {\n            var startReplacing = false,\n                prevSibling = null,\n                parent, contents, yy, len, element;\n\n            if (!placeholder || !html) {\n                return;\n            }\n\n            parent = $(placeholder.openElement).parent();\n            contents = parent.contents();\n\n            for (yy = 0, len = contents.length; yy < len; yy++) {\n                element = contents[yy];\n\n                if (element == placeholder.openElement) { //eslint-disable-line eqeqeq\n                    startReplacing = true;\n                }\n\n                if (startReplacing) {\n                    $(element).remove();\n                } else if (element.nodeType != 8) { //eslint-disable-line eqeqeq\n                    //due to comment tag doesn't have siblings we try to find it manually\n                    prevSibling = element;\n                }\n\n                if (element == placeholder.closeElement) { //eslint-disable-line eqeqeq\n                    break;\n                }\n            }\n\n            if (prevSibling) {\n                $(prevSibling).after(html);\n            } else {\n                $(parent).prepend(html);\n            }\n\n            // trigger event to use mage-data-init attribute\n            $(parent).trigger('contentUpdated');\n        },\n\n        /**\n         * AJAX helper\n         * @param {Object} placeholders\n         * @param {String} version\n         * @private\n         */\n        _ajax: function (placeholders, version) {\n            var ii,\n                data = {\n                    blocks: [],\n                    handles: this.options.handles,\n                    originalRequest: this.options.originalRequest,\n                    version: version\n                };\n\n            for (ii = 0; ii < placeholders.length; ii++) {\n                data.blocks.push(placeholders[ii].name);\n            }\n            data.blocks = JSON.stringify(data.blocks.sort());\n            data.handles = JSON.stringify(data.handles);\n            data.originalRequest = JSON.stringify(data.originalRequest);\n            $.ajax({\n                url: this.options.url,\n                data: data,\n                type: 'GET',\n                cache: true,\n                dataType: 'json',\n                context: this,\n\n                /**\n                 * Response handler\n                 * @param {Object} response\n                 */\n                success: function (response) {\n                    var placeholder, i;\n\n                    for (i = 0; i < placeholders.length; i++) {\n                        placeholder = placeholders[i];\n\n                        if (response.hasOwnProperty(placeholder.name)) {\n                            this._replacePlaceholder(placeholder, response[placeholder.name]);\n                        }\n                    }\n                }\n            });\n        }\n    });\n\n    domReady(function () {\n        formKeyInit();\n    });\n\n    return {\n        'pageCache': $.mage.pageCache,\n        'formKey': $.mage.formKey\n    };\n});\n","Magento_PageCache/js/form-key-provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(function () {\n    'use strict';\n\n    return function (settings) {\n        var formKey,\n            inputElements,\n            inputSelector = 'input[name=\"form_key\"]';\n\n        /**\n         * Set form_key cookie\n         * @private\n         */\n        function setFormKeyCookie(value) {\n            var expires,\n                secure,\n                date = new Date(),\n                cookiesConfig = window.cookiesConfig || {},\n                isSecure = !!cookiesConfig.secure,\n                samesite = cookiesConfig.samesite || 'lax';\n\n            date.setTime(date.getTime() + 86400000);\n            expires = '; expires=' + date.toUTCString();\n            secure = isSecure ? '; secure' : '';\n            samesite = '; samesite=' + samesite;\n\n            document.cookie = 'form_key=' + (value || '') + expires + secure + '; path=/' + samesite;\n        }\n\n        /**\n         * Retrieves form key from cookie\n         * @private\n         */\n        function getFormKeyCookie() {\n            var cookie,\n                i,\n                nameEQ = 'form_key=',\n                cookieArr = document.cookie.split(';');\n\n            for (i = 0; i < cookieArr.length; i++) {\n                cookie = cookieArr[i];\n\n                while (cookie.charAt(0) === ' ') {\n                    cookie = cookie.substring(1, cookie.length);\n                }\n\n                if (cookie.indexOf(nameEQ) === 0) {\n                    return cookie.substring(nameEQ.length, cookie.length);\n                }\n            }\n\n            return null;\n        }\n\n        /**\n         * Get form key from UI input hidden\n         * @private\n         */\n        function getFormKeyFromUI() {\n            return document.querySelector(inputSelector).value;\n        }\n\n        /**\n         * Generate form key string\n         * @private\n         */\n        function generateFormKeyString() {\n            var result = '',\n                length = 16,\n                chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n            while (length--) {\n                result += chars[Math.round(Math.random() * (chars.length - 1))];\n            }\n\n            return result;\n        }\n\n        /**\n         * Init form_key inputs with value\n         * @private\n         */\n        function initFormKey() {\n            formKey = getFormKeyCookie();\n\n            if (settings && settings.isPaginationCacheEnabled && !formKey) {\n                formKey = getFormKeyFromUI();\n                setFormKeyCookie(formKey);\n            }\n\n            if (!formKey) {\n                formKey = generateFormKeyString();\n                setFormKeyCookie(formKey);\n            }\n            inputElements = document.querySelectorAll(inputSelector);\n\n            if (inputElements.length) {\n                Array.prototype.forEach.call(inputElements, function (element) {\n                    element.setAttribute('value', formKey);\n                });\n            }\n        }\n\n        initFormKey();\n    };\n});\n","Magento_Captcha/js/captcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    /**\n     * @api\n     */\n    $.widget('mage.captcha', {\n        options: {\n            refreshClass: 'refreshing',\n            reloadSelector: '.captcha-reload',\n            imageSelector: '.captcha-img',\n            imageLoader: ''\n        },\n\n        /**\n         * Method binds click event to reload image\n         * @private\n         */\n        _create: function () {\n            this.element.on('click', this.options.reloadSelector, $.proxy(this.refresh, this));\n        },\n\n        /**\n         * Method triggers an AJAX request to refresh the CAPTCHA image\n         */\n        refresh: function () {\n            var imageLoader = this.options.imageLoader;\n\n            if (imageLoader) {\n                this.element.find(this.options.imageSelector).attr('src', imageLoader);\n            }\n            this.element.addClass(this.options.refreshClass);\n\n            $.ajax({\n                url: this.options.url,\n                type: 'post',\n                dataType: 'json',\n                context: this,\n                data: {\n                    'formId': this.options.type\n                },\n\n                /**\n                 * @param {Object} response\n                 */\n                success: function (response) {\n                    if (response.imgSrc) {\n                        this.element.find(this.options.imageSelector).attr('src', response.imgSrc);\n                    }\n                },\n\n                /** Complete callback. */\n                complete: function () {\n                    this.element.removeClass(this.options.refreshClass);\n                }\n            });\n        }\n    });\n\n    return $.mage.captcha;\n});\n","Magento_Captcha/js/view/checkout/loginCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Captcha/js/view/checkout/defaultCaptcha',\n    'Magento_Captcha/js/model/captchaList',\n    'Magento_Customer/js/action/login',\n    'underscore'\n],\nfunction (defaultCaptcha, captchaList, loginAction, _) {\n    'use strict';\n\n    return defaultCaptcha.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            var self = this,\n                currentCaptcha;\n\n            this._super();\n            currentCaptcha = captchaList.getCaptchaByFormId(this.formId);\n\n            if (currentCaptcha != null) {\n                currentCaptcha.setIsVisible(true);\n                this.setCurrentCaptcha(currentCaptcha);\n\n                loginAction.registerLoginCallback(function (loginData) {\n                    if (loginData['captcha_form_id'] &&\n                        loginData['captcha_form_id'] === self.formId &&\n                        self.isRequired()\n                    ) {\n                        _.defer(self.refresh.bind(self));\n                    }\n                });\n            }\n        }\n    });\n});\n","Magento_Captcha/js/view/checkout/defaultCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'uiComponent',\n    'Magento_Captcha/js/model/captcha',\n    'Magento_Captcha/js/model/captchaList',\n    'Magento_Customer/js/customer-data',\n    'underscore'\n], function ($, Component, Captcha, captchaList, customerData, _) {\n    'use strict';\n\n    var captchaConfig;\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_Captcha/checkout/captcha'\n        },\n        dataScope: 'global',\n        currentCaptcha: null,\n        subscribedFormIds: [],\n\n        /**\n         * @return {*}\n         */\n        captchaValue: function () {\n            return this.currentCaptcha.getCaptchaValue();\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            if (window[this.configSource] && window[this.configSource].captcha) {\n                captchaConfig = window[this.configSource].captcha;\n                $.each(captchaConfig, function (formId, captchaData) {\n                    var captcha;\n\n                    captchaData.formId = formId;\n                    captcha = Captcha(captchaData);\n                    this.checkCustomerData(formId, customerData.get('captcha')(), captcha);\n                    this.subscribeCustomerData(formId, captcha);\n                    captchaList.add(captcha);\n                }.bind(this));\n            }\n        },\n\n        /**\n         * Check customer data for captcha configuration.\n         *\n         * @param {String} formId\n         * @param {Object} captchaData\n         * @param {Object} captcha\n         */\n        checkCustomerData: function (formId, captchaData, captcha) {\n            if (!_.isEmpty(captchaData) &&\n                !_.isEmpty(captchaData[formId]) &&\n                captchaData[formId].timestamp > captcha.timestamp\n            ) {\n                if (!captcha.isRequired() && captchaData[formId].isRequired) {\n                    captcha.refresh();\n                }\n                captcha.isRequired(captchaData[formId].isRequired);\n                captcha.timestamp = captchaData[formId].timestamp;\n            }\n        },\n\n        /**\n         * Subscribe for customer data updates.\n         *\n         * @param {String} formId\n         * @param {Object} captcha\n         */\n        subscribeCustomerData: function (formId, captcha) {\n            if (this.subscribedFormIds.includes(formId) === false) {\n                this.subscribedFormIds.push(formId);\n                customerData.get('captcha').subscribe(function (captchaData) {\n                    this.checkCustomerData(formId, captchaData, captcha);\n                }.bind(this));\n            }\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        getIsLoading: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.isLoading : false;\n        },\n\n        /**\n         * @return {null|Object}\n         */\n        getCurrentCaptcha: function () {\n            return this.currentCaptcha;\n        },\n\n        /**\n         * @param {Object} captcha\n         */\n        setCurrentCaptcha: function (captcha) {\n            this.currentCaptcha = captcha;\n        },\n\n        /**\n         * @return {String|null}\n         */\n        getFormId: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getFormId() : null;\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        getIsVisible: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getIsVisible() : false;\n        },\n\n        /**\n         * @param {Boolean} flag\n         */\n        setIsVisible: function (flag) {\n            this.currentCaptcha.setIsVisible(flag);\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isRequired: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getIsRequired() : false;\n        },\n\n        /**\n         * Set isRequired on current captcha model.\n         *\n         * @param {Boolean} flag\n         */\n        setIsRequired: function (flag) {\n            this.currentCaptcha.setIsRequired(flag);\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isCaseSensitive: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getIsCaseSensitive() : false;\n        },\n\n        /**\n         * @return {String|Number|null}\n         */\n        imageHeight: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getImageHeight() : null;\n        },\n\n        /**\n         * @return {String|null}\n         */\n        getImageSource: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getImageSource() : null;\n        },\n\n        /**\n         * Refresh captcha.\n         */\n        refresh: function () {\n            this.currentCaptcha.refresh();\n        }\n    });\n});\n","Magento_Captcha/js/action/refresh.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery', 'mage/url'\n], function ($, urlBuilder) {\n    'use strict';\n\n    return function (refreshUrl, formId, imageSource) {\n        return $.ajax({\n            url: urlBuilder.build(refreshUrl),\n            type: 'POST',\n            data: JSON.stringify({\n                'formId': formId\n            }),\n            global: false,\n            contentType: 'application/json'\n        }).done(\n            function (response) {\n                if (response.imgSrc) {\n                    imageSource(response.imgSrc);\n                }\n            }\n        );\n    };\n});\n","Magento_Captcha/js/model/captcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'ko',\n    'Magento_Captcha/js/action/refresh'\n], function ($, ko, refreshAction) {\n    'use strict';\n\n    return function (captchaData) {\n        return {\n            formId: captchaData.formId,\n            imageSource: ko.observable(captchaData.imageSrc),\n            visibility: ko.observable(false),\n            captchaValue: ko.observable(null),\n            isRequired: ko.observable(captchaData.isRequired),\n            isCaseSensitive: captchaData.isCaseSensitive,\n            imageHeight: captchaData.imageHeight,\n            refreshUrl: captchaData.refreshUrl,\n            isLoading: ko.observable(false),\n            timestamp: null,\n\n            /**\n             * @return {String}\n             */\n            getFormId: function () {\n                return this.formId;\n            },\n\n            /**\n             * @param {String} formId\n             */\n            setFormId: function (formId) {\n                this.formId = formId;\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            getIsVisible: function () {\n                return this.visibility();\n            },\n\n            /**\n             * @param {Boolean} flag\n             */\n            setIsVisible: function (flag) {\n                this.visibility(flag);\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            getIsRequired: function () {\n                return this.isRequired();\n            },\n\n            /**\n             * @param {Boolean} flag\n             */\n            setIsRequired: function (flag) {\n                this.isRequired(flag);\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            getIsCaseSensitive: function () {\n                return this.isCaseSensitive;\n            },\n\n            /**\n             * @param {Boolean} flag\n             */\n            setIsCaseSensitive: function (flag) {\n                this.isCaseSensitive = flag;\n            },\n\n            /**\n             * @return {String|Number}\n             */\n            getImageHeight: function () {\n                return this.imageHeight;\n            },\n\n            /**\n             * @param {String|Number}height\n             */\n            setImageHeight: function (height) {\n                this.imageHeight = height;\n            },\n\n            /**\n             * @return {String}\n             */\n            getImageSource: function () {\n                return this.imageSource;\n            },\n\n            /**\n             * @param {String} imageSource\n             */\n            setImageSource: function (imageSource) {\n                this.imageSource(imageSource);\n            },\n\n            /**\n             * @return {String}\n             */\n            getRefreshUrl: function () {\n                return this.refreshUrl;\n            },\n\n            /**\n             * @param {String} url\n             */\n            setRefreshUrl: function (url) {\n                this.refreshUrl = url;\n            },\n\n            /**\n             * @return {*}\n             */\n            getCaptchaValue: function () {\n                return this.captchaValue;\n            },\n\n            /**\n             * @param {*} value\n             */\n            setCaptchaValue: function (value) {\n                this.captchaValue(value);\n            },\n\n            /**\n             * Refresh captcha.\n             */\n            refresh: function () {\n                var refresh,\n                    self = this;\n\n                this.isLoading(true);\n\n                refresh = refreshAction(this.getRefreshUrl(), this.getFormId(), this.getImageSource());\n                $.when(refresh).done(function () {\n                    self.isLoading(false);\n                });\n            }\n        };\n    };\n});\n","Magento_Captcha/js/model/captchaList.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['jquery'], function ($) {\n    'use strict';\n\n    var captchaList = [];\n\n    return {\n        /**\n         * @param {Object} captcha\n         */\n        add: function (captcha) {\n            captchaList.push(captcha);\n        },\n\n        /**\n         * @param {String} formId\n         * @return {Object}\n         */\n        getCaptchaByFormId: function (formId) {\n            var captcha = null;\n\n            $.each(captchaList, function (key, item) {\n                if (formId === item.formId) {\n                    captcha = item;\n\n                    return false;\n                }\n            });\n\n            return captcha;\n        },\n\n        /**\n         * @return {Array}\n         */\n        getCaptchaList: function () {\n            return captchaList;\n        }\n    };\n});\n","js-storage/js.storage.js":"/*\n * JS Storage Plugin\n *\n * Copyright (c) 2019 Julien Maurel\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/mit-license.php\n *\n * Project home:\n * https://github.com/julien-maurel/js-storage\n *\n * Version: 1.1.0\n */\n(function (factory) {\n    var registeredInModuleLoader = false;\n    if (typeof define === 'function' && define.amd) {\n        define(['jquery', 'jquery/jquery.cookie'], factory);\n        registeredInModuleLoader = true;\n    }\n    if (typeof exports === 'object') {\n        module.exports = factory();\n        registeredInModuleLoader = true;\n    }\n    if (!registeredInModuleLoader) {\n        var OldStorages = window.Storages;\n        var api = window.Storages = factory();\n        api.noConflict = function () {\n            window.Storages = OldStorages;\n            return api;\n        };\n    }\n}(function () {\n    // Variables used by utilities functions (like isPlainObject...)\n    var class2type = {};\n    var toString = class2type.toString;\n    var hasOwn = class2type.hasOwnProperty;\n    var fnToString = hasOwn.toString;\n    var ObjectFunctionString = fnToString.call(Object);\n    var getProto = Object.getPrototypeOf;\n    var apis = {};\n\n    // Prefix to use with cookie fallback\n    var cookie_local_prefix = \"ls_\";\n    var cookie_session_prefix = \"ss_\";\n\n    // Get items from a storage\n    function _get() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], vi, ret, tmp, i, j;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        } else if (Array.isArray(a0)) {\n            // If second argument is an array, return an object with value of storage for each item in this array\n            ret = {};\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    vi = a0[i];\n                    try {\n                        ret[vi] = JSON.parse(s.getItem(vi));\n                    } catch (e) {\n                        ret[vi] = s.getItem(vi);\n                    }\n                }\n            }\n            return ret;\n        } else if (l == 1) {\n            // If only 1 argument, return value directly\n            try {\n                return JSON.parse(s.getItem(a0));\n            } catch (e) {\n                return s.getItem(a0);\n            }\n        } else {\n            // If more than 1 argument, parse storage to retrieve final value to return it\n            // Get first level\n            try {\n                ret = JSON.parse(s.getItem(a0));\n                if (!ret) {\n                    throw new ReferenceError(a0 + ' is not defined in this storage');\n                }\n            } catch (e) {\n                throw new ReferenceError(a0 + ' is not defined in this storage');\n            }\n            // Parse next levels\n            for (i = 1; i < l - 1; i++) {\n                ret = ret[a[i]];\n                if (ret === undefined) {\n                    throw new ReferenceError([].slice.call(a, 0, i + 1).join('.') + ' is not defined in this storage');\n                }\n            }\n            // If last argument is an array, return an object with value for each item in this array\n            // Else return value normally\n            if (Array.isArray(a[i])) {\n                tmp = ret;\n                ret = {};\n                for (j in a[i]) {\n                    if (a[i].hasOwnProperty(j)) {\n                        ret[a[i][j]] = tmp[a[i][j]];\n                    }\n                }\n                return ret;\n            } else {\n                return ret[a[i]];\n            }\n        }\n    }\n\n    // Set items of a storage\n    function _set() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], a1 = a[1], vi, to_store = isNaN(a1) ? {} : [], type, tmp, i;\n        if (l < 1 || !_isPlainObject(a0) && l < 2) {\n            throw new Error('Minimum 2 arguments must be given or first parameter must be an object');\n        } else if (_isPlainObject(a0)) {\n            // If first argument is an object, set values of storage for each property of this object\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    vi = a0[i];\n                    if (!_isPlainObject(vi) && !this.alwaysUseJson) {\n                        s.setItem(i, vi);\n                    } else {\n                        s.setItem(i, JSON.stringify(vi));\n                    }\n                }\n            }\n            return a0;\n        } else if (l == 2) {\n            // If only 2 arguments, set value of storage directly\n            if (typeof a1 === 'object' || this.alwaysUseJson) {\n                s.setItem(a0, JSON.stringify(a1));\n            } else {\n                s.setItem(a0, a1);\n            }\n            return a1;\n        } else {\n            // If more than 3 arguments, parse storage to retrieve final node and set value\n            // Get first level\n            try {\n                tmp = s.getItem(a0);\n                if (tmp != null) {\n                    to_store = JSON.parse(tmp);\n                }\n            } catch (e) {\n            }\n            tmp = to_store;\n            // Parse next levels and set value\n            for (i = 1; i < l - 2; i++) {\n                vi = a[i];\n                type = isNaN(a[i + 1]) ? \"object\" : \"array\";\n                if (!tmp[vi] || type == \"object\" && !_isPlainObject(tmp[vi]) || type == \"array\" && !Array.isArray(tmp[vi])) {\n                    if (type == \"array\") tmp[vi] = [];\n                    else tmp[vi] = {};\n                }\n                tmp = tmp[vi];\n            }\n            tmp[a[i]] = a[i + 1];\n            s.setItem(a0, JSON.stringify(to_store));\n            return to_store;\n        }\n    }\n\n    // Remove items from a storage\n    function _remove() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], to_store, tmp, i, j;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        } else if (Array.isArray(a0)) {\n            // If first argument is an array, remove values from storage for each item of this array\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    s.removeItem(a0[i]);\n                }\n            }\n            return true;\n        } else if (l == 1) {\n            // If only 2 arguments, remove value from storage directly\n            s.removeItem(a0);\n            return true;\n        } else {\n            // If more than 2 arguments, parse storage to retrieve final node and remove value\n            // Get first level\n            try {\n                to_store = tmp = JSON.parse(s.getItem(a0));\n            } catch (e) {\n                throw new ReferenceError(a0 + ' is not defined in this storage');\n            }\n            // Parse next levels and remove value\n            for (i = 1; i < l - 1; i++) {\n                tmp = tmp[a[i]];\n                if (tmp === undefined) {\n                    throw new ReferenceError([].slice.call(a, 1, i).join('.') + ' is not defined in this storage');\n                }\n            }\n            // If last argument is an array,remove value for each item in this array\n            // Else remove value normally\n            if (Array.isArray(a[i])) {\n                for (j in a[i]) {\n                    if (a[i].hasOwnProperty(j)) {\n                        delete tmp[a[i][j]];\n                    }\n                }\n            } else {\n                delete tmp[a[i]];\n            }\n            s.setItem(a0, JSON.stringify(to_store));\n            return true;\n        }\n    }\n\n    // Remove all items from a storage\n    function _removeAll(reinit_ns) {\n        var keys = _keys.call(this), i;\n        for (i in keys) {\n            if (keys.hasOwnProperty(i)) {\n                _remove.call(this, keys[i]);\n            }\n        }\n        // Reinitialize all namespace storages\n        if (reinit_ns) {\n            for (i in apis.namespaceStorages) {\n                if (apis.namespaceStorages.hasOwnProperty(i)) {\n                    _createNamespace(i);\n                }\n            }\n        }\n    }\n\n    // Check if items of a storage are empty\n    function _isEmpty() {\n        var l = arguments.length, a = arguments, a0 = a[0], i;\n        if (l == 0) {\n            // If no argument, test if storage is empty\n            return (_keys.call(this).length == 0);\n        } else if (Array.isArray(a0)) {\n            // If first argument is an array, test each item of this array and return true only if all items are empty\n            for (i = 0; i < a0.length; i++) {\n                if (!_isEmpty.call(this, a0[i])) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            // If at least 1 argument, try to get value and test it\n            try {\n                var v = _get.apply(this, arguments);\n                // Convert result to an object (if last argument is an array, _get return already an object) and test each item\n                if (!Array.isArray(a[l - 1])) {\n                    v = {'totest': v};\n                }\n                for (i in v) {\n                    if (v.hasOwnProperty(i) && !(\n                        (_isPlainObject(v[i]) && _isEmptyObject(v[i])) ||\n                        (Array.isArray(v[i]) && !v[i].length) ||\n                        (typeof v[i] !== 'boolean' && !v[i])\n                    )) {\n                        return false;\n                    }\n                }\n                return true;\n            } catch (e) {\n                return true;\n            }\n        }\n    }\n\n    // Check if items of a storage exist\n    function _isSet() {\n        var l = arguments.length, a = arguments, a0 = a[0], i;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        }\n        if (Array.isArray(a0)) {\n            // If first argument is an array, test each item of this array and return true only if all items exist\n            for (i = 0; i < a0.length; i++) {\n                if (!_isSet.call(this, a0[i])) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            // For other case, try to get value and test it\n            try {\n                var v = _get.apply(this, arguments);\n                // Convert result to an object (if last argument is an array, _get return already an object) and test each item\n                if (!Array.isArray(a[l - 1])) {\n                    v = {'totest': v};\n                }\n                for (i in v) {\n                    if (v.hasOwnProperty(i) && !(v[i] !== undefined && v[i] !== null)) {\n                        return false;\n                    }\n                }\n                return true;\n            } catch (e) {\n                return false;\n            }\n        }\n    }\n\n    // Get keys of a storage or of an item of the storage\n    function _keys() {\n        var storage = this._type, l = arguments.length, s = window[storage], keys = [], o = {};\n        // If at least 1 argument, get value from storage to retrieve keys\n        // Else, use storage to retrieve keys\n        if (l > 0) {\n            o = _get.apply(this, arguments);\n        } else {\n            o = s;\n        }\n        if (o && o._cookie) {\n            // If storage is a cookie, use js-cookie to retrieve keys\n            var cookies = Cookies.get();\n            for (var key in cookies) {\n                if (cookies.hasOwnProperty(key) && key != '') {\n                    keys.push(key.replace(o._prefix, ''));\n                }\n            }\n        } else {\n            for (var i in o) {\n                if (o.hasOwnProperty(i)) {\n                    keys.push(i);\n                }\n            }\n        }\n        return keys;\n    }\n\n    // Create new namespace storage\n    function _createNamespace(name) {\n        if (!name || typeof name != \"string\") {\n            throw new Error('First parameter must be a string');\n        }\n        if (storage_available) {\n            if (!window.localStorage.getItem(name)) {\n                window.localStorage.setItem(name, '{}');\n            }\n            if (!window.sessionStorage.getItem(name)) {\n                window.sessionStorage.setItem(name, '{}');\n            }\n        } else {\n            if (!window.localCookieStorage.getItem(name)) {\n                window.localCookieStorage.setItem(name, '{}');\n            }\n            if (!window.sessionCookieStorage.getItem(name)) {\n                window.sessionCookieStorage.setItem(name, '{}');\n            }\n        }\n        var ns = {\n            localStorage: _extend({}, apis.localStorage, {_ns: name}),\n            sessionStorage: _extend({}, apis.sessionStorage, {_ns: name})\n        };\n        if (cookies_available) {\n            if (!window.cookieStorage.getItem(name)) {\n                window.cookieStorage.setItem(name, '{}');\n            }\n            ns.cookieStorage = _extend({}, apis.cookieStorage, {_ns: name});\n        }\n        apis.namespaceStorages[name] = ns;\n        return ns;\n    }\n\n    // Test if storage is natively available on browser\n    function _testStorage(name) {\n        var foo = 'jsapi';\n        try {\n            if (!window[name]) {\n                return false;\n            }\n            window[name].setItem(foo, foo);\n            window[name].removeItem(foo);\n            return true;\n        } catch (e) {\n            return false;\n        }\n    }\n\n    // Test if a variable is a plain object (from jQuery)\n    function _isPlainObject(obj) {\n        var proto, Ctor;\n\n        // Detect obvious negatives\n        // Use toString instead of jQuery.type to catch host objects\n        if (!obj || toString.call(obj) !== \"[object Object]\") {\n            return false;\n        }\n\n        proto = getProto(obj);\n\n        // Objects with no prototype (e.g., `Object.create( null )`) are plain\n        if (!proto) {\n            return true;\n        }\n\n        // Objects with prototype are plain iff they were constructed by a global Object function\n        Ctor = hasOwn.call(proto, \"constructor\") && proto.constructor;\n        return typeof Ctor === \"function\" && fnToString.call(Ctor) === ObjectFunctionString;\n    }\n\n    // Test if a variable is an empty object (from jQuery)\n    function _isEmptyObject(obj) {\n        var name;\n\n        for (name in obj) {\n            return false;\n        }\n        return true;\n    }\n\n    // Merge objects\n    function _extend() {\n        var i = 1;\n        var result = arguments[0];\n        for (; i < arguments.length; i++) {\n            var attributes = arguments[i];\n            for (var key in attributes) {\n                if (attributes.hasOwnProperty(key)) {\n                    result[key] = attributes[key];\n                }\n            }\n        }\n        return result;\n    }\n\n    // Check if storages are natively available on browser and check is js-cookie is present\n    var storage_available = _testStorage('localStorage');\n    var cookies_available = typeof Cookies !== 'undefined';\n\n    // Namespace object\n    var storage = {\n        _type: '',\n        _ns: '',\n        _callMethod: function (f, a) {\n            a = Array.prototype.slice.call(a);\n            var p = [], a0 = a[0];\n            if (this._ns) {\n                p.push(this._ns);\n            }\n            if (typeof a0 === 'string' && a0.indexOf('.') !== -1) {\n                a.shift();\n                [].unshift.apply(a, a0.split('.'));\n            }\n            [].push.apply(p, a);\n            return f.apply(this, p);\n        },\n        // Define if plugin always use JSON to store values (even to store simple values like string, int...) or not\n        alwaysUseJson: false,\n        // Get items. If no parameters and storage have a namespace, return all namespace\n        get: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_get, arguments);\n        },\n        // Set items\n        set: function () {\n            var l = arguments.length, a = arguments, a0 = a[0];\n            if (l < 1 || !_isPlainObject(a0) && l < 2) {\n                throw new Error('Minimum 2 arguments must be given or first parameter must be an object');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            // If first argument is an object and storage is a namespace storage, set values individually\n            if (_isPlainObject(a0) && this._ns) {\n                for (var i in a0) {\n                    if (a0.hasOwnProperty(i)) {\n                        this._callMethod(_set, [i, a0[i]]);\n                    }\n                }\n                return a0;\n            } else {\n                var r = this._callMethod(_set, a);\n                if (this._ns) {\n                    return r[a0.split('.')[0]];\n                } else {\n                    return r;\n                }\n            }\n        },\n        // Delete items\n        remove: function () {\n            if (arguments.length < 1) {\n                throw new Error('Minimum 1 argument must be given');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_remove, arguments);\n        },\n        // Delete all items\n        removeAll: function (reinit_ns) {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            if (this._ns) {\n                this._callMethod(_set, [{}]);\n                return true;\n            } else {\n                return this._callMethod(_removeAll, [reinit_ns]);\n            }\n        },\n        // Items empty\n        isEmpty: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_isEmpty, arguments);\n        },\n        // Items exists\n        isSet: function () {\n            if (arguments.length < 1) {\n                throw new Error('Minimum 1 argument must be given');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_isSet, arguments);\n        },\n        // Get keys of items\n        keys: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_keys, arguments);\n        }\n    };\n\n    // Use js-cookie for compatibility with old browsers and give access to cookieStorage\n    if (cookies_available) {\n        // sessionStorage is valid for one window/tab. To simulate that with cookie, we set a name for the window and use it for the name of the cookie\n        if (!window.name) {\n            window.name = Math.floor(Math.random() * 100000000);\n        }\n        var cookie_storage = {\n            _cookie: true,\n            _prefix: '',\n            _expires: null,\n            _path: null,\n            _domain: null,\n            _secure: false,\n            setItem: function (n, v) {\n                Cookies.set(this._prefix + n, v, {expires: this._expires, path: this._path, domain: this._domain, secure: this._secure});\n            },\n            getItem: function (n) {\n                return Cookies.get(this._prefix + n);\n            },\n            removeItem: function (n) {\n                return Cookies.remove(this._prefix + n, {path: this._path});\n            },\n            clear: function () {\n                var cookies = Cookies.get();\n                for (var key in cookies) {\n                    if (cookies.hasOwnProperty(key) && key != '') {\n                        if (!this._prefix && key.indexOf(cookie_local_prefix) === -1 && key.indexOf(cookie_session_prefix) === -1 || this._prefix && key.indexOf(this._prefix) === 0) {\n                            Cookies.remove(key);\n                        }\n                    }\n                }\n            },\n            setExpires: function (e) {\n                this._expires = e;\n                return this;\n            },\n            setPath: function (p) {\n                this._path = p;\n                return this;\n            },\n            setDomain: function (d) {\n                this._domain = d;\n                return this;\n            },\n            setSecure: function (s) {\n                this._secure = s;\n                return this;\n            },\n            setConf: function (c) {\n                if (c.path) {\n                    this._path = c.path;\n                }\n                if (c.domain) {\n                    this._domain = c.domain;\n                }\n                if (c.secure) {\n                    this._secure = c.secure;\n                }\n                if (c.expires) {\n                    this._expires = c.expires;\n                }\n                return this;\n            },\n            setDefaultConf: function () {\n                this._path = this._domain = this._expires = null;\n                this._secure = false;\n            }\n        };\n        if (!storage_available) {\n            window.localCookieStorage = _extend({}, cookie_storage, {\n                _prefix: cookie_local_prefix,\n                _expires: 365 * 10,\n                _secure: true\n            });\n            window.sessionCookieStorage = _extend({}, cookie_storage, {\n                _prefix: cookie_session_prefix + window.name + '_',\n                _secure: true\n            });\n        }\n        window.cookieStorage = _extend({}, cookie_storage);\n        // cookieStorage API\n        apis.cookieStorage = _extend({}, storage, {\n            _type: 'cookieStorage',\n            setExpires: function (e) {\n                window.cookieStorage.setExpires(e);\n                return this;\n            },\n            setPath: function (p) {\n                window.cookieStorage.setPath(p);\n                return this;\n            },\n            setDomain: function (d) {\n                window.cookieStorage.setDomain(d);\n                return this;\n            },\n            setSecure: function (s) {\n                window.cookieStorage.setSecure(s);\n                return this;\n            },\n            setConf: function (c) {\n                window.cookieStorage.setConf(c);\n                return this;\n            },\n            setDefaultConf: function () {\n                window.cookieStorage.setDefaultConf();\n                return this;\n            }\n        });\n    }\n\n    // Get a new API on a namespace\n    apis.initNamespaceStorage = function (ns) {\n        return _createNamespace(ns);\n    };\n    if (storage_available) {\n        // localStorage API\n        apis.localStorage = _extend({}, storage, {_type: 'localStorage'});\n        // sessionStorage API\n        apis.sessionStorage = _extend({}, storage, {_type: 'sessionStorage'});\n    } else {\n        // localStorage API\n        apis.localStorage = _extend({}, storage, {_type: 'localCookieStorage'});\n        // sessionStorage API\n        apis.sessionStorage = _extend({}, storage, {_type: 'sessionCookieStorage'});\n    }\n    // List of all namespace storage\n    apis.namespaceStorages = {};\n    // Remove all items in all storages\n    apis.removeAllStorages = function (reinit_ns) {\n        apis.localStorage.removeAll(reinit_ns);\n        apis.sessionStorage.removeAll(reinit_ns);\n        if (apis.cookieStorage) {\n            apis.cookieStorage.removeAll(reinit_ns);\n        }\n        if (!reinit_ns) {\n            apis.namespaceStorages = {};\n        }\n    };\n    // About alwaysUseJson\n    // By default, all values are string on html storages and the plugin don't use json to store simple values (strings, int, float...)\n    // So by default, if you do storage.setItem('test',2), value in storage will be \"2\", not 2\n    // If you set this property to true, all values set with the plugin will be stored as json to have typed values in any cases\n    apis.alwaysUseJsonInStorage = function (value) {\n        storage.alwaysUseJson = value;\n        apis.localStorage.alwaysUseJson = value;\n        apis.sessionStorage.alwaysUseJson = value;\n        if (apis.cookieStorage) {\n            apis.cookieStorage.alwaysUseJson = value;\n        }\n    };\n\n    return apis;\n}));\n","js-storage/storage-wrapper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'js-storage/js.storage'\n], function ($, storage) {\n    'use strict';\n\n    if (window.cookieStorage) {\n        var cookiesConfig = window.cookiesConfig || {};\n\n        $.extend(window.cookieStorage, {\n            _secure: !!cookiesConfig.secure,\n            _samesite: cookiesConfig.samesite ? cookiesConfig.samesite : 'lax',\n\n            /**\n             * Set value under name\n             * @param {String} name\n             * @param {String} value\n             * @param {Object} [options]\n             */\n            setItem: function (name, value, options) {\n                var _default = {\n                    expires: this._expires,\n                    path: this._path,\n                    domain: this._domain,\n                    secure: this._secure,\n                    samesite: this._samesite\n                };\n\n                $.cookie(this._prefix + name, value, $.extend(_default, options || {}));\n            },\n\n            /**\n             * Set default options\n             * @param {Object} c\n             * @returns {storage}\n             */\n            setConf: function (c) {\n                if (c.path) {\n                    this._path = c.path;\n                }\n\n                if (c.domain) {\n                    this._domain = c.domain;\n                }\n\n                if (c.expires) {\n                    this._expires = c.expires;\n                }\n\n                if (typeof c.secure !== 'undefined') {\n                    this._secure = c.secure;\n                }\n\n                if (typeof c.samesite !== 'undefined') {\n                    this._samesite = c.samesite;\n                }\n\n                return this;\n            }\n        });\n    }\n\n    $.alwaysUseJsonInStorage = $.alwaysUseJsonInStorage || storage.alwaysUseJsonInStorage;\n    $.cookieStorage = $.cookieStorage || storage.cookieStorage;\n    $.initNamespaceStorage = $.initNamespaceStorage || storage.initNamespaceStorage;\n    $.localStorage = $.localStorage || storage.localStorage;\n    $.namespaceStorages = $.namespaceStorages || storage.namespaceStorages;\n    $.removeAllStorages = $.removeAllStorages || storage.removeAllStorages;\n    $.sessionStorage = $.sessionStorage || storage.sessionStorage;\n});\n","Magento_InventoryConfigurableProductFrontendUi/js/configurable-variation-qty.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * Configurable variation left qty.\n */\ndefine([\n    'jquery',\n    'underscore',\n    'mage/url'\n], function ($, _, urlBuilder) {\n    'use strict';\n\n    return function (productSku, salesChannel, salesChannelCode) {\n        var selectorInfoStockSkuQty = '.availability.only',\n            selectorInfoStockSkuQtyValue = '.availability.only > strong',\n            productQtyInfoBlock = $(selectorInfoStockSkuQty),\n            productQtyInfo = $(selectorInfoStockSkuQtyValue);\n\n        if (!_.isUndefined(productSku) && productSku !== null) {\n            $.ajax({\n                url: urlBuilder.build('inventory_catalog/product/getQty/'),\n                dataType: 'json',\n                data: {\n                    'sku': productSku,\n                    'channel': salesChannel,\n                    'salesChannelCode': salesChannelCode\n                }\n            }).done(function (response) {\n                if (response.qty !== null && response.qty > 0) {\n                    productQtyInfo.text(response.qty);\n                    productQtyInfoBlock.show();\n                } else {\n                    productQtyInfoBlock.hide();\n                }\n            }).fail(function () {\n                productQtyInfoBlock.hide();\n            });\n        } else {\n            productQtyInfoBlock.hide();\n        }\n    };\n});\n","Magento_InventoryConfigurableProductFrontendUi/js/configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'configurableVariationQty',\n    'jquery-ui-modules/widget'\n], function ($, configurableVariationQty) {\n    'use strict';\n\n    return function (configurable) {\n        $.widget('mage.configurable', configurable, {\n\n            /** @inheritdoc */\n            _configureElement: function (element) {\n                var salesChannel = this.options.spConfig.channel,\n                    salesChannelCode = this.options.spConfig.salesChannelCode,\n                    productVariationsSku = this.options.spConfig.sku;\n\n                this._super(element);\n                configurableVariationQty(productVariationsSku[this.simpleProduct], salesChannel, salesChannelCode);\n            }\n        });\n\n        return $.mage.configurable;\n    };\n});\n","requirejs/domReady.js":"/**\n * @license RequireJS domReady 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.\n * Available via the MIT or new BSD license.\n * see: http://github.com/requirejs/domReady for details\n */\n/*jslint */\n/*global require: false, define: false, requirejs: false,\n  window: false, clearInterval: false, document: false,\n  self: false, setInterval: false */\n\n\ndefine(function () {\n    'use strict';\n\n    var isTop, testDiv, scrollIntervalId,\n        isBrowser = typeof window !== \"undefined\" && window.document,\n        isPageLoaded = !isBrowser,\n        doc = isBrowser ? document : null,\n        readyCalls = [];\n\n    function runCallbacks(callbacks) {\n        var i;\n        for (i = 0; i < callbacks.length; i += 1) {\n            callbacks[i](doc);\n        }\n    }\n\n    function callReady() {\n        var callbacks = readyCalls;\n\n        if (isPageLoaded) {\n            //Call the DOM ready callbacks\n            if (callbacks.length) {\n                readyCalls = [];\n                runCallbacks(callbacks);\n            }\n        }\n    }\n\n    /**\n     * Sets the page as loaded.\n     */\n    function pageLoaded() {\n        if (!isPageLoaded) {\n            isPageLoaded = true;\n            if (scrollIntervalId) {\n                clearInterval(scrollIntervalId);\n            }\n\n            callReady();\n        }\n    }\n\n    if (isBrowser) {\n        if (document.addEventListener) {\n            //Standards. Hooray! Assumption here that if standards based,\n            //it knows about DOMContentLoaded.\n            document.addEventListener(\"DOMContentLoaded\", pageLoaded, false);\n            window.addEventListener(\"load\", pageLoaded, false);\n        } else if (window.attachEvent) {\n            window.attachEvent(\"onload\", pageLoaded);\n\n            testDiv = document.createElement('div');\n            try {\n                isTop = window.frameElement === null;\n            } catch (e) {}\n\n            //DOMContentLoaded approximation that uses a doScroll, as found by\n            //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/,\n            //but modified by other contributors, including jdalton\n            if (testDiv.doScroll && isTop && window.external) {\n                scrollIntervalId = setInterval(function () {\n                    try {\n                        testDiv.doScroll();\n                        pageLoaded();\n                    } catch (e) {}\n                }, 30);\n            }\n        }\n\n        //Check if document is no longer loading, and if so, just trigger page load\n        //listeners. Latest webkit browsers also use \"interactive\", and\n        //will fire the onDOMContentLoaded before \"interactive\" but not after\n        //entering \"interactive\" or \"complete\". More details:\n        //http://dev.w3.org/html5/spec/the-end.html#the-end\n        //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded\n        //Hmm, this is more complicated on further use, see \"firing too early\"\n        //bug: https://github.com/requirejs/domReady/issues/1\n        //so removing the || document.readyState === \"interactive\" test.\n        //There is still a window.onload binding that should get fired if\n        //DOMContentLoaded is missed.\n        if (document.readyState !== \"loading\") {\n            // Handle it asynchronously to allow scripts the opportunity to delay ready\n            setTimeout(pageLoaded);\n        }\n    }\n\n    /** START OF PUBLIC API **/\n\n    /**\n     * Registers a callback for DOM ready. If DOM is already ready, the\n     * callback is called immediately.\n     * @param {Function} callback\n     */\n    function domReady(callback) {\n        if (isPageLoaded) {\n            callback(doc);\n        } else {\n            readyCalls.push(callback);\n        }\n        return domReady;\n    }\n\n    domReady.version = '2.0.1';\n\n    /**\n     * Loader Plugin API method\n     */\n    domReady.load = function (name, req, onLoad, config) {\n        if (config.isBuild) {\n            onLoad(null);\n        } else {\n            domReady(onLoad);\n        }\n    };\n\n    /** END OF PUBLIC API **/\n\n    return domReady;\n});\n","requirejs/text.js":"/**\n * @license RequireJS text 2.0.12 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.\n * Available via the MIT or new BSD license.\n * see: http://github.com/requirejs/text for details\n */\n/*jslint regexp: true */\n/*global require, XMLHttpRequest, ActiveXObject,\n  define, window, process, Packages,\n  java, location, Components, FileUtils */\n\ndefine(['module'], function (module) {\n    'use strict';\n\n    var text, fs, Cc, Ci, xpcIsWindows,\n        progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],\n        xmlRegExp = /^\\s*<\\?xml(\\s)+version=[\\'\\\"](\\d)*.(\\d)*[\\'\\\"](\\s)*\\?>/im,\n        bodyRegExp = /<body[^>]*>\\s*([\\s\\S]+)\\s*<\\/body>/im,\n        hasLocation = typeof location !== 'undefined' && location.href,\n        defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\\:/, ''),\n        defaultHostName = hasLocation && location.hostname,\n        defaultPort = hasLocation && (location.port || undefined),\n        buildMap = {},\n        masterConfig = (module.config && module.config()) || {};\n\n    text = {\n        version: '2.0.12',\n\n        strip: function (content) {\n            //Strips <?xml ...?> declarations so that external SVG and XML\n            //documents can be added to a document without worry. Also, if the string\n            //is an HTML document, only the part inside the body tag is returned.\n            if (content) {\n                content = content.replace(xmlRegExp, \"\");\n                var matches = content.match(bodyRegExp);\n                if (matches) {\n                    content = matches[1];\n                }\n            } else {\n                content = \"\";\n            }\n            return content;\n        },\n\n        jsEscape: function (content) {\n            return content.replace(/(['\\\\])/g, '\\\\$1')\n                .replace(/[\\f]/g, \"\\\\f\")\n                .replace(/[\\b]/g, \"\\\\b\")\n                .replace(/[\\n]/g, \"\\\\n\")\n                .replace(/[\\t]/g, \"\\\\t\")\n                .replace(/[\\r]/g, \"\\\\r\")\n                .replace(/[\\u2028]/g, \"\\\\u2028\")\n                .replace(/[\\u2029]/g, \"\\\\u2029\");\n        },\n\n        createXhr: masterConfig.createXhr || function () {\n            //Would love to dump the ActiveX crap in here. Need IE 6 to die first.\n            var xhr, i, progId;\n            if (typeof XMLHttpRequest !== \"undefined\") {\n                return new XMLHttpRequest();\n            } else if (typeof ActiveXObject !== \"undefined\") {\n                for (i = 0; i < 3; i += 1) {\n                    progId = progIds[i];\n                    try {\n                        xhr = new ActiveXObject(progId);\n                    } catch (e) {}\n\n                    if (xhr) {\n                        progIds = [progId];  // so faster next time\n                        break;\n                    }\n                }\n            }\n\n            return xhr;\n        },\n\n        /**\n         * Parses a resource name into its component parts. Resource names\n         * look like: module/name.ext!strip, where the !strip part is\n         * optional.\n         * @param {String} name the resource name\n         * @returns {Object} with properties \"moduleName\", \"ext\" and \"strip\"\n         * where strip is a boolean.\n         */\n        parseName: function (name) {\n            var modName, ext, temp,\n                strip = false,\n                index = name.indexOf(\".\"),\n                isRelative = name.indexOf('./') === 0 ||\n                             name.indexOf('../') === 0;\n\n            if (index !== -1 && (!isRelative || index > 1)) {\n                modName = name.substring(0, index);\n                ext = name.substring(index + 1, name.length);\n            } else {\n                modName = name;\n            }\n\n            temp = ext || modName;\n            index = temp.indexOf(\"!\");\n            if (index !== -1) {\n                //Pull off the strip arg.\n                strip = temp.substring(index + 1) === \"strip\";\n                temp = temp.substring(0, index);\n                if (ext) {\n                    ext = temp;\n                } else {\n                    modName = temp;\n                }\n            }\n\n            return {\n                moduleName: modName,\n                ext: ext,\n                strip: strip\n            };\n        },\n\n        xdRegExp: /^((\\w+)\\:)?\\/\\/([^\\/\\\\]+)/,\n\n        /**\n         * Is an URL on another domain. Only works for browser use, returns\n         * false in non-browser environments. Only used to know if an\n         * optimized .js version of a text resource should be loaded\n         * instead.\n         * @param {String} url\n         * @returns Boolean\n         */\n        useXhr: function (url, protocol, hostname, port) {\n            var uProtocol, uHostName, uPort,\n                match = text.xdRegExp.exec(url);\n            if (!match) {\n                return true;\n            }\n            uProtocol = match[2];\n            uHostName = match[3];\n\n            uHostName = uHostName.split(':');\n            uPort = uHostName[1];\n            uHostName = uHostName[0];\n\n            return (!uProtocol || uProtocol === protocol) &&\n                   (!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) &&\n                   ((!uPort && !uHostName) || uPort === port);\n        },\n\n        finishLoad: function (name, strip, content, onLoad) {\n            content = strip ? text.strip(content) : content;\n            if (masterConfig.isBuild) {\n                buildMap[name] = content;\n            }\n            onLoad(content);\n        },\n\n        load: function (name, req, onLoad, config) {\n            //Name has format: some.module.filext!strip\n            //The strip part is optional.\n            //if strip is present, then that means only get the string contents\n            //inside a body tag in an HTML string. For XML/SVG content it means\n            //removing the <?xml ...?> declarations so the content can be inserted\n            //into the current doc without problems.\n\n            // Do not bother with the work if a build and text will\n            // not be inlined.\n            if (config && config.isBuild && !config.inlineText) {\n                onLoad();\n                return;\n            }\n\n            masterConfig.isBuild = config && config.isBuild;\n\n            var parsed = text.parseName(name),\n                nonStripName = parsed.moduleName +\n                    (parsed.ext ? '.' + parsed.ext : ''),\n                url = req.toUrl(nonStripName),\n                useXhr = (masterConfig.useXhr) ||\n                         text.useXhr;\n\n            // Do not load if it is an empty: url\n            if (url.indexOf('empty:') === 0) {\n                onLoad();\n                return;\n            }\n\n            //Load the text. Use XHR if possible and in a browser.\n            if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {\n                text.get(url, function (content) {\n                    text.finishLoad(name, parsed.strip, content, onLoad);\n                }, function (err) {\n                    if (onLoad.error) {\n                        onLoad.error(err);\n                    }\n                });\n            } else {\n                //Need to fetch the resource across domains. Assume\n                //the resource has been optimized into a JS module. Fetch\n                //by the module name + extension, but do not include the\n                //!strip part to avoid file system issues.\n                req([nonStripName], function (content) {\n                    text.finishLoad(parsed.moduleName + '.' + parsed.ext,\n                                    parsed.strip, content, onLoad);\n                });\n            }\n        },\n\n        write: function (pluginName, moduleName, write, config) {\n            if (buildMap.hasOwnProperty(moduleName)) {\n                var content = text.jsEscape(buildMap[moduleName]);\n                write.asModule(pluginName + \"!\" + moduleName,\n                               \"define(function () { return '\" +\n                                   content +\n                               \"';});\\n\");\n            }\n        },\n\n        writeFile: function (pluginName, moduleName, req, write, config) {\n            var parsed = text.parseName(moduleName),\n                extPart = parsed.ext ? '.' + parsed.ext : '',\n                nonStripName = parsed.moduleName + extPart,\n                //Use a '.js' file name so that it indicates it is a\n                //script that can be loaded across domains.\n                fileName = req.toUrl(parsed.moduleName + extPart) + '.js';\n\n            //Leverage own load() method to load plugin value, but only\n            //write out values that do not have the strip argument,\n            //to avoid any potential issues with ! in file names.\n            text.load(nonStripName, req, function (value) {\n                //Use own write() method to construct full module value.\n                //But need to create shell that translates writeFile's\n                //write() to the right interface.\n                var textWrite = function (contents) {\n                    return write(fileName, contents);\n                };\n                textWrite.asModule = function (moduleName, contents) {\n                    return write.asModule(moduleName, fileName, contents);\n                };\n\n                text.write(pluginName, nonStripName, textWrite, config);\n            }, config);\n        }\n    };\n\n    if (masterConfig.env === 'node' || (!masterConfig.env &&\n            typeof process !== \"undefined\" &&\n            process.versions &&\n            !!process.versions.node &&\n            !process.versions['node-webkit'])) {\n        //Using special require.nodeRequire, something added by r.js.\n        fs = require.nodeRequire('fs');\n\n        text.get = function (url, callback, errback) {\n            try {\n                var file = fs.readFileSync(url, 'utf8');\n                //Remove BOM (Byte Mark Order) from utf8 files if it is there.\n                if (file.indexOf('\\uFEFF') === 0) {\n                    file = file.substring(1);\n                }\n                callback(file);\n            } catch (e) {\n                if (errback) {\n                    errback(e);\n                }\n            }\n        };\n    } else if (masterConfig.env === 'xhr' || (!masterConfig.env &&\n            text.createXhr())) {\n        text.get = function (url, callback, errback, headers) {\n            var xhr = text.createXhr(), header;\n            xhr.open('GET', url, true);\n\n            //Allow plugins direct access to xhr headers\n            if (headers) {\n                for (header in headers) {\n                    if (headers.hasOwnProperty(header)) {\n                        xhr.setRequestHeader(header.toLowerCase(), headers[header]);\n                    }\n                }\n            }\n\n            //Allow overrides specified in config\n            if (masterConfig.onXhr) {\n                masterConfig.onXhr(xhr, url);\n            }\n\n            xhr.onreadystatechange = function (evt) {\n                var status, err;\n                //Do not explicitly handle errors, those should be\n                //visible via console output in the browser.\n                if (xhr.readyState === 4) {\n                    status = xhr.status || 0;\n                    if (status > 399 && status < 600) {\n                        //An http 4xx or 5xx error. Signal an error.\n                        err = new Error(url + ' HTTP status: ' + status);\n                        err.xhr = xhr;\n                        if (errback) {\n                            errback(err);\n                        }\n                    } else {\n                        callback(xhr.responseText);\n                    }\n\n                    if (masterConfig.onXhrComplete) {\n                        masterConfig.onXhrComplete(xhr, url);\n                    }\n                }\n            };\n            xhr.send(null);\n        };\n    } else if (masterConfig.env === 'rhino' || (!masterConfig.env &&\n            typeof Packages !== 'undefined' && typeof java !== 'undefined')) {\n        //Why Java, why is this so awkward?\n        text.get = function (url, callback) {\n            var stringBuffer, line,\n                encoding = \"utf-8\",\n                file = new java.io.File(url),\n                lineSeparator = java.lang.System.getProperty(\"line.separator\"),\n                input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),\n                content = '';\n            try {\n                stringBuffer = new java.lang.StringBuffer();\n                line = input.readLine();\n\n                // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324\n                // http://www.unicode.org/faq/utf_bom.html\n\n                // Note that when we use utf-8, the BOM should appear as \"EF BB BF\", but it doesn't due to this bug in the JDK:\n                // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058\n                if (line && line.length() && line.charAt(0) === 0xfeff) {\n                    // Eat the BOM, since we've already found the encoding on this file,\n                    // and we plan to concatenating this buffer with others; the BOM should\n                    // only appear at the top of a file.\n                    line = line.substring(1);\n                }\n\n                if (line !== null) {\n                    stringBuffer.append(line);\n                }\n\n                while ((line = input.readLine()) !== null) {\n                    stringBuffer.append(lineSeparator);\n                    stringBuffer.append(line);\n                }\n                //Make sure we return a JavaScript string and not a Java string.\n                content = String(stringBuffer.toString()); //String\n            } finally {\n                input.close();\n            }\n            callback(content);\n        };\n    } else if (masterConfig.env === 'xpconnect' || (!masterConfig.env &&\n            typeof Components !== 'undefined' && Components.classes &&\n            Components.interfaces)) {\n        //Avert your gaze!\n        Cc = Components.classes;\n        Ci = Components.interfaces;\n        Components.utils['import']('resource://gre/modules/FileUtils.jsm');\n        xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc);\n\n        text.get = function (url, callback) {\n            var inStream, convertStream, fileObj,\n                readData = {};\n\n            if (xpcIsWindows) {\n                url = url.replace(/\\//g, '\\\\');\n            }\n\n            fileObj = new FileUtils.File(url);\n\n            //XPCOM, you so crazy\n            try {\n                inStream = Cc['@mozilla.org/network/file-input-stream;1']\n                           .createInstance(Ci.nsIFileInputStream);\n                inStream.init(fileObj, 1, 0, false);\n\n                convertStream = Cc['@mozilla.org/intl/converter-input-stream;1']\n                                .createInstance(Ci.nsIConverterInputStream);\n                convertStream.init(inStream, \"utf-8\", inStream.available(),\n                Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);\n\n                convertStream.readString(inStream.available(), readData);\n                convertStream.close();\n                inStream.close();\n                callback(readData.value);\n            } catch (e) {\n                throw new Error((fileObj && fileObj.path || '') + ': ' + e);\n            }\n        };\n    }\n    return text;\n});","Magento_LoginAsCustomerFrontendUi/js/login.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Customer/js/customer-data',\n    'Magento_Customer/js/section-config'\n], function ($, customerData, sectionConfig) {\n\n    'use strict';\n\n    return function (config) {\n        customerData.reload(sectionConfig.getSectionNames()).done(function () {\n            window.location.href = config.redirectUrl;\n        });\n    };\n});\n","Magento_LoginAsCustomerFrontendUi/js/view/loginAsCustomer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'uiComponent',\n    'Magento_Customer/js/customer-data',\n    'mage/translate'\n], function ($, _, Component, customer) {\n    'use strict';\n\n    return Component.extend({\n\n        defaults: {\n            isVisible: false\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            var customerData, loggedAsCustomerData;\n\n            this._super();\n\n            customerData = customer.get('customer');\n            loggedAsCustomerData = customer.get('loggedAsCustomer');\n\n            customerData.subscribe(function (data) {\n                this.fullname = data.fullname;\n                this.updateBanner();\n            }.bind(this));\n            loggedAsCustomerData.subscribe(function (data) {\n                this.adminUserId = data.adminUserId;\n                this.websiteName = data.websiteName;\n                this.updateBanner();\n            }.bind(this));\n\n            this.fullname = customerData().fullname;\n            this.adminUserId = loggedAsCustomerData().adminUserId;\n            this.websiteName = loggedAsCustomerData().websiteName;\n\n            this.updateBanner();\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe(['isVisible', 'notificationText']);\n\n            return this;\n        },\n\n        /**\n         * Update banner area\n         *\n         * @returns void\n         */\n        updateBanner: function () {\n            if (this.adminUserId !== undefined) {\n                this.isVisible(this.adminUserId);\n            }\n\n            if (this.fullname !== undefined && this.websiteName !== undefined) {\n                this.notificationText($.mage.__('You are connected as <strong>%1</strong> on %2')\n                    .replace('%1', _.escape(this.fullname))\n                    .replace('%2', _.escape(this.websiteName)));\n            }\n        }\n    });\n});\n","Magento_Persistent/js/view/additional-welcome.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/translate',\n    'Magento_Customer/js/customer-data'\n], function ($, $t, customerData) {\n    'use strict';\n\n    return {\n        /**\n         * Init.\n         */\n        init: function () {\n            var persistent = customerData.get('persistent');\n\n            if (persistent().fullname === undefined) {\n                customerData.get('persistent').subscribe(this.replacePersistentWelcome);\n            } else {\n                this.replacePersistentWelcome();\n            }\n        },\n\n        /**\n         * Replace welcome message for customer with persistent cookie.\n         */\n        replacePersistentWelcome: function () {\n            var persistent = customerData.get('persistent'),\n                welcomeElems;\n\n            if (persistent().fullname !== undefined) {\n                welcomeElems = $('li.greet.welcome > span.not-logged-in');\n\n                if (welcomeElems.length) {\n                    $(welcomeElems).each(function () {\n                        var html = $t('Welcome, %1!').replace('%1', persistent().fullname);\n\n                        $(this).attr('data-bind', html);\n                        $(this).html(html);\n                    });\n                    $(welcomeElems).append(' <span><a ' + window.notYouLink + '>' + $t('Not you?') + '</a>');\n                }\n            }\n        },\n\n        /**\n         * @constructor\n         */\n        'Magento_Persistent/js/view/additional-welcome': function () {\n            this.init();\n        }\n    };\n});\n","Magento_Persistent/js/view/customer-data-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'mage/utils/wrapper'\n], function ($, wrapper) {\n    'use strict';\n\n    var mixin = {\n\n        /**\n         * Check if persistent section is expired due to lifetime.\n         *\n         * @param {Function} originFn - Original method.\n         * @return {Array}\n         */\n        getExpiredSectionNames: function (originFn) {\n            var expiredSections = originFn(),\n                storage = $.initNamespaceStorage('mage-cache-storage').localStorage,\n                currentTimestamp = Math.floor(Date.now() / 1000),\n                persistentIndex = expiredSections.indexOf('persistent'),\n                persistentLifeTime = 0,\n                sectionData;\n\n            if (window.persistent !== undefined && window.persistent.expirationLifetime !== undefined) {\n                persistentLifeTime = window.persistent.expirationLifetime;\n            }\n\n            if (persistentIndex !== -1) {\n                sectionData = storage.get('persistent');\n\n                if (typeof sectionData === 'object' &&\n                    sectionData['data_id'] + persistentLifeTime >= currentTimestamp\n                ) {\n                    expiredSections.splice(persistentIndex, 1);\n                }\n            }\n\n            return expiredSections;\n        },\n\n        /**\n         * @param {Object} settings\n         * @constructor\n         */\n        'Magento_Customer/js/customer-data': function (originFn) {\n            let mageCacheTimeout = new Date($.localStorage.get('mage-cache-timeout')),\n                mageCacheSessId = $.cookieStorage.isSet('mage-cache-sessid');\n\n            originFn();\n            if (window.persistent !== undefined && (mageCacheTimeout < new Date() || !mageCacheSessId)) {\n                this.reload(['persistent','cart'],true);\n            }\n        }\n    };\n\n    /**\n     * Override default customer-data.getExpiredSectionNames().\n     */\n    return function (target) {\n        return wrapper.extend(target, mixin);\n    };\n});\n","Magento_Review/js/validate-review.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery/validate',\n    'mage/translate'\n], function ($) {\n    'use strict';\n\n    $.validator.addMethod(\n        'rating-required', function (value) {\n            return value !== undefined;\n        }, $.mage.__('Please select one of each of the ratings above.'));\n});\n","Magento_Review/js/submit-review.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    return function (config, element) {\n        $(element).on('submit', function () {\n            if ($(this).valid()) {\n                $(this).find('.submit').attr('disabled', true);\n            }\n        });\n    };\n});\n","Magento_Review/js/process-reviews.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'tabs',\n    'collapsible'\n], function ($) {\n    'use strict';\n\n    /**\n     * @param {String} url\n     * @param {*} fromPages\n     */\n    function processReviews(url, fromPages) {\n        $.ajax({\n            url: url,\n            cache: true,\n            dataType: 'html',\n            showLoader: false,\n            loaderContext: $('.product.data.items')\n        }).done(function (data) {\n            $('#product-review-container').html(data).trigger('contentUpdated'); \n            if($('.product.info.detailed').hasClass('vertical')) {\n              $('#product-review-container').parent().parent().css(\"min-height\",$('#product-review-container').parent().outerHeight()+\"px\");\n            }\n\n            $('[data-role=\"product-review\"] .pages a').each(function (index, element) {\n                $(element).on('click', function (event) { //eslint-disable-line max-nested-callbacks\n                    processReviews($(element).attr('href'), true);\n                    event.preventDefault();\n                });\n            });\n        }).always(function () {\n            if (fromPages == true) { //eslint-disable-line eqeqeq\n                $('html, body').animate({\n                    scrollTop: $('#reviews').offset().top - 50\n                }, 300);\n            }\n        });\n    }\n\n    return function (config) {\n        var reviewTab = $(config.reviewsTabSelector),\n            requiredReviewTabRole = 'tab';\n\n        if (reviewTab.attr('role') === requiredReviewTabRole && reviewTab.hasClass('active')) {\n            processReviews(config.productReviewUrl, location.hash === '#reviews');\n        } else {\n            reviewTab.one('beforeOpen', function () {\n                processReviews(config.productReviewUrl);\n            });\n        }\n\n        $(function () {\n            $('.product-info-main .reviews-actions a').on('click', function (event) {\n                var anchor, addReviewBlock;\n\n                event.preventDefault();\n                anchor = $(this).attr('href').replace(/^.*?(#|$)/, '');\n                addReviewBlock = $('#' + anchor);\n\n                if (addReviewBlock.length) {\n                    $('.product.data.items [data-role=\"content\"]').each(function (index) { //eslint-disable-line\n                        if (this.id == 'reviews') { //eslint-disable-line eqeqeq\n                            $('.product.data.items').tabs('activate', index);\n                        }\n                    });\n                    $('html, body').animate({\n                        scrollTop: addReviewBlock.offset().top - 50\n                    }, 300);\n                }\n\n            });\n        });\n    };\n});\n","Magento_Review/js/error-placement.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/mage'\n], function ($) {\n    'use strict';\n\n    return function (config, element) {\n        $(element).mage('validation', {\n            /** @inheritdoc */\n            errorPlacement: function (error, el) {\n\n                if (el.parents('#product-review-table').length) {\n                    $('#product-review-table').siblings(this.errorElement + '.' + this.errorClass).remove();\n                    $('#product-review-table').after(error);\n                } else {\n                    el.after(error);\n                }\n            }\n        });\n    };\n});\n","Magento_Review/js/view/review.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Customer/js/customer-data',\n    'Magento_Customer/js/view/customer'\n], function (Component, customerData) {\n    'use strict';\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this.review = customerData.get('review').extend({\n                disposableCustomerData: 'review'\n            });\n        },\n\n        /**\n         * @return {*}\n         */\n        nickname: function () {\n            return this.review().nickname || customerData.get('customer')().firstname;\n        }\n    });\n});\n","Magento_Downloadable/js/downloadable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'Magento_Catalog/js/price-box'\n], function ($) {\n    'use strict';\n\n    /**\n     * Downloadable widget\n     */\n    $.widget('mage.downloadable', {\n        options: {\n            priceHolderSelector: '.price-box',\n            linkElement: '',\n            allElements: ''\n        },\n\n        /**\n         * @inheritdoc\n         */\n        _init: function initLinks() {\n            var element = this.element,\n                options = $(this.options.linkElement, element);\n\n            options.trigger('change');\n        },\n\n        /**\n         *  @inheritdoc\n         */\n        _create: function () {\n            var self = this;\n\n            this.element.find(this.options.linkElement).on('change', $.proxy(function () {\n                this._reloadPrice();\n            }, this));\n\n            this.element.find(this.options.allElements).on('change', function () {\n                if (this.checked) {\n                    $('label[for=\"' + this.id + '\"] > span').text($(this).attr('data-checked'));\n                    self.element.find(self.options.linkElement + ':not(:checked)').each(function () {\n                        $(this).trigger('click');\n                    });\n                } else {\n                    $('[for=\"' + this.id + '\"] > span').text($(this).attr('data-notchecked'));\n                    self.element.find(self.options.linkElement + ':checked').each(function () {\n                        $(this).trigger('click');\n                    });\n                }\n            });\n\n            this._reloadPrice();\n        },\n\n        /**\n         * Reload product price with selected link price included\n         * @private\n         */\n        _reloadPrice: function () {\n            var finalPrice = 0,\n                basePrice = 0;\n\n            this.element.find(this.options.linkElement + ':checked').each($.proxy(function (index, element) {\n                finalPrice += this.options.config.links[$(element).val()].finalPrice;\n                basePrice += this.options.config.links[$(element).val()].basePrice;\n            }, this));\n\n            $(this.options.priceHolderSelector).trigger('updatePrice', {\n                'prices': {\n                    'finalPrice': {\n                        'amount': finalPrice\n                    },\n                    'basePrice': {\n                        'amount': basePrice\n                    }\n                }\n            });\n\n            this.reloadAllCheckText();\n        },\n\n        /**\n         * Reload all-elements-checkbox's label\n         * @private\n         */\n        reloadAllCheckText: function () {\n            var allChecked = true,\n                allElementsCheck = $(this.options.allElements),\n                allElementsLabel = $('label[for=\"' + allElementsCheck.attr('id') + '\"] > span');\n\n            $(this.options.linkElement).each(function () {\n                if (!this.checked) {\n                    allChecked = false;\n                }\n            });\n\n            if (allChecked) {\n                allElementsLabel.text(allElementsCheck.attr('data-checked'));\n                allElementsCheck.prop('checked', true);\n            } else {\n                allElementsLabel.text(allElementsCheck.attr('data-notchecked'));\n                allElementsCheck.prop('checked', false);\n            }\n        }\n    });\n\n    return $.mage.downloadable;\n});\n","Mageplaza_AjaxLayer/js/view/layer.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_AjaxLayer\r\n * @copyright   Copyright (c) Mageplaza (http://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\n\r\ndefine([\r\n    'jquery',\r\n    'Mageplaza_AjaxLayer/js/action/submit-filter',\r\n    'Magento_Catalog/js/price-utils',\r\n    'jquery-ui-modules/widget',\r\n    'accordion',\r\n    'productListToolbarForm'\r\n], function ($, submitFilterAction, ultil) {\r\n    \"use strict\";\r\n\r\n    var infinite_loaded_count = 0;\r\n\r\n    $.widget('mageplaza.layer', $.mage.accordion, {\r\n        options: {\r\n            openedState: 'active',\r\n            collapsible: true,\r\n            multipleCollapsible: true,\r\n            animate: 200,\r\n            productsListSelector: '#layer-product-list',\r\n            mobileShopbyElement: '#layered-filter-block .filter-title [data-role=title]',\r\n            collapsibleElement: '[data-role=ln_collapsible]',\r\n            header: '[data-role=ln_title]',\r\n            content: '[data-role=ln_content]',\r\n            isCustomerLoggedIn: false,\r\n            params: [],\r\n            active: []\r\n        },\r\n\r\n        inFinite: function() {\r\n            var self = this;\r\n            next_page = \"\";\r\n            if($(self.options.productsListSelector +' .infinite-loader').length > 0){\r\n                active = true;\r\n            }\r\n            $(\".pages-items li > a.next\").each(function(){\r\n                next_page = $(this).attr(\"href\");\r\n            });\r\n            if(!next_page){\r\n                $('.infinite-loader').hide();\r\n            }\r\n            $(\".infinite-loader .btn-load-more\").click(function(){\r\n                if(!loading && next_page){\r\n                    loading = true;\r\n                    self.ajaxInfinite(next_page);\r\n                }\r\n            });\r\n        },\r\n\r\n        ajaxInfinite: function (submitUrl) {\r\n          var self = this;\r\n          infinite_loaded_count++;\r\n          $('.infinite-loader .btn-load-more').hide();\r\n          $('.infinite-loader .loading').show();\r\n          $.ajax({\r\n              url: submitUrl,\r\n              type: 'get',\r\n              beforeSend: function () {\r\n                  $('.infinite-loader .btn-load-more').hide();\r\n                  $('.infinite-loader .loading').show();\r\n              },\r\n              success: function (res) {\r\n                  loading = false;\r\n                  var $products = $(res.products);\r\n                  if (res.backUrl) {\r\n                      window.location = res.backUrl;\r\n                      return;\r\n                  }\r\n                  if($products){\r\n                      $products.each(function(i,el){\r\n                          if($(el).hasClass('products-grid')){\r\n                              var items_grid = $(this).find('.product-items .item');\r\n                              $(self.options.productsListSelector + ' .products.wrapper .product-items').append(items_grid);\r\n                              $(self.options.productsListSelector).trigger('contentUpdated');\r\n                          }\r\n                          if($(el).hasClass('products-list')){\r\n                              var items_list = $(this).find('.product-items .item');\r\n                              $(self.options.productsListSelector + ' .products.wrapper .product-items').append(items_list);\r\n                              $(self.options.productsListSelector).trigger('contentUpdated');\r\n                          }\r\n                          if($(el).hasClass('toolbar-products')){\r\n                              if($(this).find('.pages a.next').length > 0){\r\n                                  $(self.options.productsListSelector + ' .pages a.next').attr('href', $(this).find('.pages a.next').attr('href'));\r\n                              }else{\r\n                                  $(self.options.productsListSelector + ' .pages a.next').remove();\r\n                              }\r\n                          }\r\n                      });\r\n                      if($(\"form[data-role=tocart-form]\").length > 0) {\r\n                          $(\"form[data-role=tocart-form]\").catalogAddToCart();\r\n                      }\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(2n)').addClass('nth-child-2n');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(2n+1)').addClass('nth-child-2np1');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(3n)').addClass('nth-child-3n');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(3n+1)').addClass('nth-child-3np1');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(4n)').addClass('nth-child-4n');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(4n+1)').addClass('nth-child-4np1');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(5n)').addClass('nth-child-5n');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(5n+1)').addClass('nth-child-5np1');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(6n)').addClass('nth-child-6n');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(6n+1)').addClass('nth-child-6np1');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(7n)').addClass('nth-child-7n');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(7n+1)').addClass('nth-child-7np1');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(8n)').addClass('nth-child-8n');\r\n                      $('.main .products.grid .product-items li.product-item:nth-child(8n+1)').addClass('nth-child-8np1');\r\n                      var hist = submitUrl;\r\n                      if(submitUrl.indexOf(\"p=\") > -1){\r\n                          var len = submitUrl.length-submitUrl.indexOf(\"p=\");\r\n                          var str_temp = submitUrl.substr(submitUrl.indexOf(\"p=\"),len);\r\n                          var page_param = \"\";\r\n                          if(str_temp.indexOf(\"&\") == -1){\r\n                              page_param = str_temp;\r\n                          } else {\r\n                              page_param = str_temp.substr(0,str_temp.indexOf(\"&\"));\r\n                          }\r\n                          hist = submitUrl.replace(page_param, \"\");\r\n                      }\r\n                      if (typeof window.history.pushState === 'function') {\r\n                          window.history.pushState({url: hist}, '', hist);\r\n                      }\r\n                      if(typeof enable_quickview != 'undefined' && enable_quickview == true) {\r\n                          requirejs(['jquery', 'weltpixel_quickview' ],\r\n                              function($, quickview) {\r\n                                  $('.weltpixel-quickview').off('click').on('click', function() {\r\n                                      var prodUrl = $(this).attr('data-quickview-url');\r\n                                      if (prodUrl.length) {\r\n                                          quickview.displayContent(prodUrl);\r\n                                      }\r\n                                  });\r\n                              });\r\n                      }\r\n                      $(\".products-grid .weltpixel-quickview\").each(function(){\r\n                          $(this).appendTo($(this).parent().parent().children(\".product-item-photo\"));\r\n                      });\r\n                      $(\"#layer-product-list img.porto-lazyload:not(.porto-lazyload-loaded)\").lazyload({effect:\"fadeIn\"});\r\n                      if ($('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').length) {\r\n                          $('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('initialized.owl.carousel', function() {\r\n                              $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\r\n                          });\r\n                          $('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('changed.owl.carousel', function() {\r\n                              $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\r\n                          });\r\n                      }\r\n                      next_page = \"\";\r\n                      $(\".pages-items li > a.next\").each(function(){\r\n                          next_page = $(this).attr(\"href\");\r\n                      });\r\n                      $('.infinite-loader .loading').hide();\r\n                      if(next_page){\r\n                          $('.infinite-loader .btn-load-more').show();\r\n                          $(\".infinite-loader .btn-load-more\").unbind(\"click\").click(function(){\r\n                              if(!loading && next_page){\r\n                                  loading = true;\r\n                                  self.ajaxInfinite(next_page);\r\n                              }\r\n                          });\r\n                      }\r\n                  }\r\n\r\n              },\r\n              error: function () {\r\n                  window.location.reload();\r\n              }\r\n          });\r\n\r\n        _create: function () {\r\n            this.initActiveItems();\r\n\r\n            this._super();\r\n\r\n            this.initProductListUrl();\r\n            this.initObserve();\r\n            this.initWishlistCompare();\r\n        },\r\n\r\n        initActiveItems: function () {\r\n            var layerActives = this.options.active,\r\n                actives = [];\r\n\r\n            if (typeof window.layerActiveTabs !== 'undefined') {\r\n                layerActives = window.layerActiveTabs;\r\n            }\r\n            if (layerActives.length) {\r\n                this.element.find('.filter-options-item').each(function (index) {\r\n                    if (~$.inArray($(this).attr('attribute'), layerActives)) {\r\n                        actives.push(index);\r\n                    }\r\n                });\r\n            }\r\n\r\n            this.options.active = actives;\r\n\r\n            return this;\r\n        },\r\n\r\n        initProductListUrl: function () {\r\n            var isProcessToolbar = false;\r\n            $.mage.productListToolbarForm.prototype.changeUrl = function (paramName, paramValue, defaultValue) {\r\n                if (isProcessToolbar) {\r\n                    return;\r\n                }\r\n                isProcessToolbar = true;\r\n\r\n                var urlPaths = this.options.url.split('?'),\r\n                    baseUrl = urlPaths[0],\r\n                    urlParams = urlPaths[1] ? urlPaths[1].split('&') : [],\r\n                    paramData = {},\r\n                    parameters;\r\n                for (var i = 0; i < urlParams.length; i++) {\r\n                    parameters = urlParams[i].split('=');\r\n                    paramData[parameters[0]] = parameters[1] !== undefined\r\n                        ? window.decodeURIComponent(parameters[1].replace(/\\+/g, '%20'))\r\n                        : '';\r\n                }\r\n                paramData[paramName] = paramValue;\r\n                if (paramValue === defaultValue) {\r\n                    delete paramData[paramName];\r\n                }\r\n                paramData = $.param(paramData);\r\n                submitFilterAction(baseUrl + (paramData.length ? '?' + paramData : ''));\r\n            }\r\n        },\r\n\r\n        initObserve: function () {\r\n            var self = this;\r\n\r\n            // fix browser back, forward button\r\n            if (typeof window.history.replaceState === \"function\") {\r\n                window.history.replaceState({url: document.URL}, document.title);\r\n\r\n                setTimeout(function () {\r\n                    window.onpopstate = function (e) {\r\n                        if (e.state) {\r\n                            submitFilterAction(e.state.url, 1);\r\n                        }\r\n                    };\r\n                }, 0)\r\n            }\r\n\r\n            var pageElements = $('#layer-product-list').find('.pages a');\r\n            pageElements.each(function () {\r\n                var el = $(this),\r\n                    link = self.checkUrl(el.prop('href'));\r\n                if (!link) {\r\n                    return;\r\n                }\r\n\r\n                el.bind('click', function (e) {\r\n                    submitFilterAction(link);\r\n                    e.stopPropagation();\r\n                    e.preventDefault();\r\n                })\r\n            });\r\n\r\n            var currentElements = this.element.find('.filter-current a, .filter-actions a');\r\n            currentElements.each(function (index) {\r\n                var el = $(this),\r\n                    link = self.checkUrl(el.prop('href'));\r\n                if (!link) {\r\n                    return;\r\n                }\r\n\r\n                el.bind('click', function (e) {\r\n                    submitFilterAction(link);\r\n                    e.stopPropagation();\r\n                    e.preventDefault();\r\n                });\r\n            });\r\n\r\n            var optionElements = this.element.find('.filter-options a');\r\n            optionElements.each(function (index) {\r\n                var el = $(this),\r\n                    link = self.checkUrl(el.prop('href'));\r\n                if (!link) {\r\n                    return;\r\n                }\r\n\r\n                el.bind('click', function (e) {\r\n                    if (el.hasClass('swatch-option-link-layered')) {\r\n                        self.selectSwatchOption(el);\r\n                    }\r\n\r\n                    self.ajaxSubmit(link);\r\n                    e.stopPropagation();\r\n                    e.preventDefault();\r\n                });\r\n            });\r\n\r\n            var swatchElements = this.element.find('.swatch-attribute');\r\n            swatchElements.each(function (index) {\r\n                var el = $(this);\r\n                var attCode = el.attr('attribute-code');\r\n                if (attCode) {\r\n                    if (self.options.params.hasOwnProperty(attCode)) {\r\n                        var attValues = self.options.params[attCode].split(\",\");\r\n                        var swatchOptions = el.find('.swatch-option');\r\n                        swatchOptions.each(function (option) {\r\n                            var elOption = $(this);\r\n                            if ($.inArray(elOption.attr('option-id'), attValues) !== -1) {\r\n                                elOption.addClass('selected');\r\n                            }\r\n                        });\r\n                    }\r\n                }\r\n            });\r\n            if(typeof enable_quickview != 'undefined' && enable_quickview == true) {\r\n                requirejs(['jquery', 'weltpixel_quickview' ],\r\n                    function($, quickview) {\r\n                        $('.weltpixel-quickview').off('click').on('click', function() {\r\n                            var prodUrl = $(this).attr('data-quickview-url');\r\n                            if (prodUrl.length) {\r\n                                quickview.displayContent(prodUrl);\r\n                            }\r\n                        });\r\n                    });\r\n            }\r\n\r\n            $(\".products-grid .weltpixel-quickview\").each(function(){\r\n                $(this).appendTo($(this).parents('.product-item-info').children(\".product-item-photo\"));\r\n            });\r\n            $(\"#layer-product-list img.porto-lazyload:not(.porto-lazyload-loaded)\").lazyload({effect:\"fadeIn\"});\r\n            if ($('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').length) {\r\n                $('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('changed.owl.carousel', function() {\r\n                    $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\r\n                });\r\n            }\r\n            self.inFinite();\r\n        },\r\n\r\n        selectSwatchOption: function (el) {\r\n            var childEl = el.find('.swatch-option');\r\n            if (childEl.hasClass('selected')) {\r\n                childEl.removeClass('selected');\r\n            } else {\r\n                childEl.addClass('selected');\r\n            }\r\n        },\r\n\r\n        ajaxSubmit: function (submitUrl) {\r\n            this.element.find(this.options.mobileShopbyElement).trigger('click');\r\n\r\n            return submitFilterAction(submitUrl);\r\n        },\r\n\r\n        checkUrl: function (url) {\r\n            var regex = /(http|https):\\/\\/(\\w+:{0,1}\\w*)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%!\\-\\/]))?/;\r\n\r\n            return regex.test(url) ? url : null;\r\n        },\r\n\r\n        //Handling 'add to wishlist' & 'add to compare' event\r\n        initWishlistCompare: function () {\r\n            var isCustomerLoggedIn = this.options.isCustomerLoggedIn,\r\n                elClass = 'a.action.tocompare' + (isCustomerLoggedIn ? ',a.action.towishlist' : '');\r\n            $(elClass).each(function () {\r\n                var el = $(this);\r\n                $(el).bind('click', function (e) {\r\n                    var dataPost = $(el).data('post'),\r\n                        formKey = $('input[name=\"form_key\"]').val(), method = 'post';\r\n                    if (formKey) {\r\n                        dataPost.data.form_key = formKey;\r\n                    }\r\n\r\n                    var paramData = $.param(dataPost.data),\r\n                        url = dataPost.action + (paramData.length ? '?' + paramData : '');\r\n                    submitFilterAction(url, true, method);\r\n                    e.stopPropagation();\r\n                    e.preventDefault();\r\n                });\r\n            })\r\n        }\r\n    });\r\n\r\n    return $.mageplaza.layer;\r\n});\r\n","Mageplaza_AjaxLayer/js/action/submit-filter.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_AjaxLayer\r\n * @copyright   Copyright (c) Mageplaza (http://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\n\r\ndefine(\r\n    [\r\n        'jquery',\r\n        'mage/storage',\r\n        'Mageplaza_AjaxLayer/js/model/loader',\r\n        'mage/apply/main',\r\n        'ko'\r\n    ],\r\n    function ($, storage, loader, mage, ko) {\r\n        'use strict';\r\n\r\n        var productContainer   = $('#layer-product-list'),\r\n            layerContainer     = $('.layered-filter-block-container'),\r\n            quickViewContainer = $('#mpquickview-popup');\r\n\r\n        return function (submitUrl, isChangeUrl, method) {\r\n            /** save active state */\r\n            var actives = [],\r\n                data;\r\n            $('.filter-options-item').each(function (index) {\r\n                if ($(this).hasClass('active')) {\r\n                    actives.push($(this).attr('attribute'));\r\n                }\r\n            });\r\n            window.layerActiveTabs = actives;\r\n\r\n            /** start loader */\r\n            loader.startLoader();\r\n\r\n            /** change browser url */\r\n            if (typeof window.history.pushState === 'function' && (typeof isChangeUrl === 'undefined')) {\r\n                window.history.pushState({url: submitUrl}, '', submitUrl);\r\n            }\r\n            if (method === 'post') {// For 'add to wishlist' & 'add to compare' event\r\n                return storage.post(submitUrl).done(\r\n                ).fail(\r\n                    function () {\r\n                        window.location.reload();\r\n                    }\r\n                ).always(function () {\r\n                    loader.stopLoader();\r\n                });\r\n            }\r\n\r\n            return storage.get(submitUrl).done(\r\n                function (response) {\r\n                    if (response.backUrl) {\r\n                        window.location = response.backUrl;\r\n                        return;\r\n                    }\r\n                    if (response.navigation) {\r\n                        layerContainer.html(response.navigation);\r\n                    }\r\n                    if (response.products) {\r\n                        productContainer.html(response.products);\r\n                    }\r\n                    if (response.quickview) {\r\n                        quickViewContainer.html(response.quickview);\r\n                    }\r\n\r\n                    ko.cleanNode(productContainer[0]);\r\n                    productContainer.applyBindings();\r\n\r\n                    if (mage) {\r\n                        $(\"html, body\").animate({scrollTop: $('#layer-product-list').offset().top - 100}, \"slow\");\r\n                        mage.apply();\r\n                    }\r\n                }\r\n            ).fail(\r\n                function () {\r\n                    window.location.reload();\r\n                }\r\n            ).always(\r\n                function () {\r\n\r\n                    var colorAttr = $('.filter-options .filter-options-item .color .swatch-option-link-layered .swatch-option');\r\n\r\n                    colorAttr.each(function(){\r\n                        var el  = $(this),\r\n                            hex = el.attr('data-option-tooltip-value');\r\n                        if(typeof hex != \"undefined\"){\r\n                            if (hex.charAt(0) === '#') {\r\n                                hex = hex.substr(1);\r\n                            }\r\n                            if ((hex.length < 2) || (hex.length > 6)) {\r\n                                el.attr('style','background: '+el.attr('data-option-label')+';');\r\n                            }\r\n                            var values = hex.split(''),\r\n                                r,\r\n                                g,\r\n                                b;\r\n\r\n                            if (hex.length === 2) {\r\n                                r = parseInt(values[0].toString() + values[1].toString(), 16);\r\n                                g = r;\r\n                                b = r;\r\n                            } else if (hex.length === 3) {\r\n                                r = parseInt(values[0].toString() + values[0].toString(), 16);\r\n                                g = parseInt(values[1].toString() + values[1].toString(), 16);\r\n                                b = parseInt(values[2].toString() + values[2].toString(), 16);\r\n                            } else if (hex.length === 6) {\r\n                                r = parseInt(values[0].toString() + values[1].toString(), 16);\r\n                                g = parseInt(values[2].toString() + values[3].toString(), 16);\r\n                                b = parseInt(values[4].toString() + values[5].toString(), 16);\r\n                            } else {\r\n                                el.attr('style','background: '+el.attr('data-option-label')+';');\r\n                            }\r\n\r\n                            el.attr('style','background: center center no-repeat rgb('+[r, g, b]+');');\r\n                        }\r\n\r\n                    });\r\n\r\n                    //selected\r\n\r\n                    var filterCurrent = $('.layered-filter-block-container .filter-current .items .item .filter-value');\r\n\r\n                    filterCurrent.each(function(){\r\n                        var el         = $(this),\r\n                            colorLabel = el.html(),\r\n                            colorAttr  = $('.filter-options .filter-options-item .color .swatch-option-link-layered .swatch-option');\r\n\r\n                        colorAttr.each(function(){\r\n                            var elA = $(this);\r\n                            if(elA.attr('data-option-label') === colorLabel && !elA.hasClass('selected')){\r\n                                elA.addClass('selected');\r\n                            }\r\n                        });\r\n                    });\r\n\r\n                    loader.stopLoader();\r\n                }\r\n            );\r\n        };\r\n    }\r\n);\r\n","Mageplaza_AjaxLayer/js/model/loader.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_AjaxLayer\r\n * @copyright   Copyright (c) Mageplaza (http://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\n\r\ndefine(['jquery'], function ($) {\r\n        'use strict';\r\n\r\n        return {\r\n            /**\r\n             * Start full page loader action\r\n             */\r\n            startLoader: function () {\r\n                $('.sidebar-overlay').click();\r\n                $('.ln_overlay').show();\r\n            },\r\n\r\n            /**\r\n             * Stop full page loader action\r\n             */\r\n            stopLoader: function () {\r\n                $('.ln_overlay').hide();\r\n                $('.swatch-option-tooltip').hide();\r\n            }\r\n        };\r\n    }\r\n);\r\n","js-cookie/cookie-wrapper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'js-cookie/js.cookie'\n], function ($, cookie) {\n    'use strict';\n\n    window.Cookies = window.Cookies || cookie;\n\n    var config = $.cookie = function (key, value, options) {\n        if (value !== undefined) {\n            options = $.extend({}, config.defaults, options);\n\n            return cookie.set(key, value, options);\n        }\n\n        var result = key ? undefined : {},\n            cookies = document.cookie ? document.cookie.split('; ') : [],\n            i;\n\n        for (i = 0; i < cookies.length; i++) {\n            var parts = cookies[i].split('='),\n                name = config.raw ? parts.shift() : decodeURIComponent(parts.shift()),\n                cookieValue = parts.join('=');\n\n            if (key && key === name) {\n                result = decodeURIComponent(cookieValue.replace('/\\\\+/g', ' '));\n                break;\n            }\n\n            if (!key && (cookieValue = decodeURIComponent(cookieValue.replace('/\\\\+/g', ' '))) !== undefined) {\n                result[name] = cookieValue;\n            }\n        }\n\n        return result;\n    };\n\n    config.defaults = {};\n\n    $.removeCookie = function (key, options) {\n        if ($.cookie(key) === undefined) {\n            return false;\n        }\n\n        $.cookie(key, '', $.extend({}, options, { expires: -1 }));\n        return !$.cookie(key);\n    };\n});\n","js-cookie/js.cookie.js":"/*! js-cookie v3.0.1 | MIT */\n;\n(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n        typeof define === 'function' && define.amd ? define(factory) :\n            (global = global || self, (function () {\n                var current = global.Cookies;\n                var exports = global.Cookies = factory();\n                exports.noConflict = function () { global.Cookies = current; return exports; };\n            }()));\n}(this, (function () { 'use strict';\n\n    /* eslint-disable no-var */\n    function assign (target) {\n        for (var i = 1; i < arguments.length; i++) {\n            var source = arguments[i];\n            for (var key in source) {\n                target[key] = source[key];\n            }\n        }\n        return target\n    }\n    /* eslint-enable no-var */\n\n    /* eslint-disable no-var */\n    var defaultConverter = {\n        read: function (value) {\n            if (value[0] === '\"') {\n                value = value.slice(1, -1);\n            }\n            return value.replace(/(%[\\dA-F]{2})+/gi, decodeURIComponent)\n        },\n        write: function (value) {\n            return encodeURIComponent(value).replace(\n                /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,\n                decodeURIComponent\n            )\n        }\n    };\n    /* eslint-enable no-var */\n\n    /* eslint-disable no-var */\n\n    function init (converter, defaultAttributes) {\n        function set (key, value, attributes) {\n            if (typeof document === 'undefined') {\n                return\n            }\n\n            attributes = assign({}, defaultAttributes, attributes);\n\n            if (typeof attributes.expires === 'number') {\n                attributes.expires = new Date(Date.now() + attributes.expires * 864e5);\n            }\n            if (attributes.expires) {\n                attributes.expires = attributes.expires.toUTCString();\n            }\n\n            key = encodeURIComponent(key)\n                .replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)\n                .replace(/[()]/g, escape);\n\n            var stringifiedAttributes = '';\n            for (var attributeName in attributes) {\n                if (!attributes[attributeName]) {\n                    continue\n                }\n\n                stringifiedAttributes += '; ' + attributeName;\n\n                if (attributes[attributeName] === true) {\n                    continue\n                }\n\n                // Considers RFC 6265 section 5.2:\n                // ...\n                // 3.  If the remaining unparsed-attributes contains a %x3B (\";\")\n                //     character:\n                // Consume the characters of the unparsed-attributes up to,\n                // not including, the first %x3B (\";\") character.\n                // ...\n                stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];\n            }\n\n            return (document.cookie =\n                key + '=' + converter.write(value, key) + stringifiedAttributes)\n        }\n\n        function get (key) {\n            if (typeof document === 'undefined' || (arguments.length && !key)) {\n                return\n            }\n\n            // To prevent the for loop in the first place assign an empty array\n            // in case there are no cookies at all.\n            var cookies = document.cookie ? document.cookie.split('; ') : [];\n            var jar = {};\n            for (var i = 0; i < cookies.length; i++) {\n                var parts = cookies[i].split('=');\n                var value = parts.slice(1).join('=');\n\n                try {\n                    var foundKey = decodeURIComponent(parts[0]);\n                    jar[foundKey] = converter.read(value, foundKey);\n\n                    if (key === foundKey) {\n                        break\n                    }\n                } catch (e) {}\n            }\n\n            return key ? jar[key] : jar\n        }\n\n        return Object.create(\n            {\n                set: set,\n                get: get,\n                remove: function (key, attributes) {\n                    set(\n                        key,\n                        '',\n                        assign({}, attributes, {\n                            expires: -1\n                        })\n                    );\n                },\n                withAttributes: function (attributes) {\n                    return init(this.converter, assign({}, this.attributes, attributes))\n                },\n                withConverter: function (converter) {\n                    return init(assign({}, this.converter, converter), this.attributes)\n                }\n            },\n            {\n                attributes: { value: Object.freeze(defaultAttributes) },\n                converter: { value: Object.freeze(converter) }\n            }\n        )\n    }\n\n    var api = init(defaultConverter, { path: '/' });\n    /* eslint-enable no-var */\n\n    return api;\n\n})));\n","Smartwave_Porto/js/jquery.bridget.js":"/**\n * Bridget makes jQuery widgets\n * v1.0.1\n */\n\n( function( window ) {\n\n'use strict';\n\n// -------------------------- utils -------------------------- //\n\nvar slice = Array.prototype.slice;\n\nfunction noop() {}\n\n// -------------------------- definition -------------------------- //\n\nfunction defineBridget( $ ) {\n\n// bail if no jQuery\nif ( !$ ) {\n  return;\n}\n\n// -------------------------- addOptionMethod -------------------------- //\n\n/**\n * adds option method -> $().plugin('option', {...})\n * @param {Function} PluginClass - constructor class\n */\nfunction addOptionMethod( PluginClass ) {\n  // don't overwrite original option method\n  if(typeof PluginClass === \"function\"){\n      if ( PluginClass.prototype.option ) {\n        return;\n      }\n\n      // option setter\n      PluginClass.prototype.option = function( opts ) {\n        // bail out if not an object\n        if ( !$.isPlainObject( opts ) ){\n          return;\n        }\n        this.options = $.extend( true, this.options, opts );\n      };\n  } else {\n      return;\n  }\n}\n\n\n// -------------------------- plugin bridge -------------------------- //\n\n// helper function for logging errors\n// $.error breaks jQuery chaining\nvar logError = typeof console === 'undefined' ? noop :\n  function( message ) {\n    console.error( message );\n  };\n\n/**\n * jQuery plugin bridge, access methods like $elem.plugin('method')\n * @param {String} namespace - plugin name\n * @param {Function} PluginClass - constructor class\n */\nfunction bridge( namespace, PluginClass ) {\n  // add to jQuery fn namespace\n  $.fn[ namespace ] = function( options ) {\n    if ( typeof options === 'string' ) {\n      // call plugin method when first argument is a string\n      // get arguments for method\n      var args = slice.call( arguments, 1 );\n\n      for ( var i=0, len = this.length; i < len; i++ ) {\n        var elem = this[i];\n        var instance = $.data( elem, namespace );\n        if ( !instance ) {\n          logError( \"cannot call methods on \" + namespace + \" prior to initialization; \" +\n            \"attempted to call '\" + options + \"'\" );\n          continue;\n        }\n        if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) {\n          logError( \"no such method '\" + options + \"' for \" + namespace + \" instance\" );\n          continue;\n        }\n\n        // trigger method with arguments\n        var returnValue = instance[ options ].apply( instance, args );\n\n        // break look and return first value if provided\n        if ( returnValue !== undefined ) {\n          return returnValue;\n        }\n      }\n      // return this if no return value\n      return this;\n    } else {\n      return this.each( function() {\n        var instance = $.data( this, namespace );\n        if ( instance ) {\n          // apply options & init\n          instance.option( options );\n          instance._init();\n        } else {\n          // initialize new instance\n          instance = new PluginClass( this, options );\n          $.data( this, namespace, instance );\n        }\n      });\n    }\n  };\n\n}\n\n// -------------------------- bridget -------------------------- //\n\n/**\n * converts a Prototypical class into a proper jQuery plugin\n *   the class must have a ._init method\n * @param {String} namespace - plugin name, used in $().pluginName\n * @param {Function} PluginClass - constructor class\n */\n$.bridget = function( namespace, PluginClass ) {\n  addOptionMethod( PluginClass );\n  bridge( namespace, PluginClass );\n};\n\nreturn $.bridget;\n\n}\n\n// transport\nif ( typeof define === 'function' && define.amd ) {\n  // AMD\n  define( [ 'jquery' ], defineBridget );\n} else {\n  // get jquery from browser global\n  defineBridget( window.jQuery );\n}\n\n})( window );\n","Smartwave_Porto/js/ev-emitter.js":"/**\n * EvEmitter v1.0.1\n * Lil' event emitter\n * MIT License\n */\n\n/* jshint unused: true, undef: true, strict: true */\n\n( function( global, factory ) {\n  // universal module definition\n  /* jshint strict: false */ /* globals define, module */\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD - RequireJS\n    define( factory );\n  } else if ( typeof module == 'object' && module.exports ) {\n    // CommonJS - Browserify, Webpack\n    module.exports = factory();\n  } else {\n    // Browser globals\n    global.EvEmitter = factory();\n  }\n\n}( this, function() {\n\n\"use strict\";\n\nfunction EvEmitter() {}\n\nvar proto = EvEmitter.prototype;\n\nproto.on = function( eventName, listener ) {\n  if ( !eventName || !listener ) {\n    return;\n  }\n  // set events hash\n  var events = this._events = this._events || {};\n  // set listeners array\n  var listeners = events[ eventName ] = events[ eventName ] || [];\n  // only add once\n  if ( listeners.indexOf( listener ) == -1 ) {\n    listeners.push( listener );\n  }\n\n  return this;\n};\n\nproto.once = function( eventName, listener ) {\n  if ( !eventName || !listener ) {\n    return;\n  }\n  // add event\n  this.on( eventName, listener );\n  // set once flag\n  // set onceEvents hash\n  var onceEvents = this._onceEvents = this._onceEvents || {};\n  // set onceListeners array\n  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || [];\n  // set flag\n  onceListeners[ listener ] = true;\n\n  return this;\n};\n\nproto.off = function( eventName, listener ) {\n  var listeners = this._events && this._events[ eventName ];\n  if ( !listeners || !listeners.length ) {\n    return;\n  }\n  var index = listeners.indexOf( listener );\n  if ( index != -1 ) {\n    listeners.splice( index, 1 );\n  }\n\n  return this;\n};\n\nproto.emitEvent = function( eventName, args ) {\n  var listeners = this._events && this._events[ eventName ];\n  if ( !listeners || !listeners.length ) {\n    return;\n  }\n  var i = 0;\n  var listener = listeners[i];\n  args = args || [];\n  // once stuff\n  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];\n\n  while ( listener ) {\n    var isOnce = onceListeners && onceListeners[ listener ];\n    if ( isOnce ) {\n      // remove listener\n      // remove before trigger to prevent recursion\n      this.off( eventName, listener );\n      // unset once flag\n      delete onceListeners[ listener ];\n    }\n    // trigger listener\n    listener.apply( this, args );\n    // get next listener\n    i += isOnce ? 0 : 1;\n    listener = listeners[i];\n  }\n\n  return this;\n};\n\nreturn EvEmitter;\n\n}));\n","Smartwave_Porto/js/apear.js":"/**\n *\n * Do not edit or add to this file if you wish to upgrade this extension to newer\n * version in the future.\n *\n */\nwindow.theme = {};\ndefine([\n    'jquery'\n], function ($) {\n    \"use strict\";\n    theme = theme || {};\n\n    var checks = [],\n      timerId = false,\n      one,\n      a, b, o, x, y, ax, ay,\n      retryCounter = 0,\n      has_event = false;\n\n    var checkAll = function() {\n      if (!checks.length) {\n        if (retryCounter > 10) {\n          window.removeEventListener('scroll', checkAll);\n          window.removeEventListener('resize', checkAll);\n        }\n        retryCounter++;\n      } else {\n        for ( var i = checks.length; i--; ) {\n          one = checks[i];\n          a = window.pageXOffset;\n          b = window.pageYOffset;\n          o = one.el.getBoundingClientRect();\n          x = o.left + a;\n          y = o.top + b;\n          ax = one.options.accX;\n          ay = one.options.accY;\n\n          if (y + o.height + ay >= b &&\n            y <= b + window.innerHeight + ay &&\n            x + o.width + ax >= a &&\n            x <= a + window.innerWidth + ax) {\n\n            one.fn.call(one.el, one.data);\n            checks.splice(i, 1);\n          }\n        }\n      }\n      timerId = false;\n    };\n\n    window.theme.appear = function(el, fn, options) {\n      var settings = {\n        data: undefined,\n        accX: 0,\n        accY: 0\n      };\n\n      if ( options ) {\n        options.data && ( settings.data = options.data );\n        options.accX && ( settings.accX = options.accX );\n        options.accY && ( settings.accY = options.accY );\n      }\n\n      checks.push({ el: el, fn: fn, options: settings });\n      if ( ! timerId ) {\n        timerId = theme.requestTimeout(checkAll, 100);\n      }\n\n      if ( ! has_event ) {\n        $( document.body ).on( 'appear_refresh', checkAll );\n        window.addEventListener('scroll', checkAll, {passive: true});\n        window.addEventListener('resize', checkAll);\n        has_event = true;\n      }\n    }\n});\n","Smartwave_Porto/js/packery.pkgd.js":"/*!\n * Packery PACKAGED v1.4.3\n * bin-packing layout library\n *\n * Licensed GPLv3 for open source use\n * or Flickity Commercial License for commercial use\n *\n * http://packery.metafizzy.co\n * Copyright 2015 Metafizzy\n */\n\n/**\n * Bridget makes jQuery widgets\n * v1.1.0\n * MIT license\n */\n\n( function( window ) {\n\n\n\n// -------------------------- utils -------------------------- //\n\nvar slice = Array.prototype.slice;\n\nfunction noop() {}\n\n// -------------------------- definition -------------------------- //\n\nfunction defineBridget( $ ) {\n\n// bail if no jQuery\nif ( !$ ) {\n  return;\n}\n\n// -------------------------- addOptionMethod -------------------------- //\n\n/**\n * adds option method -> $().plugin('option', {...})\n * @param {Function} PluginClass - constructor class\n */\nfunction addOptionMethod( PluginClass ) {\n  // don't overwrite original option method\n  if ( PluginClass.prototype.option ) {\n    return;\n  }\n\n  // option setter\n  PluginClass.prototype.option = function( opts ) {\n    // bail out if not an object\n    if ( !$.isPlainObject( opts ) ){\n      return;\n    }\n    this.options = $.extend( true, this.options, opts );\n  };\n}\n\n// -------------------------- plugin bridge -------------------------- //\n\n// helper function for logging errors\n// $.error breaks jQuery chaining\nvar logError = typeof console === 'undefined' ? noop :\n  function( message ) {\n    console.error( message );\n  };\n\n/**\n * jQuery plugin bridge, access methods like $elem.plugin('method')\n * @param {String} namespace - plugin name\n * @param {Function} PluginClass - constructor class\n */\nfunction bridge( namespace, PluginClass ) {\n  // add to jQuery fn namespace\n  $.fn[ namespace ] = function( options ) {\n    if ( typeof options === 'string' ) {\n      // call plugin method when first argument is a string\n      // get arguments for method\n      var args = slice.call( arguments, 1 );\n\n      for ( var i=0, len = this.length; i < len; i++ ) {\n        var elem = this[i];\n        var instance = $.data( elem, namespace );\n        if ( !instance ) {\n          logError( \"cannot call methods on \" + namespace + \" prior to initialization; \" +\n            \"attempted to call '\" + options + \"'\" );\n          continue;\n        }\n        if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) {\n          logError( \"no such method '\" + options + \"' for \" + namespace + \" instance\" );\n          continue;\n        }\n\n        // trigger method with arguments\n        var returnValue = instance[ options ].apply( instance, args );\n\n        // break look and return first value if provided\n        if ( returnValue !== undefined ) {\n          return returnValue;\n        }\n      }\n      // return this if no return value\n      return this;\n    } else {\n      return this.each( function() {\n        var instance = $.data( this, namespace );\n        if ( instance ) {\n          // apply options & init\n          instance.option( options );\n          instance._init();\n        } else {\n          // initialize new instance\n          instance = new PluginClass( this, options );\n          $.data( this, namespace, instance );\n        }\n      });\n    }\n  };\n\n}\n\n// -------------------------- bridget -------------------------- //\n\n/**\n * converts a Prototypical class into a proper jQuery plugin\n *   the class must have a ._init method\n * @param {String} namespace - plugin name, used in $().pluginName\n * @param {Function} PluginClass - constructor class\n */\n$.bridget = function( namespace, PluginClass ) {\n  addOptionMethod( PluginClass );\n  bridge( namespace, PluginClass );\n};\n\nreturn $.bridget;\n\n}\n\n// transport\nif ( typeof define === 'function' && define.amd ) {\n  // AMD\n  define( 'jquery-bridget/jquery.bridget',[ 'jquery' ], defineBridget );\n} else if ( typeof exports === 'object' ) {\n  defineBridget( require('jquery') );\n} else {\n  // get jquery from browser global\n  defineBridget( window.jQuery );\n}\ndefineBridget( window.jQuery );\n})( window );\n\n/*!\n * classie v1.0.1\n * class helper functions\n * from bonzo https://github.com/ded/bonzo\n * MIT license\n * \n * classie.has( elem, 'my-class' ) -> true/false\n * classie.add( elem, 'my-new-class' )\n * classie.remove( elem, 'my-unwanted-class' )\n * classie.toggle( elem, 'my-class' )\n */\n\n/*jshint browser: true, strict: true, undef: true, unused: true */\n/*global define: false, module: false */\n\n( function( window ) {\n\n\n\n// class helper functions from bonzo https://github.com/ded/bonzo\n\nfunction classReg( className ) {\n  return new RegExp(\"(^|\\\\s+)\" + className + \"(\\\\s+|$)\");\n}\n\n// classList support for class management\n// altho to be fair, the api sucks because it won't accept multiple classes at once\nvar hasClass, addClass, removeClass;\n\nif ( 'classList' in document.documentElement ) {\n  hasClass = function( elem, c ) {\n    return elem.classList.contains( c );\n  };\n  addClass = function( elem, c ) {\n    elem.classList.add( c );\n  };\n  removeClass = function( elem, c ) {\n    elem.classList.remove( c );\n  };\n}\nelse {\n  hasClass = function( elem, c ) {\n    return classReg( c ).test( elem.className );\n  };\n  addClass = function( elem, c ) {\n    if ( !hasClass( elem, c ) ) {\n      elem.className = elem.className + ' ' + c;\n    }\n  };\n  removeClass = function( elem, c ) {\n    elem.className = elem.className.replace( classReg( c ), ' ' );\n  };\n}\n\nfunction toggleClass( elem, c ) {\n  var fn = hasClass( elem, c ) ? removeClass : addClass;\n  fn( elem, c );\n}\n\nvar classie = {\n  // full names\n  hasClass: hasClass,\n  addClass: addClass,\n  removeClass: removeClass,\n  toggleClass: toggleClass,\n  // short names\n  has: hasClass,\n  add: addClass,\n  remove: removeClass,\n  toggle: toggleClass\n};\n\n// transport\nif ( typeof define === 'function' && define.amd ) {\n  // AMD\n  define( 'classie/classie',classie );\n} else if ( typeof exports === 'object' ) {\n  // CommonJS\n  module.exports = classie;\n} else {\n  // browser global\n  window.classie = classie;\n}\n\n})( window );\n\n/*!\n * getStyleProperty v1.0.4\n * original by kangax\n * http://perfectionkills.com/feature-testing-css-properties/\n * MIT license\n */\n\n/*jshint browser: true, strict: true, undef: true */\n/*global define: false, exports: false, module: false */\n\n( function( window ) {\n\n\n\nvar prefixes = 'Webkit Moz ms Ms O'.split(' ');\nvar docElemStyle = document.documentElement.style;\n\nfunction getStyleProperty( propName ) {\n  if ( !propName ) {\n    return;\n  }\n\n  // test standard property first\n  if ( typeof docElemStyle[ propName ] === 'string' ) {\n    return propName;\n  }\n\n  // capitalize\n  propName = propName.charAt(0).toUpperCase() + propName.slice(1);\n\n  // test vendor specific properties\n  var prefixed;\n  for ( var i=0, len = prefixes.length; i < len; i++ ) {\n    prefixed = prefixes[i] + propName;\n    if ( typeof docElemStyle[ prefixed ] === 'string' ) {\n      return prefixed;\n    }\n  }\n}\n\n// transport\nif ( typeof define === 'function' && define.amd ) {\n  // AMD\n  define( 'get-style-property/get-style-property',[],function() {\n    return getStyleProperty;\n  });\n} else if ( typeof exports === 'object' ) {\n  // CommonJS for Component\n  module.exports = getStyleProperty;\n} else {\n  // browser global\n  window.getStyleProperty = getStyleProperty;\n}\n\n})( window );\n\n/*!\n * getSize v1.2.2\n * measure size of elements\n * MIT license\n */\n\n/*jshint browser: true, strict: true, undef: true, unused: true */\n/*global define: false, exports: false, require: false, module: false, console: false */\n\n( function( window, undefined ) {\n\n\n\n// -------------------------- helpers -------------------------- //\n\n// get a number from a string, not a percentage\nfunction getStyleSize( value ) {\n  var num = parseFloat( value );\n  // not a percent like '100%', and a number\n  var isValid = value.indexOf('%') === -1 && !isNaN( num );\n  return isValid && num;\n}\n\nfunction noop() {}\n\nvar logError = typeof console === 'undefined' ? noop :\n  function( message ) {\n    console.error( message );\n  };\n\n// -------------------------- measurements -------------------------- //\n\nvar measurements = [\n  'paddingLeft',\n  'paddingRight',\n  'paddingTop',\n  'paddingBottom',\n  'marginLeft',\n  'marginRight',\n  'marginTop',\n  'marginBottom',\n  'borderLeftWidth',\n  'borderRightWidth',\n  'borderTopWidth',\n  'borderBottomWidth'\n];\n\nfunction getZeroSize() {\n  var size = {\n    width: 0,\n    height: 0,\n    innerWidth: 0,\n    innerHeight: 0,\n    outerWidth: 0,\n    outerHeight: 0\n  };\n  for ( var i=0, len = measurements.length; i < len; i++ ) {\n    var measurement = measurements[i];\n    size[ measurement ] = 0;\n  }\n  return size;\n}\n\n\n\nfunction defineGetSize( getStyleProperty ) {\n\n// -------------------------- setup -------------------------- //\n\nvar isSetup = false;\n\nvar getStyle, boxSizingProp, isBoxSizeOuter;\n\n/**\n * setup vars and functions\n * do it on initial getSize(), rather than on script load\n * For Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=548397\n */\nfunction setup() {\n  // setup once\n  if ( isSetup ) {\n    return;\n  }\n  isSetup = true;\n\n  var getComputedStyle = window.getComputedStyle;\n  getStyle = ( function() {\n    var getStyleFn = getComputedStyle ?\n      function( elem ) {\n        return getComputedStyle( elem, null );\n      } :\n      function( elem ) {\n        return elem.currentStyle;\n      };\n\n      return function getStyle( elem ) {\n        var style = getStyleFn( elem );\n        if ( !style ) {\n          logError( 'Style returned ' + style +\n            '. Are you running this code in a hidden iframe on Firefox? ' +\n            'See http://bit.ly/getsizebug1' );\n        }\n        return style;\n      };\n  })();\n\n  // -------------------------- box sizing -------------------------- //\n\n  boxSizingProp = getStyleProperty('boxSizing');\n\n  /**\n   * WebKit measures the outer-width on style.width on border-box elems\n   * IE & Firefox measures the inner-width\n   */\n  if ( boxSizingProp ) {\n    var div = document.createElement('div');\n    div.style.width = '200px';\n    div.style.padding = '1px 2px 3px 4px';\n    div.style.borderStyle = 'solid';\n    div.style.borderWidth = '1px 2px 3px 4px';\n    div.style[ boxSizingProp ] = 'border-box';\n\n    var body = document.body || document.documentElement;\n    body.appendChild( div );\n    var style = getStyle( div );\n\n    isBoxSizeOuter = getStyleSize( style.width ) === 200;\n    body.removeChild( div );\n  }\n\n}\n\n// -------------------------- getSize -------------------------- //\n\nfunction getSize( elem ) {\n  setup();\n\n  // use querySeletor if elem is string\n  if ( typeof elem === 'string' ) {\n    elem = document.querySelector( elem );\n  }\n\n  // do not proceed on non-objects\n  if ( !elem || typeof elem !== 'object' || !elem.nodeType ) {\n    return;\n  }\n\n  var style = getStyle( elem );\n\n  // if hidden, everything is 0\n  if ( style.display === 'none' ) {\n    return getZeroSize();\n  }\n\n  var size = {};\n  size.width = elem.offsetWidth;\n  size.height = elem.offsetHeight;\n\n  var isBorderBox = size.isBorderBox = !!( boxSizingProp &&\n    style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' );\n\n  // get all measurements\n  for ( var i=0, len = measurements.length; i < len; i++ ) {\n    var measurement = measurements[i];\n    var value = style[ measurement ];\n    value = mungeNonPixel( elem, value );\n    var num = parseFloat( value );\n    // any 'auto', 'medium' value will be 0\n    size[ measurement ] = !isNaN( num ) ? num : 0;\n  }\n\n  var paddingWidth = size.paddingLeft + size.paddingRight;\n  var paddingHeight = size.paddingTop + size.paddingBottom;\n  var marginWidth = size.marginLeft + size.marginRight;\n  var marginHeight = size.marginTop + size.marginBottom;\n  var borderWidth = size.borderLeftWidth + size.borderRightWidth;\n  var borderHeight = size.borderTopWidth + size.borderBottomWidth;\n\n  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;\n\n  // overwrite width and height if we can get it from style\n  var styleWidth = getStyleSize( style.width );\n  if ( styleWidth !== false ) {\n    size.width = styleWidth +\n      // add padding and border unless it's already including it\n      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );\n  }\n\n  var styleHeight = getStyleSize( style.height );\n  if ( styleHeight !== false ) {\n    size.height = styleHeight +\n      // add padding and border unless it's already including it\n      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );\n  }\n\n  size.innerWidth = size.width - ( paddingWidth + borderWidth );\n  size.innerHeight = size.height - ( paddingHeight + borderHeight );\n\n  size.outerWidth = size.width + marginWidth;\n  size.outerHeight = size.height + marginHeight;\n\n  return size;\n}\n\n// IE8 returns percent values, not pixels\n// taken from jQuery's curCSS\nfunction mungeNonPixel( elem, value ) {\n  // IE8 and has percent value\n  if ( window.getComputedStyle || value.indexOf('%') === -1 ) {\n    return value;\n  }\n  var style = elem.style;\n  // Remember the original values\n  var left = style.left;\n  var rs = elem.runtimeStyle;\n  var rsLeft = rs && rs.left;\n\n  // Put in the new values to get a computed value out\n  if ( rsLeft ) {\n    rs.left = elem.currentStyle.left;\n  }\n  style.left = value;\n  value = style.pixelLeft;\n\n  // Revert the changed values\n  style.left = left;\n  if ( rsLeft ) {\n    rs.left = rsLeft;\n  }\n\n  return value;\n}\n\nreturn getSize;\n\n}\n\n// transport\nif ( typeof define === 'function' && define.amd ) {\n  // AMD for RequireJS\n  define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize );\n} else if ( typeof exports === 'object' ) {\n  // CommonJS for Component\n  module.exports = defineGetSize( require('desandro-get-style-property') );\n} else {\n  // browser global\n  window.getSize = defineGetSize( window.getStyleProperty );\n}\n\n})( window );\n\n/*!\n * eventie v1.0.6\n * event binding helper\n *   eventie.bind( elem, 'click', myFn )\n *   eventie.unbind( elem, 'click', myFn )\n * MIT license\n */\n\n/*jshint browser: true, undef: true, unused: true */\n/*global define: false, module: false */\n\n( function( window ) {\n\n\n\nvar docElem = document.documentElement;\n\nvar bind = function() {};\n\nfunction getIEEvent( obj ) {\n  var event = window.event;\n  // add event.target\n  event.target = event.target || event.srcElement || obj;\n  return event;\n}\n\nif ( docElem.addEventListener ) {\n  bind = function( obj, type, fn ) {\n    obj.addEventListener( type, fn, false );\n  };\n} else if ( docElem.attachEvent ) {\n  bind = function( obj, type, fn ) {\n    obj[ type + fn ] = fn.handleEvent ?\n      function() {\n        var event = getIEEvent( obj );\n        fn.handleEvent.call( fn, event );\n      } :\n      function() {\n        var event = getIEEvent( obj );\n        fn.call( obj, event );\n      };\n    obj.attachEvent( \"on\" + type, obj[ type + fn ] );\n  };\n}\n\nvar unbind = function() {};\n\nif ( docElem.removeEventListener ) {\n  unbind = function( obj, type, fn ) {\n    obj.removeEventListener( type, fn, false );\n  };\n} else if ( docElem.detachEvent ) {\n  unbind = function( obj, type, fn ) {\n    obj.detachEvent( \"on\" + type, obj[ type + fn ] );\n    try {\n      delete obj[ type + fn ];\n    } catch ( err ) {\n      // can't delete window object properties\n      obj[ type + fn ] = undefined;\n    }\n  };\n}\n\nvar eventie = {\n  bind: bind,\n  unbind: unbind\n};\n\n// ----- module definition ----- //\n\nif ( typeof define === 'function' && define.amd ) {\n  // AMD\n  define( 'eventie/eventie',eventie );\n} else if ( typeof exports === 'object' ) {\n  // CommonJS\n  module.exports = eventie;\n} else {\n  // browser global\n  window.eventie = eventie;\n}\nwindow.eventie = eventie;\n})( window );\n\n/*!\n * EventEmitter v4.2.11 - git.io/ee\n * Unlicense - http://unlicense.org/\n * Oliver Caldwell - http://oli.me.uk/\n * @preserve\n */\n\n;(function () {\n    \n\n    /**\n     * Class for managing events.\n     * Can be extended to provide event functionality in other classes.\n     *\n     * @class EventEmitter Manages event registering and emitting.\n     */\n    function EventEmitter() {}\n\n    // Shortcuts to improve speed and size\n    var proto = EventEmitter.prototype;\n    var exports = this;\n    var originalGlobalValue = exports.EventEmitter;\n\n    /**\n     * Finds the index of the listener for the event in its storage array.\n     *\n     * @param {Function[]} listeners Array of listeners to search through.\n     * @param {Function} listener Method to look for.\n     * @return {Number} Index of the specified listener, -1 if not found\n     * @api private\n     */\n    function indexOfListener(listeners, listener) {\n        var i = listeners.length;\n        while (i--) {\n            if (listeners[i].listener === listener) {\n                return i;\n            }\n        }\n\n        return -1;\n    }\n\n    /**\n     * Alias a method while keeping the context correct, to allow for overwriting of target method.\n     *\n     * @param {String} name The name of the target method.\n     * @return {Function} The aliased method\n     * @api private\n     */\n    function alias(name) {\n        return function aliasClosure() {\n            return this[name].apply(this, arguments);\n        };\n    }\n\n    /**\n     * Returns the listener array for the specified event.\n     * Will initialise the event object and listener arrays if required.\n     * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.\n     * Each property in the object response is an array of listener functions.\n     *\n     * @param {String|RegExp} evt Name of the event to return the listeners from.\n     * @return {Function[]|Object} All listener functions for the event.\n     */\n    proto.getListeners = function getListeners(evt) {\n        var events = this._getEvents();\n        var response;\n        var key;\n\n        // Return a concatenated array of all matching events if\n        // the selector is a regular expression.\n        if (evt instanceof RegExp) {\n            response = {};\n            for (key in events) {\n                if (events.hasOwnProperty(key) && evt.test(key)) {\n                    response[key] = events[key];\n                }\n            }\n        }\n        else {\n            response = events[evt] || (events[evt] = []);\n        }\n\n        return response;\n    };\n\n    /**\n     * Takes a list of listener objects and flattens it into a list of listener functions.\n     *\n     * @param {Object[]} listeners Raw listener objects.\n     * @return {Function[]} Just the listener functions.\n     */\n    proto.flattenListeners = function flattenListeners(listeners) {\n        var flatListeners = [];\n        var i;\n\n        for (i = 0; i < listeners.length; i += 1) {\n            flatListeners.push(listeners[i].listener);\n        }\n\n        return flatListeners;\n    };\n\n    /**\n     * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.\n     *\n     * @param {String|RegExp} evt Name of the event to return the listeners from.\n     * @return {Object} All listener functions for an event in an object.\n     */\n    proto.getListenersAsObject = function getListenersAsObject(evt) {\n        var listeners = this.getListeners(evt);\n        var response;\n\n        if (listeners instanceof Array) {\n            response = {};\n            response[evt] = listeners;\n        }\n\n        return response || listeners;\n    };\n\n    /**\n     * Adds a listener function to the specified event.\n     * The listener will not be added if it is a duplicate.\n     * If the listener returns true then it will be removed after it is called.\n     * If you pass a regular expression as the event name then the listener will be added to all events that match it.\n     *\n     * @param {String|RegExp} evt Name of the event to attach the listener to.\n     * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.addListener = function addListener(evt, listener) {\n        var listeners = this.getListenersAsObject(evt);\n        var listenerIsWrapped = typeof listener === 'object';\n        var key;\n\n        for (key in listeners) {\n            if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {\n                listeners[key].push(listenerIsWrapped ? listener : {\n                    listener: listener,\n                    once: false\n                });\n            }\n        }\n\n        return this;\n    };\n\n    /**\n     * Alias of addListener\n     */\n    proto.on = alias('addListener');\n\n    /**\n     * Semi-alias of addListener. It will add a listener that will be\n     * automatically removed after its first execution.\n     *\n     * @param {String|RegExp} evt Name of the event to attach the listener to.\n     * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.addOnceListener = function addOnceListener(evt, listener) {\n        return this.addListener(evt, {\n            listener: listener,\n            once: true\n        });\n    };\n\n    /**\n     * Alias of addOnceListener.\n     */\n    proto.once = alias('addOnceListener');\n\n    /**\n     * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.\n     * You need to tell it what event names should be matched by a regex.\n     *\n     * @param {String} evt Name of the event to create.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.defineEvent = function defineEvent(evt) {\n        this.getListeners(evt);\n        return this;\n    };\n\n    /**\n     * Uses defineEvent to define multiple events.\n     *\n     * @param {String[]} evts An array of event names to define.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.defineEvents = function defineEvents(evts) {\n        for (var i = 0; i < evts.length; i += 1) {\n            this.defineEvent(evts[i]);\n        }\n        return this;\n    };\n\n    /**\n     * Removes a listener function from the specified event.\n     * When passed a regular expression as the event name, it will remove the listener from all events that match it.\n     *\n     * @param {String|RegExp} evt Name of the event to remove the listener from.\n     * @param {Function} listener Method to remove from the event.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.removeListener = function removeListener(evt, listener) {\n        var listeners = this.getListenersAsObject(evt);\n        var index;\n        var key;\n\n        for (key in listeners) {\n            if (listeners.hasOwnProperty(key)) {\n                index = indexOfListener(listeners[key], listener);\n\n                if (index !== -1) {\n                    listeners[key].splice(index, 1);\n                }\n            }\n        }\n\n        return this;\n    };\n\n    /**\n     * Alias of removeListener\n     */\n    proto.off = alias('removeListener');\n\n    /**\n     * Adds listeners in bulk using the manipulateListeners method.\n     * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.\n     * You can also pass it a regular expression to add the array of listeners to all events that match it.\n     * Yeah, this function does quite a bit. That's probably a bad thing.\n     *\n     * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.\n     * @param {Function[]} [listeners] An optional array of listener functions to add.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.addListeners = function addListeners(evt, listeners) {\n        // Pass through to manipulateListeners\n        return this.manipulateListeners(false, evt, listeners);\n    };\n\n    /**\n     * Removes listeners in bulk using the manipulateListeners method.\n     * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n     * You can also pass it an event name and an array of listeners to be removed.\n     * You can also pass it a regular expression to remove the listeners from all events that match it.\n     *\n     * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.\n     * @param {Function[]} [listeners] An optional array of listener functions to remove.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.removeListeners = function removeListeners(evt, listeners) {\n        // Pass through to manipulateListeners\n        return this.manipulateListeners(true, evt, listeners);\n    };\n\n    /**\n     * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.\n     * The first argument will determine if the listeners are removed (true) or added (false).\n     * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n     * You can also pass it an event name and an array of listeners to be added/removed.\n     * You can also pass it a regular expression to manipulate the listeners of all events that match it.\n     *\n     * @param {Boolean} remove True if you want to remove listeners, false if you want to add.\n     * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.\n     * @param {Function[]} [listeners] An optional array of listener functions to add/remove.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {\n        var i;\n        var value;\n        var single = remove ? this.removeListener : this.addListener;\n        var multiple = remove ? this.removeListeners : this.addListeners;\n\n        // If evt is an object then pass each of its properties to this method\n        if (typeof evt === 'object' && !(evt instanceof RegExp)) {\n            for (i in evt) {\n                if (evt.hasOwnProperty(i) && (value = evt[i])) {\n                    // Pass the single listener straight through to the singular method\n                    if (typeof value === 'function') {\n                        single.call(this, i, value);\n                    }\n                    else {\n                        // Otherwise pass back to the multiple function\n                        multiple.call(this, i, value);\n                    }\n                }\n            }\n        }\n        else {\n            // So evt must be a string\n            // And listeners must be an array of listeners\n            // Loop over it and pass each one to the multiple method\n            i = listeners.length;\n            while (i--) {\n                single.call(this, evt, listeners[i]);\n            }\n        }\n\n        return this;\n    };\n\n    /**\n     * Removes all listeners from a specified event.\n     * If you do not specify an event then all listeners will be removed.\n     * That means every event will be emptied.\n     * You can also pass a regex to remove all events that match it.\n     *\n     * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.removeEvent = function removeEvent(evt) {\n        var type = typeof evt;\n        var events = this._getEvents();\n        var key;\n\n        // Remove different things depending on the state of evt\n        if (type === 'string') {\n            // Remove all listeners for the specified event\n            delete events[evt];\n        }\n        else if (evt instanceof RegExp) {\n            // Remove all events matching the regex.\n            for (key in events) {\n                if (events.hasOwnProperty(key) && evt.test(key)) {\n                    delete events[key];\n                }\n            }\n        }\n        else {\n            // Remove all listeners in all events\n            delete this._events;\n        }\n\n        return this;\n    };\n\n    /**\n     * Alias of removeEvent.\n     *\n     * Added to mirror the node API.\n     */\n    proto.removeAllListeners = alias('removeEvent');\n\n    /**\n     * Emits an event of your choice.\n     * When emitted, every listener attached to that event will be executed.\n     * If you pass the optional argument array then those arguments will be passed to every listener upon execution.\n     * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.\n     * So they will not arrive within the array on the other side, they will be separate.\n     * You can also pass a regular expression to emit to all events that match it.\n     *\n     * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n     * @param {Array} [args] Optional array of arguments to be passed to each listener.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.emitEvent = function emitEvent(evt, args) {\n        var listeners = this.getListenersAsObject(evt);\n        var listener;\n        var i;\n        var key;\n        var response;\n\n        for (key in listeners) {\n            if (listeners.hasOwnProperty(key)) {\n                i = listeners[key].length;\n\n                while (i--) {\n                    // If the listener returns true then it shall be removed from the event\n                    // The function is executed either with a basic call or an apply if there is an args array\n                    listener = listeners[key][i];\n\n                    if (listener.once === true) {\n                        this.removeListener(evt, listener.listener);\n                    }\n\n                    response = listener.listener.apply(this, args || []);\n\n                    if (response === this._getOnceReturnValue()) {\n                        this.removeListener(evt, listener.listener);\n                    }\n                }\n            }\n        }\n\n        return this;\n    };\n\n    /**\n     * Alias of emitEvent\n     */\n    proto.trigger = alias('emitEvent');\n\n    /**\n     * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.\n     * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.\n     *\n     * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n     * @param {...*} Optional additional arguments to be passed to each listener.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.emit = function emit(evt) {\n        var args = Array.prototype.slice.call(arguments, 1);\n        return this.emitEvent(evt, args);\n    };\n\n    /**\n     * Sets the current value to check against when executing listeners. If a\n     * listeners return value matches the one set here then it will be removed\n     * after execution. This value defaults to true.\n     *\n     * @param {*} value The new value to check for when executing listeners.\n     * @return {Object} Current instance of EventEmitter for chaining.\n     */\n    proto.setOnceReturnValue = function setOnceReturnValue(value) {\n        this._onceReturnValue = value;\n        return this;\n    };\n\n    /**\n     * Fetches the current value to check against when executing listeners. If\n     * the listeners return value matches this one then it should be removed\n     * automatically. It will return true by default.\n     *\n     * @return {*|Boolean} The current value to check for or the default, true.\n     * @api private\n     */\n    proto._getOnceReturnValue = function _getOnceReturnValue() {\n        if (this.hasOwnProperty('_onceReturnValue')) {\n            return this._onceReturnValue;\n        }\n        else {\n            return true;\n        }\n    };\n\n    /**\n     * Fetches the events object and creates one if required.\n     *\n     * @return {Object} The events storage object.\n     * @api private\n     */\n    proto._getEvents = function _getEvents() {\n        return this._events || (this._events = {});\n    };\n\n    /**\n     * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.\n     *\n     * @return {Function} Non conflicting EventEmitter class.\n     */\n    EventEmitter.noConflict = function noConflict() {\n        exports.EventEmitter = originalGlobalValue;\n        return EventEmitter;\n    };\n\n    // Expose the class either via AMD, CommonJS or the global object\n    if (typeof define === 'function' && define.amd) {\n        define('eventEmitter/EventEmitter',[],function () {\n            return EventEmitter;\n        });\n    }\n    else if (typeof module === 'object' && module.exports){\n        module.exports = EventEmitter;\n    }\n    else {\n        exports.EventEmitter = EventEmitter;\n    }\n}.call(this));\n\n/*!\n * docReady v1.0.4\n * Cross browser DOMContentLoaded event emitter\n * MIT license\n */\n\n/*jshint browser: true, strict: true, undef: true, unused: true*/\n/*global define: false, require: false, module: false */\n\n( function( window ) {\n\n\n\nvar document = window.document;\n// collection of functions to be triggered on ready\nvar queue = [];\n\nfunction docReady( fn ) {\n  // throw out non-functions\n  if ( typeof fn !== 'function' ) {\n    return;\n  }\n\n  if ( docReady.isReady ) {\n    // ready now, hit it\n    fn();\n  } else {\n    // queue function when ready\n    queue.push( fn );\n  }\n}\n\ndocReady.isReady = false;\n\n// triggered on various doc ready events\nfunction onReady( event ) {\n  // bail if already triggered or IE8 document is not ready just yet\n  var isIE8NotReady = event.type === 'readystatechange' && document.readyState !== 'complete';\n  if ( docReady.isReady || isIE8NotReady ) {\n    return;\n  }\n\n  trigger();\n}\n\nfunction trigger() {\n  docReady.isReady = true;\n  // process queue\n  for ( var i=0, len = queue.length; i < len; i++ ) {\n    var fn = queue[i];\n    fn();\n  }\n}\n\nfunction defineDocReady( eventie ) {\n  // trigger ready if page is ready\n  if ( document.readyState === 'complete' ) {\n    trigger();\n  } else {\n    // listen for events\n    window.eventie.bind( document, 'DOMContentLoaded', onReady );\n    window.eventie.bind( document, 'readystatechange', onReady );\n    window.eventie.bind( window, 'load', onReady );\n  }\n\n  return docReady;\n}\n\n// transport\nif ( typeof define === 'function' && define.amd ) {\n  // AMD\n  define( 'doc-ready/doc-ready',[ 'eventie/eventie' ], defineDocReady );\n} else if ( typeof exports === 'object' ) {\n  module.exports = defineDocReady( require('eventie') );\n} else {\n  // browser global\n  window.docReady = defineDocReady( window.eventie );\n}\n\n})( window );\n\n/**\n * matchesSelector v1.0.3\n * matchesSelector( element, '.selector' )\n * MIT license\n */\n\n/*jshint browser: true, strict: true, undef: true, unused: true */\n/*global define: false, module: false */\n\n( function( ElemProto ) {\n\n  \n\n  var matchesMethod = ( function() {\n    // check for the standard method name first\n    if ( ElemProto.matches ) {\n      return 'matches';\n    }\n    // check un-prefixed\n    if ( ElemProto.matchesSelector ) {\n      return 'matchesSelector';\n    }\n    // check vendor prefixes\n    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];\n\n    for ( var i=0, len = prefixes.length; i < len; i++ ) {\n      var prefix = prefixes[i];\n      var method = prefix + 'MatchesSelector';\n      if ( ElemProto[ method ] ) {\n        return method;\n      }\n    }\n  })();\n\n  // ----- match ----- //\n\n  function match( elem, selector ) {\n    return elem[ matchesMethod ]( selector );\n  }\n\n  // ----- appendToFragment ----- //\n\n  function checkParent( elem ) {\n    // not needed if already has parent\n    if ( elem.parentNode ) {\n      return;\n    }\n    var fragment = document.createDocumentFragment();\n    fragment.appendChild( elem );\n  }\n\n  // ----- query ----- //\n\n  // fall back to using QSA\n  // thx @jonathantneal https://gist.github.com/3062955\n  function query( elem, selector ) {\n    // append to fragment if no parent\n    checkParent( elem );\n\n    // match elem with all selected elems of parent\n    var elems = elem.parentNode.querySelectorAll( selector );\n    for ( var i=0, len = elems.length; i < len; i++ ) {\n      // return true if match\n      if ( elems[i] === elem ) {\n        return true;\n      }\n    }\n    // otherwise return false\n    return false;\n  }\n\n  // ----- matchChild ----- //\n\n  function matchChild( elem, selector ) {\n    checkParent( elem );\n    return match( elem, selector );\n  }\n\n  // ----- matchesSelector ----- //\n\n  var matchesSelector;\n\n  if ( matchesMethod ) {\n    // IE9 supports matchesSelector, but doesn't work on orphaned elems\n    // check for that\n    var div = document.createElement('div');\n    var supportsOrphans = match( div, 'div' );\n    matchesSelector = supportsOrphans ? match : matchChild;\n  } else {\n    matchesSelector = query;\n  }\n\n  // transport\n  if ( typeof define === 'function' && define.amd ) {\n    // AMD\n    define( 'matches-selector/matches-selector',[],function() {\n      return matchesSelector;\n    });\n  } else if ( typeof exports === 'object' ) {\n    module.exports = matchesSelector;\n  }\n  else {\n    // browser global\n    window.matchesSelector = matchesSelector;\n  }\n\n})( Element.prototype );\n\n/**\n * Fizzy UI utils v1.0.1\n * MIT license\n */\n\n/*jshint browser: true, undef: true, unused: true, strict: true */\n\n( function( window, factory ) {\n  /*global define: false, module: false, require: false */\n  \n  // universal module definition\n\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( 'fizzy-ui-utils/utils',[\n      'doc-ready/doc-ready',\n      'matches-selector/matches-selector'\n    ], function( docReady, matchesSelector ) {\n      return factory( window, docReady, matchesSelector );\n    });\n  } else if ( typeof exports == 'object' ) {\n    // CommonJS\n    module.exports = factory(\n      window,\n      require('doc-ready'),\n      require('desandro-matches-selector')\n    );\n  } else {\n    // browser global\n    window.fizzyUIUtils = factory(\n      window,\n      window.docReady,\n      window.matchesSelector\n    );\n  }\n\n}( window, function factory( window, docReady, matchesSelector ) {\n\n\n\nvar utils = {};\n\n// ----- extend ----- //\n\n// extends objects\nutils.extend = function( a, b ) {\n  for ( var prop in b ) {\n    a[ prop ] = b[ prop ];\n  }\n  return a;\n};\n\n// ----- modulo ----- //\n\nutils.modulo = function( num, div ) {\n  return ( ( num % div ) + div ) % div;\n};\n\n// ----- isArray ----- //\n  \nvar objToString = Object.prototype.toString;\nutils.isArray = function( obj ) {\n  return objToString.call( obj ) == '[object Array]';\n};\n\n// ----- makeArray ----- //\n\n// turn element or nodeList into an array\nutils.makeArray = function( obj ) {\n  var ary = [];\n  if ( utils.isArray( obj ) ) {\n    // use object if already an array\n    ary = obj;\n  } else if ( obj && typeof obj.length == 'number' ) {\n    // convert nodeList to array\n    for ( var i=0, len = obj.length; i < len; i++ ) {\n      ary.push( obj[i] );\n    }\n  } else {\n    // array of single index\n    ary.push( obj );\n  }\n  return ary;\n};\n\n// ----- indexOf ----- //\n\n// index of helper cause IE8\nutils.indexOf = Array.prototype.indexOf ? function( ary, obj ) {\n    return ary.indexOf( obj );\n  } : function( ary, obj ) {\n    for ( var i=0, len = ary.length; i < len; i++ ) {\n      if ( ary[i] === obj ) {\n        return i;\n      }\n    }\n    return -1;\n  };\n\n// ----- removeFrom ----- //\n\nutils.removeFrom = function( ary, obj ) {\n  var index = utils.indexOf( ary, obj );\n  if ( index != -1 ) {\n    ary.splice( index, 1 );\n  }\n};\n\n// ----- isElement ----- //\n\n// http://stackoverflow.com/a/384380/182183\nutils.isElement = ( typeof HTMLElement == 'function' || typeof HTMLElement == 'object' ) ?\n  function isElementDOM2( obj ) {\n    return obj instanceof HTMLElement;\n  } :\n  function isElementQuirky( obj ) {\n    return obj && typeof obj == 'object' &&\n      obj.nodeType == 1 && typeof obj.nodeName == 'string';\n  };\n\n// ----- setText ----- //\n\nutils.setText = ( function() {\n  var setTextProperty;\n  function setText( elem, text ) {\n    // only check setTextProperty once\n    setTextProperty = setTextProperty || ( document.documentElement.textContent !== undefined ? 'textContent' : 'innerText' );\n    elem[ setTextProperty ] = text;\n  }\n  return setText;\n})();\n\n// ----- getParent ----- //\n\nutils.getParent = function( elem, selector ) {\n  while ( elem != document.body ) {\n    elem = elem.parentNode;\n    if ( matchesSelector( elem, selector ) ) {\n      return elem;\n    }\n  }\n};\n\n// ----- getQueryElement ----- //\n\n// use element as selector string\nutils.getQueryElement = function( elem ) {\n  if ( typeof elem == 'string' ) {\n    return document.querySelector( elem );\n  }\n  return elem;\n};\n\n// ----- handleEvent ----- //\n\n// enable .ontype to trigger from .addEventListener( elem, 'type' )\nutils.handleEvent = function( event ) {\n  var method = 'on' + event.type;\n  if ( this[ method ] ) {\n    this[ method ]( event );\n  }\n};\n\n// ----- filterFindElements ----- //\n\nutils.filterFindElements = function( elems, selector ) {\n  // make array of elems\n  elems = utils.makeArray( elems );\n  var ffElems = [];\n\n  for ( var i=0, len = elems.length; i < len; i++ ) {\n    var elem = elems[i];\n    // check that elem is an actual element\n    if ( !utils.isElement( elem ) ) {\n      continue;\n    }\n    // filter & find items if we have a selector\n    if ( selector ) {\n      // filter siblings\n      if ( matchesSelector( elem, selector ) ) {\n        ffElems.push( elem );\n      }\n      // find children\n      var childElems = elem.querySelectorAll( selector );\n      // concat childElems to filterFound array\n      for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {\n        ffElems.push( childElems[j] );\n      }\n    } else {\n      ffElems.push( elem );\n    }\n  }\n\n  return ffElems;\n};\n\n// ----- debounceMethod ----- //\n\nutils.debounceMethod = function( _class, methodName, threshold ) {\n  // original method\n  var method = _class.prototype[ methodName ];\n  var timeoutName = methodName + 'Timeout';\n\n  _class.prototype[ methodName ] = function() {\n    var timeout = this[ timeoutName ];\n    if ( timeout ) {\n      clearTimeout( timeout );\n    }\n    var args = arguments;\n\n    var _this = this;\n    this[ timeoutName ] = setTimeout( function() {\n      method.apply( _this, args );\n      delete _this[ timeoutName ];\n    }, threshold || 100 );\n  };\n};\n\n// ----- htmlInit ----- //\n\n// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/\nutils.toDashed = function( str ) {\n  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {\n    return $1 + '-' + $2;\n  }).toLowerCase();\n};\n\nvar console = window.console;\n/**\n * allow user to initialize classes via .js-namespace class\n * htmlInit( Widget, 'widgetName' )\n * options are parsed from data-namespace-option attribute\n */\nutils.htmlInit = function( WidgetClass, namespace ) {\n  docReady( function() {\n    var dashedNamespace = utils.toDashed( namespace );\n    var elems = document.querySelectorAll( '.js-' + dashedNamespace );\n    var dataAttr = 'data-' + dashedNamespace + '-options';\n\n    for ( var i=0, len = elems.length; i < len; i++ ) {\n      var elem = elems[i];\n      var attr = elem.getAttribute( dataAttr );\n      var options;\n      try {\n        options = attr && JSON.parse( attr );\n      } catch ( error ) {\n        // log error, do not initialize\n        if ( console ) {\n          console.error( 'Error parsing ' + dataAttr + ' on ' +\n            elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' +\n            error );\n        }\n        continue;\n      }\n      // initialize\n      var instance = new WidgetClass( elem, options );\n      // make available via $().data('layoutname')\n      var jQuery = window.jQuery;\n      if ( jQuery ) {\n        jQuery.data( elem, namespace, instance );\n      }\n    }\n  });\n};\n\n// -----  ----- //\n\nreturn utils;\n\n}));\n\n/**\n * Outlayer Item\n */\n\n( function( window, factory ) {\n  \n  // universal module definition\n  if ( typeof define === 'function' && define.amd ) {\n    // AMD\n    define( 'outlayer/item',[\n        'eventEmitter/EventEmitter',\n        'get-size/get-size',\n        'get-style-property/get-style-property',\n        'fizzy-ui-utils/utils'\n      ],\n      function( EventEmitter, getSize, getStyleProperty, utils ) {\n        return factory( window, EventEmitter, getSize, getStyleProperty, utils );\n      }\n    );\n  } else if (typeof exports === 'object') {\n    // CommonJS\n    module.exports = factory(\n      window,\n      require('wolfy87-eventemitter'),\n      require('get-size'),\n      require('desandro-get-style-property'),\n      require('fizzy-ui-utils')\n    );\n  } else {\n    // browser global\n    window.Outlayer = {};\n    window.Outlayer.Item = factory(\n      window,\n      window.EventEmitter,\n      window.getSize,\n      window.getStyleProperty,\n      window.fizzyUIUtils\n    );\n  }\n\n}( window, function factory( window, EventEmitter, getSize, getStyleProperty, utils ) {\n\n\n// ----- helpers ----- //\n\nvar getComputedStyle = window.getComputedStyle;\nvar getStyle = getComputedStyle ?\n  function( elem ) {\n    return getComputedStyle( elem, null );\n  } :\n  function( elem ) {\n    return elem.currentStyle;\n  };\n\n\nfunction isEmptyObj( obj ) {\n  for ( var prop in obj ) {\n    return false;\n  }\n  prop = null;\n  return true;\n}\n\n// -------------------------- CSS3 support -------------------------- //\n\nvar transitionProperty = getStyleProperty('transition');\nvar transformProperty = getStyleProperty('transform');\nvar supportsCSS3 = transitionProperty && transformProperty;\nvar is3d = !!getStyleProperty('perspective');\n\nvar transitionEndEvent = {\n  WebkitTransition: 'webkitTransitionEnd',\n  MozTransition: 'transitionend',\n  OTransition: 'otransitionend',\n  transition: 'transitionend'\n}[ transitionProperty ];\n\n// properties that could have vendor prefix\nvar prefixableProperties = [\n  'transform',\n  'transition',\n  'transitionDuration',\n  'transitionProperty'\n];\n\n// cache all vendor properties\nvar vendorProperties = ( function() {\n  var cache = {};\n  for ( var i=0, len = prefixableProperties.length; i < len; i++ ) {\n    var prop = prefixableProperties[i];\n    var supportedProp = getStyleProperty( prop );\n    if ( supportedProp && supportedProp !== prop ) {\n      cache[ prop ] = supportedProp;\n    }\n  }\n  return cache;\n})();\n\n// -------------------------- Item -------------------------- //\n\nfunction Item( element, layout ) {\n  if ( !element ) {\n    return;\n  }\n\n  this.element = element;\n  // parent layout class, i.e. Masonry, Isotope, or Packery\n  this.layout = layout;\n  this.position = {\n    x: 0,\n    y: 0\n  };\n\n  this._create();\n}\n\n// inherit EventEmitter\nutils.extend( Item.prototype, EventEmitter.prototype );\n\nItem.prototype._create = function() {\n  // transition objects\n  this._transn = {\n    ingProperties: {},\n    clean: {},\n    onEnd: {}\n  };\n\n  this.css({\n    position: 'absolute'\n  });\n};\n\n// trigger specified handler for event type\nItem.prototype.handleEvent = function( event ) {\n  var method = 'on' + event.type;\n  if ( this[ method ] ) {\n    this[ method ]( event );\n  }\n};\n\nItem.prototype.getSize = function() {\n  this.size = getSize( this.element );\n};\n\n/**\n * apply CSS styles to element\n * @param {Object} style\n */\nItem.prototype.css = function( style ) {\n  var elemStyle = this.element.style;\n\n  for ( var prop in style ) {\n    // use vendor property if available\n    var supportedProp = vendorProperties[ prop ] || prop;\n    elemStyle[ supportedProp ] = style[ prop ];\n  }\n};\n\n // measure position, and sets it\nItem.prototype.getPosition = function() {\n  var style = getStyle( this.element );\n  var layoutOptions = this.layout.options;\n  var isOriginLeft = layoutOptions.isOriginLeft;\n  var isOriginTop = layoutOptions.isOriginTop;\n  var xValue = style[ isOriginLeft ? 'left' : 'right' ];\n  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];\n  // convert percent to pixels\n  var layoutSize = this.layout.size;\n  var x = xValue.indexOf('%') != -1 ?\n    ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );\n  var y = yValue.indexOf('%') != -1 ?\n    ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );\n\n  // clean up 'auto' or other non-integer values\n  x = isNaN( x ) ? 0 : x;\n  y = isNaN( y ) ? 0 : y;\n  // remove padding from measurement\n  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;\n  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;\n\n  this.position.x = x;\n  this.position.y = y;\n};\n\n// set settled position, apply padding\nItem.prototype.layoutPosition = function() {\n  var layoutSize = this.layout.size;\n  var layoutOptions = this.layout.options;\n  var style = {};\n\n  // x\n  var xPadding = layoutOptions.isOriginLeft ? 'paddingLeft' : 'paddingRight';\n  var xProperty = layoutOptions.isOriginLeft ? 'left' : 'right';\n  var xResetProperty = layoutOptions.isOriginLeft ? 'right' : 'left';\n\n  var x = this.position.x + layoutSize[ xPadding ];\n  // set in percentage or pixels\n  style[ xProperty ] = this.getXValue( x );\n  // reset other property\n  style[ xResetProperty ] = '';\n\n  // y\n  var yPadding = layoutOptions.isOriginTop ? 'paddingTop' : 'paddingBottom';\n  var yProperty = layoutOptions.isOriginTop ? 'top' : 'bottom';\n  var yResetProperty = layoutOptions.isOriginTop ? 'bottom' : 'top';\n\n  var y = this.position.y + layoutSize[ yPadding ];\n  // set in percentage or pixels\n  style[ yProperty ] = this.getYValue( y );\n  // reset other property\n  style[ yResetProperty ] = '';\n\n  this.css( style );\n  this.emitEvent( 'layout', [ this ] );\n};\n\nItem.prototype.getXValue = function( x ) {\n  var layoutOptions = this.layout.options;\n  return layoutOptions.percentPosition && !layoutOptions.isHorizontal ?\n    ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';\n};\n\nItem.prototype.getYValue = function( y ) {\n  var layoutOptions = this.layout.options;\n  return layoutOptions.percentPosition && layoutOptions.isHorizontal ?\n    ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';\n};\n\n\nItem.prototype._transitionTo = function( x, y ) {\n  this.getPosition();\n  // get current x & y from top/left\n  var curX = this.position.x;\n  var curY = this.position.y;\n\n  var compareX = parseInt( x, 10 );\n  var compareY = parseInt( y, 10 );\n  var didNotMove = compareX === this.position.x && compareY === this.position.y;\n\n  // save end position\n  this.setPosition( x, y );\n\n  // if did not move and not transitioning, just go to layout\n  if ( didNotMove && !this.isTransitioning ) {\n    this.layoutPosition();\n    return;\n  }\n\n  var transX = x - curX;\n  var transY = y - curY;\n  var transitionStyle = {};\n  transitionStyle.transform = this.getTranslate( transX, transY );\n\n  this.transition({\n    to: transitionStyle,\n    onTransitionEnd: {\n      transform: this.layoutPosition\n    },\n    isCleaning: true\n  });\n};\n\nItem.prototype.getTranslate = function( x, y ) {\n  // flip cooridinates if origin on right or bottom\n  var layoutOptions = this.layout.options;\n  x = layoutOptions.isOriginLeft ? x : -x;\n  y = layoutOptions.isOriginTop ? y : -y;\n\n  if ( is3d ) {\n    return 'translate3d(' + x + 'px, ' + y + 'px, 0)';\n  }\n\n  return 'translate(' + x + 'px, ' + y + 'px)';\n};\n\n// non transition + transform support\nItem.prototype.goTo = function( x, y ) {\n  this.setPosition( x, y );\n  this.layoutPosition();\n};\n\n// use transition and transforms if supported\nItem.prototype.moveTo = supportsCSS3 ?\n  Item.prototype._transitionTo : Item.prototype.goTo;\n\nItem.prototype.setPosition = function( x, y ) {\n  this.position.x = parseInt( x, 10 );\n  this.position.y = parseInt( y, 10 );\n};\n\n// ----- transition ----- //\n\n/**\n * @param {Object} style - CSS\n * @param {Function} onTransitionEnd\n */\n\n// non transition, just trigger callback\nItem.prototype._nonTransition = function( args ) {\n  this.css( args.to );\n  if ( args.isCleaning ) {\n    this._removeStyles( args.to );\n  }\n  for ( var prop in args.onTransitionEnd ) {\n    args.onTransitionEnd[ prop ].call( this );\n  }\n};\n\n/**\n * proper transition\n * @param {Object} args - arguments\n *   @param {Object} to - style to transition to\n *   @param {Object} from - style to start transition from\n *   @param {Boolean} isCleaning - removes transition styles after transition\n *   @param {Function} onTransitionEnd - callback\n */\nItem.prototype._transition = function( args ) {\n  // redirect to nonTransition if no transition duration\n  if ( !parseFloat( this.layout.options.transitionDuration ) ) {\n    this._nonTransition( args );\n    return;\n  }\n\n  var _transition = this._transn;\n  // keep track of onTransitionEnd callback by css property\n  for ( var prop in args.onTransitionEnd ) {\n    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];\n  }\n  // keep track of properties that are transitioning\n  for ( prop in args.to ) {\n    _transition.ingProperties[ prop ] = true;\n    // keep track of properties to clean up when transition is done\n    if ( args.isCleaning ) {\n      _transition.clean[ prop ] = true;\n    }\n  }\n\n  // set from styles\n  if ( args.from ) {\n    this.css( args.from );\n    // force redraw. http://blog.alexmaccaw.com/css-transitions\n    var h = this.element.offsetHeight;\n    // hack for JSHint to hush about unused var\n    h = null;\n  }\n  // enable transition\n  this.enableTransition( args.to );\n  // set styles that are transitioning\n  this.css( args.to );\n\n  this.isTransitioning = true;\n\n};\n\n// dash before all cap letters, including first for\n// WebkitTransform => -webkit-transform\nfunction toDashedAll( str ) {\n  return str.replace( /([A-Z])/g, function( $1 ) {\n    return '-' + $1.toLowerCase();\n  });\n}\n\nvar transitionProps = 'opacity,' +\n  toDashedAll( vendorProperties.transform || 'transform' );\n\nItem.prototype.enableTransition = function(/* style */) {\n  // HACK changing transitionProperty during a transition\n  // will cause transition to jump\n  if ( this.isTransitioning ) {\n    return;\n  }\n\n  // make `transition: foo, bar, baz` from style object\n  // HACK un-comment this when enableTransition can work\n  // while a transition is happening\n  // var transitionValues = [];\n  // for ( var prop in style ) {\n  //   // dash-ify camelCased properties like WebkitTransition\n  //   prop = vendorProperties[ prop ] || prop;\n  //   transitionValues.push( toDashedAll( prop ) );\n  // }\n  // enable transition styles\n  this.css({\n    transitionProperty: transitionProps,\n    transitionDuration: this.layout.options.transitionDuration\n  });\n  // listen for transition end event\n  this.element.addEventListener( transitionEndEvent, this, false );\n};\n\nItem.prototype.transition = Item.prototype[ transitionProperty ? '_transition' : '_nonTransition' ];\n\n// ----- events ----- //\n\nItem.prototype.onwebkitTransitionEnd = function( event ) {\n  this.ontransitionend( event );\n};\n\nItem.prototype.onotransitionend = function( event ) {\n  this.ontransitionend( event );\n};\n\n// properties that I munge to make my life easier\nvar dashedVendorProperties = {\n  '-webkit-transform': 'transform',\n  '-moz-transform': 'transform',\n  '-o-transform': 'transform'\n};\n\nItem.prototype.ontransitionend = function( event ) {\n  // disregard bubbled events from children\n  if ( event.target !== this.element ) {\n    return;\n  }\n  var _transition = this._transn;\n  // get property name of transitioned property, convert to prefix-free\n  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;\n\n  // remove property that has completed transitioning\n  delete _transition.ingProperties[ propertyName ];\n  // check if any properties are still transitioning\n  if ( isEmptyObj( _transition.ingProperties ) ) {\n    // all properties have completed transitioning\n    this.disableTransition();\n  }\n  // clean style\n  if ( propertyName in _transition.clean ) {\n    // clean up style\n    this.element.style[ event.propertyName ] = '';\n    delete _transition.clean[ propertyName ];\n  }\n  // trigger onTransitionEnd callback\n  if ( propertyName in _transition.onEnd ) {\n    var onTransitionEnd = _transition.onEnd[ propertyName ];\n    onTransitionEnd.call( this );\n    delete _transition.onEnd[ propertyName ];\n  }\n\n  this.emitEvent( 'transitionEnd', [ this ] );\n};\n\nItem.prototype.disableTransition = function() {\n  this.removeTransitionStyles();\n  this.element.removeEventListener( transitionEndEvent, this, false );\n  this.isTransitioning = false;\n};\n\n/**\n * removes style property from element\n * @param {Object} style\n**/\nItem.prototype._removeStyles = function( style ) {\n  // clean up transition styles\n  var cleanStyle = {};\n  for ( var prop in style ) {\n    cleanStyle[ prop ] = '';\n  }\n  this.css( cleanStyle );\n};\n\nvar cleanTransitionStyle = {\n  transitionProperty: '',\n  transitionDuration: ''\n};\n\nItem.prototype.removeTransitionStyles = function() {\n  // remove transition\n  this.css( cleanTransitionStyle );\n};\n\n// ----- show/hide/remove ----- //\n\n// remove element from DOM\nItem.prototype.removeElem = function() {\n  this.element.parentNode.removeChild( this.element );\n  // remove display: none\n  this.css({ display: '' });\n  this.emitEvent( 'remove', [ this ] );\n};\n\nItem.prototype.remove = function() {\n  // just remove element if no transition support or no transition\n  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {\n    this.removeElem();\n    return;\n  }\n\n  // start transition\n  var _this = this;\n  this.once( 'transitionEnd', function() {\n    _this.removeElem();\n  });\n  this.hide();\n};\n\nItem.prototype.reveal = function() {\n  delete this.isHidden;\n  // remove display: none\n  this.css({ display: '' });\n\n  var options = this.layout.options;\n\n  var onTransitionEnd = {};\n  var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');\n  onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;\n\n  this.transition({\n    from: options.hiddenStyle,\n    to: options.visibleStyle,\n    isCleaning: true,\n    onTransitionEnd: onTransitionEnd\n  });\n};\n\nItem.prototype.onRevealTransitionEnd = function() {\n  // check if still visible\n  // during transition, item may have been hidden\n  if ( !this.isHidden ) {\n    this.emitEvent('reveal');\n  }\n};\n\n/**\n * get style property use for hide/reveal transition end\n * @param {String} styleProperty - hiddenStyle/visibleStyle\n * @returns {String}\n */\nItem.prototype.getHideRevealTransitionEndProperty = function( styleProperty ) {\n  var optionStyle = this.layout.options[ styleProperty ];\n  // use opacity\n  if ( optionStyle.opacity ) {\n    return 'opacity';\n  }\n  // get first property\n  for ( var prop in optionStyle ) {\n    return prop;\n  }\n};\n\nItem.prototype.hide = function() {\n  // set flag\n  this.isHidden = true;\n  // remove display: none\n  this.css({ display: '' });\n\n  var options = this.layout.options;\n\n  var onTransitionEnd = {};\n  var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');\n  onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;\n\n  this.transition({\n    from: options.visibleStyle,\n    to: options.hiddenStyle,\n    // keep hidden stuff hidden\n    isCleaning: true,\n    onTransitionEnd: onTransitionEnd\n  });\n};\n\nItem.prototype.onHideTransitionEnd = function() {\n  // check if still hidden\n  // during transition, item may have been un-hidden\n  if ( this.isHidden ) {\n    this.css({ display: 'none' });\n    this.emitEvent('hide');\n  }\n};\n\nItem.prototype.destroy = function() {\n  this.css({\n    position: '',\n    left: '',\n    right: '',\n    top: '',\n    bottom: '',\n    transition: '',\n    transform: ''\n  });\n};\n\nreturn Item;\n\n}));\n\n/*!\n * Outlayer v1.4.2\n * the brains and guts of a layout library\n * MIT license\n */\n\n( function( window, factory ) {\n  \n  // universal module definition\n\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( 'outlayer/outlayer',[\n        'eventie/eventie',\n        'eventEmitter/EventEmitter',\n        'get-size/get-size',\n        'fizzy-ui-utils/utils',\n        './item'\n      ],\n      function( eventie, EventEmitter, getSize, utils, Item ) {\n        return factory( window, eventie, EventEmitter, getSize, utils, Item);\n      }\n    );\n  } else if ( typeof exports == 'object' ) {\n    // CommonJS\n    module.exports = factory(\n      window,\n      require('eventie'),\n      require('wolfy87-eventemitter'),\n      require('get-size'),\n      require('fizzy-ui-utils'),\n      require('./item')\n    );\n  } else {\n    // browser global\n    window.Outlayer = factory(\n      window,\n      window.eventie,\n      window.EventEmitter,\n      window.getSize,\n      window.fizzyUIUtils,\n      window.Outlayer.Item\n    );\n  }\n\n}( window, function factory( window, eventie, EventEmitter, getSize, utils, Item ) {\n\n\n// ----- vars ----- //\n\nvar console = window.console;\nvar jQuery = window.jQuery;\nvar noop = function() {};\n\n// -------------------------- Outlayer -------------------------- //\n\n// globally unique identifiers\nvar GUID = 0;\n// internal store of all Outlayer intances\nvar instances = {};\n\n\n/**\n * @param {Element, String} element\n * @param {Object} options\n * @constructor\n */\nfunction Outlayer( element, options ) {\n  var queryElement = utils.getQueryElement( element );\n  if ( !queryElement ) {\n    if ( console ) {\n      console.error( 'Bad element for ' + this.constructor.namespace +\n        ': ' + ( queryElement || element ) );\n    }\n    return;\n  }\n  this.element = queryElement;\n  // add jQuery\n  if ( jQuery ) {\n    this.$element = jQuery( this.element );\n  }\n\n  // options\n  this.options = utils.extend( {}, this.constructor.defaults );\n  this.option( options );\n\n  // add id for Outlayer.getFromElement\n  var id = ++GUID;\n  this.element.outlayerGUID = id; // expando\n  instances[ id ] = this; // associate via id\n\n  // kick it off\n  this._create();\n\n  if ( this.options.isInitLayout ) {\n    this.layout();\n  }\n}\n\n// settings are for internal use only\nOutlayer.namespace = 'outlayer';\nOutlayer.Item = Item;\n\n// default options\nOutlayer.defaults = {\n  containerStyle: {\n    position: 'relative'\n  },\n  isInitLayout: true,\n  isOriginLeft: true,\n  isOriginTop: true,\n  isResizeBound: true,\n  isResizingContainer: true,\n  // item options\n  transitionDuration: '0.4s',\n  hiddenStyle: {\n    opacity: 0,\n    transform: 'scale(0.001)'\n  },\n  visibleStyle: {\n    opacity: 1,\n    transform: 'scale(1)'\n  }\n};\n\n// inherit EventEmitter\nutils.extend( Outlayer.prototype, EventEmitter.prototype );\n\n/**\n * set options\n * @param {Object} opts\n */\nOutlayer.prototype.option = function( opts ) {\n  utils.extend( this.options, opts );\n};\n\nOutlayer.prototype._create = function() {\n  // get items from children\n  this.reloadItems();\n  // elements that affect layout, but are not laid out\n  this.stamps = [];\n  this.stamp( this.options.stamp );\n  // set container style\n  utils.extend( this.element.style, this.options.containerStyle );\n\n  // bind resize method\n  if ( this.options.isResizeBound ) {\n    this.bindResize();\n  }\n};\n\n// goes through all children again and gets bricks in proper order\nOutlayer.prototype.reloadItems = function() {\n  // collection of item elements\n  this.items = this._itemize( this.element.children );\n};\n\n\n/**\n * turn elements into Outlayer.Items to be used in layout\n * @param {Array or NodeList or HTMLElement} elems\n * @returns {Array} items - collection of new Outlayer Items\n */\nOutlayer.prototype._itemize = function( elems ) {\n\n  var itemElems = this._filterFindItemElements( elems );\n  var Item = this.constructor.Item;\n\n  // create new Outlayer Items for collection\n  var items = [];\n  for ( var i=0, len = itemElems.length; i < len; i++ ) {\n    var elem = itemElems[i];\n    var item = new Item( elem, this );\n    items.push( item );\n  }\n\n  return items;\n};\n\n/**\n * get item elements to be used in layout\n * @param {Array or NodeList or HTMLElement} elems\n * @returns {Array} items - item elements\n */\nOutlayer.prototype._filterFindItemElements = function( elems ) {\n  return utils.filterFindElements( elems, this.options.itemSelector );\n};\n\n/**\n * getter method for getting item elements\n * @returns {Array} elems - collection of item elements\n */\nOutlayer.prototype.getItemElements = function() {\n  var elems = [];\n  for ( var i=0, len = this.items.length; i < len; i++ ) {\n    elems.push( this.items[i].element );\n  }\n  return elems;\n};\n\n// ----- init & layout ----- //\n\n/**\n * lays out all items\n */\nOutlayer.prototype.layout = function() {\n  this._resetLayout();\n  this._manageStamps();\n\n  // don't animate first layout\n  var isInstant = this.options.isLayoutInstant !== undefined ?\n    this.options.isLayoutInstant : !this._isLayoutInited;\n  this.layoutItems( this.items, isInstant );\n\n  // flag for initalized\n  this._isLayoutInited = true;\n};\n\n// _init is alias for layout\nOutlayer.prototype._init = Outlayer.prototype.layout;\n\n/**\n * logic before any new layout\n */\nOutlayer.prototype._resetLayout = function() {\n  this.getSize();\n};\n\n\nOutlayer.prototype.getSize = function() {\n  this.size = getSize( this.element );\n};\n\n/**\n * get measurement from option, for columnWidth, rowHeight, gutter\n * if option is String -> get element from selector string, & get size of element\n * if option is Element -> get size of element\n * else use option as a number\n *\n * @param {String} measurement\n * @param {String} size - width or height\n * @private\n */\nOutlayer.prototype._getMeasurement = function( measurement, size ) {\n  var option = this.options[ measurement ];\n  var elem;\n  if ( !option ) {\n    // default to 0\n    this[ measurement ] = 0;\n  } else {\n    // use option as an element\n    if ( typeof option === 'string' ) {\n      elem = this.element.querySelector( option );\n    } else if ( utils.isElement( option ) ) {\n      elem = option;\n    }\n    // use size of element, if element\n    this[ measurement ] = elem ? getSize( elem )[ size ] : option;\n  }\n};\n\n/**\n * layout a collection of item elements\n * @api public\n */\nOutlayer.prototype.layoutItems = function( items, isInstant ) {\n  items = this._getItemsForLayout( items );\n\n  this._layoutItems( items, isInstant );\n\n  this._postLayout();\n};\n\n/**\n * get the items to be laid out\n * you may want to skip over some items\n * @param {Array} items\n * @returns {Array} items\n */\nOutlayer.prototype._getItemsForLayout = function( items ) {\n  var layoutItems = [];\n  for ( var i=0, len = items.length; i < len; i++ ) {\n    var item = items[i];\n    if ( !item.isIgnored ) {\n      layoutItems.push( item );\n    }\n  }\n  return layoutItems;\n};\n\n/**\n * layout items\n * @param {Array} items\n * @param {Boolean} isInstant\n */\nOutlayer.prototype._layoutItems = function( items, isInstant ) {\n  this._emitCompleteOnItems( 'layout', items );\n\n  if ( !items || !items.length ) {\n    // no items, emit event with empty array\n    return;\n  }\n\n  var queue = [];\n\n  for ( var i=0, len = items.length; i < len; i++ ) {\n    var item = items[i];\n    // get x/y object from method\n    var position = this._getItemLayoutPosition( item );\n    // enqueue\n    position.item = item;\n    position.isInstant = isInstant || item.isLayoutInstant;\n    queue.push( position );\n  }\n\n  this._processLayoutQueue( queue );\n};\n\n/**\n * get item layout position\n * @param {Outlayer.Item} item\n * @returns {Object} x and y position\n */\nOutlayer.prototype._getItemLayoutPosition = function( /* item */ ) {\n  return {\n    x: 0,\n    y: 0\n  };\n};\n\n/**\n * iterate over array and position each item\n * Reason being - separating this logic prevents 'layout invalidation'\n * thx @paul_irish\n * @param {Array} queue\n */\nOutlayer.prototype._processLayoutQueue = function( queue ) {\n  for ( var i=0, len = queue.length; i < len; i++ ) {\n    var obj = queue[i];\n    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant );\n  }\n};\n\n/**\n * Sets position of item in DOM\n * @param {Outlayer.Item} item\n * @param {Number} x - horizontal position\n * @param {Number} y - vertical position\n * @param {Boolean} isInstant - disables transitions\n */\nOutlayer.prototype._positionItem = function( item, x, y, isInstant ) {\n  if ( isInstant ) {\n    // if not transition, just set CSS\n    item.goTo( x, y );\n  } else {\n    item.moveTo( x, y );\n  }\n};\n\n/**\n * Any logic you want to do after each layout,\n * i.e. size the container\n */\nOutlayer.prototype._postLayout = function() {\n  this.resizeContainer();\n};\n\nOutlayer.prototype.resizeContainer = function() {\n  if ( !this.options.isResizingContainer ) {\n    return;\n  }\n  var size = this._getContainerSize();\n  if ( size ) {\n    this._setContainerMeasure( size.width, true );\n    this._setContainerMeasure( size.height, false );\n  }\n};\n\n/**\n * Sets width or height of container if returned\n * @returns {Object} size\n *   @param {Number} width\n *   @param {Number} height\n */\nOutlayer.prototype._getContainerSize = noop;\n\n/**\n * @param {Number} measure - size of width or height\n * @param {Boolean} isWidth\n */\nOutlayer.prototype._setContainerMeasure = function( measure, isWidth ) {\n  if ( measure === undefined ) {\n    return;\n  }\n\n  var elemSize = this.size;\n  // add padding and border width if border box\n  if ( elemSize.isBorderBox ) {\n    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +\n      elemSize.borderLeftWidth + elemSize.borderRightWidth :\n      elemSize.paddingBottom + elemSize.paddingTop +\n      elemSize.borderTopWidth + elemSize.borderBottomWidth;\n  }\n\n  measure = Math.max( measure, 0 );\n  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';\n};\n\n/**\n * emit eventComplete on a collection of items events\n * @param {String} eventName\n * @param {Array} items - Outlayer.Items\n */\nOutlayer.prototype._emitCompleteOnItems = function( eventName, items ) {\n  var _this = this;\n  function onComplete() {\n    _this.dispatchEvent( eventName + 'Complete', null, [ items ] );\n  }\n\n  var count = items.length;\n  if ( !items || !count ) {\n    onComplete();\n    return;\n  }\n\n  var doneCount = 0;\n  function tick() {\n    doneCount++;\n    if ( doneCount === count ) {\n      onComplete();\n    }\n  }\n\n  // bind callback\n  for ( var i=0, len = items.length; i < len; i++ ) {\n    var item = items[i];\n    item.once( eventName, tick );\n  }\n};\n\n/**\n * emits events via eventEmitter and jQuery events\n * @param {String} type - name of event\n * @param {Event} event - original event\n * @param {Array} args - extra arguments\n */\nOutlayer.prototype.dispatchEvent = function( type, event, args ) {\n  // add original event to arguments\n  var emitArgs = event ? [ event ].concat( args ) : args;\n  this.emitEvent( type, emitArgs );\n\n  if ( jQuery ) {\n    // set this.$element\n    this.$element = this.$element || jQuery( this.element );\n    if ( event ) {\n      // create jQuery event\n      var $event = jQuery.Event( event );\n      $event.type = type;\n      this.$element.trigger( $event, args );\n    } else {\n      // just trigger with type if no event available\n      this.$element.trigger( type, args );\n    }\n  }\n};\n\n// -------------------------- ignore & stamps -------------------------- //\n\n\n/**\n * keep item in collection, but do not lay it out\n * ignored items do not get skipped in layout\n * @param {Element} elem\n */\nOutlayer.prototype.ignore = function( elem ) {\n  var item = this.getItem( elem );\n  if ( item ) {\n    item.isIgnored = true;\n  }\n};\n\n/**\n * return item to layout collection\n * @param {Element} elem\n */\nOutlayer.prototype.unignore = function( elem ) {\n  var item = this.getItem( elem );\n  if ( item ) {\n    delete item.isIgnored;\n  }\n};\n\n/**\n * adds elements to stamps\n * @param {NodeList, Array, Element, or String} elems\n */\nOutlayer.prototype.stamp = function( elems ) {\n  elems = this._find( elems );\n  if ( !elems ) {\n    return;\n  }\n\n  this.stamps = this.stamps.concat( elems );\n  // ignore\n  for ( var i=0, len = elems.length; i < len; i++ ) {\n    var elem = elems[i];\n    this.ignore( elem );\n  }\n};\n\n/**\n * removes elements to stamps\n * @param {NodeList, Array, or Element} elems\n */\nOutlayer.prototype.unstamp = function( elems ) {\n  elems = this._find( elems );\n  if ( !elems ){\n    return;\n  }\n\n  for ( var i=0, len = elems.length; i < len; i++ ) {\n    var elem = elems[i];\n    // filter out removed stamp elements\n    utils.removeFrom( this.stamps, elem );\n    this.unignore( elem );\n  }\n\n};\n\n/**\n * finds child elements\n * @param {NodeList, Array, Element, or String} elems\n * @returns {Array} elems\n */\nOutlayer.prototype._find = function( elems ) {\n  if ( !elems ) {\n    return;\n  }\n  // if string, use argument as selector string\n  if ( typeof elems === 'string' ) {\n    elems = this.element.querySelectorAll( elems );\n  }\n  elems = utils.makeArray( elems );\n  return elems;\n};\n\nOutlayer.prototype._manageStamps = function() {\n  if ( !this.stamps || !this.stamps.length ) {\n    return;\n  }\n\n  this._getBoundingRect();\n\n  for ( var i=0, len = this.stamps.length; i < len; i++ ) {\n    var stamp = this.stamps[i];\n    this._manageStamp( stamp );\n  }\n};\n\n// update boundingLeft / Top\nOutlayer.prototype._getBoundingRect = function() {\n  // get bounding rect for container element\n  var boundingRect = this.element.getBoundingClientRect();\n  var size = this.size;\n  this._boundingRect = {\n    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,\n    top: boundingRect.top + size.paddingTop + size.borderTopWidth,\n    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),\n    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )\n  };\n};\n\n/**\n * @param {Element} stamp\n**/\nOutlayer.prototype._manageStamp = noop;\n\n/**\n * get x/y position of element relative to container element\n * @param {Element} elem\n * @returns {Object} offset - has left, top, right, bottom\n */\nOutlayer.prototype._getElementOffset = function( elem ) {\n  var boundingRect = elem.getBoundingClientRect();\n  var thisRect = this._boundingRect;\n  var size = getSize( elem );\n  var offset = {\n    left: boundingRect.left - thisRect.left - size.marginLeft,\n    top: boundingRect.top - thisRect.top - size.marginTop,\n    right: thisRect.right - boundingRect.right - size.marginRight,\n    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom\n  };\n  return offset;\n};\n\n// -------------------------- resize -------------------------- //\n\n// enable event handlers for listeners\n// i.e. resize -> onresize\nOutlayer.prototype.handleEvent = function( event ) {\n  var method = 'on' + event.type;\n  if ( this[ method ] ) {\n    this[ method ]( event );\n  }\n};\n\n/**\n * Bind layout to window resizing\n */\nOutlayer.prototype.bindResize = function() {\n  // bind just one listener\n  if ( this.isResizeBound ) {\n    return;\n  }\n  window.eventie.bind( window, 'resize', this );\n  this.isResizeBound = true;\n};\n\n/**\n * Unbind layout to window resizing\n */\nOutlayer.prototype.unbindResize = function() {\n  if ( this.isResizeBound ) {\n    window.eventie.unbind( window, 'resize', this );\n  }\n  this.isResizeBound = false;\n};\n\n// original debounce by John Hann\n// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/\n\n// this fires every resize\nOutlayer.prototype.onresize = function() {\n  if ( this.resizeTimeout ) {\n    clearTimeout( this.resizeTimeout );\n  }\n\n  var _this = this;\n  function delayed() {\n    _this.resize();\n    delete _this.resizeTimeout;\n  }\n\n  this.resizeTimeout = setTimeout( delayed, 100 );\n};\n\n// debounced, layout on resize\nOutlayer.prototype.resize = function() {\n  // don't trigger if size did not change\n  // or if resize was unbound. See #9\n  if ( !this.isResizeBound || !this.needsResizeLayout() ) {\n    return;\n  }\n\n  this.layout();\n};\n\n/**\n * check if layout is needed post layout\n * @returns Boolean\n */\nOutlayer.prototype.needsResizeLayout = function() {\n  var size = getSize( this.element );\n  // check that this.size and size are there\n  // IE8 triggers resize on body size change, so they might not be\n  var hasSizes = this.size && size;\n  return hasSizes && size.innerWidth !== this.size.innerWidth;\n};\n\n// -------------------------- methods -------------------------- //\n\n/**\n * add items to Outlayer instance\n * @param {Array or NodeList or Element} elems\n * @returns {Array} items - Outlayer.Items\n**/\nOutlayer.prototype.addItems = function( elems ) {\n  var items = this._itemize( elems );\n  // add items to collection\n  if ( items.length ) {\n    this.items = this.items.concat( items );\n  }\n  return items;\n};\n\n/**\n * Layout newly-appended item elements\n * @param {Array or NodeList or Element} elems\n */\nOutlayer.prototype.appended = function( elems ) {\n  var items = this.addItems( elems );\n  if ( !items.length ) {\n    return;\n  }\n  // layout and reveal just the new items\n  this.layoutItems( items, true );\n  this.reveal( items );\n};\n\n/**\n * Layout prepended elements\n * @param {Array or NodeList or Element} elems\n */\nOutlayer.prototype.prepended = function( elems ) {\n  var items = this._itemize( elems );\n  if ( !items.length ) {\n    return;\n  }\n  // add items to beginning of collection\n  var previousItems = this.items.slice(0);\n  this.items = items.concat( previousItems );\n  // start new layout\n  this._resetLayout();\n  this._manageStamps();\n  // layout new stuff without transition\n  this.layoutItems( items, true );\n  this.reveal( items );\n  // layout previous items\n  this.layoutItems( previousItems );\n};\n\n/**\n * reveal a collection of items\n * @param {Array of Outlayer.Items} items\n */\nOutlayer.prototype.reveal = function( items ) {\n  this._emitCompleteOnItems( 'reveal', items );\n\n  var len = items && items.length;\n  for ( var i=0; len && i < len; i++ ) {\n    var item = items[i];\n    item.reveal();\n  }\n};\n\n/**\n * hide a collection of items\n * @param {Array of Outlayer.Items} items\n */\nOutlayer.prototype.hide = function( items ) {\n  this._emitCompleteOnItems( 'hide', items );\n\n  var len = items && items.length;\n  for ( var i=0; len && i < len; i++ ) {\n    var item = items[i];\n    item.hide();\n  }\n};\n\n/**\n * reveal item elements\n * @param {Array}, {Element}, {NodeList} items\n */\nOutlayer.prototype.revealItemElements = function( elems ) {\n  var items = this.getItems( elems );\n  this.reveal( items );\n};\n\n/**\n * hide item elements\n * @param {Array}, {Element}, {NodeList} items\n */\nOutlayer.prototype.hideItemElements = function( elems ) {\n  var items = this.getItems( elems );\n  this.hide( items );\n};\n\n/**\n * get Outlayer.Item, given an Element\n * @param {Element} elem\n * @param {Function} callback\n * @returns {Outlayer.Item} item\n */\nOutlayer.prototype.getItem = function( elem ) {\n  // loop through items to get the one that matches\n  for ( var i=0, len = this.items.length; i < len; i++ ) {\n    var item = this.items[i];\n    if ( item.element === elem ) {\n      // return item\n      return item;\n    }\n  }\n};\n\n/**\n * get collection of Outlayer.Items, given Elements\n * @param {Array} elems\n * @returns {Array} items - Outlayer.Items\n */\nOutlayer.prototype.getItems = function( elems ) {\n  elems = utils.makeArray( elems );\n  var items = [];\n  for ( var i=0, len = elems.length; i < len; i++ ) {\n    var elem = elems[i];\n    var item = this.getItem( elem );\n    if ( item ) {\n      items.push( item );\n    }\n  }\n\n  return items;\n};\n\n/**\n * remove element(s) from instance and DOM\n * @param {Array or NodeList or Element} elems\n */\nOutlayer.prototype.remove = function( elems ) {\n  var removeItems = this.getItems( elems );\n\n  this._emitCompleteOnItems( 'remove', removeItems );\n\n  // bail if no items to remove\n  if ( !removeItems || !removeItems.length ) {\n    return;\n  }\n\n  for ( var i=0, len = removeItems.length; i < len; i++ ) {\n    var item = removeItems[i];\n    item.remove();\n    // remove item from collection\n    utils.removeFrom( this.items, item );\n  }\n};\n\n// ----- destroy ----- //\n\n// remove and disable Outlayer instance\nOutlayer.prototype.destroy = function() {\n  // clean up dynamic styles\n  var style = this.element.style;\n  style.height = '';\n  style.position = '';\n  style.width = '';\n  // destroy items\n  for ( var i=0, len = this.items.length; i < len; i++ ) {\n    var item = this.items[i];\n    item.destroy();\n  }\n\n  this.unbindResize();\n\n  var id = this.element.outlayerGUID;\n  delete instances[ id ]; // remove reference to instance by id\n  delete this.element.outlayerGUID;\n  // remove data for jQuery\n  if ( jQuery ) {\n    jQuery.removeData( this.element, this.constructor.namespace );\n  }\n\n};\n\n// -------------------------- data -------------------------- //\n\n/**\n * get Outlayer instance from element\n * @param {Element} elem\n * @returns {Outlayer}\n */\nOutlayer.data = function( elem ) {\n  elem = utils.getQueryElement( elem );\n  var id = elem && elem.outlayerGUID;\n  return id && instances[ id ];\n};\n\n\n// -------------------------- create Outlayer class -------------------------- //\n\n/**\n * create a layout class\n * @param {String} namespace\n */\nOutlayer.create = function( namespace, options ) {\n  // sub-class Outlayer\n  function Layout() {\n    Outlayer.apply( this, arguments );\n  }\n  // inherit Outlayer prototype, use Object.create if there\n  if ( Object.create ) {\n    Layout.prototype = Object.create( Outlayer.prototype );\n  } else {\n    utils.extend( Layout.prototype, Outlayer.prototype );\n  }\n  // set contructor, used for namespace and Item\n  Layout.prototype.constructor = Layout;\n\n  Layout.defaults = utils.extend( {}, Outlayer.defaults );\n  // apply new options\n  utils.extend( Layout.defaults, options );\n  // keep prototype.settings for backwards compatibility (Packery v1.2.0)\n  Layout.prototype.settings = {};\n\n  Layout.namespace = namespace;\n\n  Layout.data = Outlayer.data;\n\n  // sub-class Item\n  Layout.Item = function LayoutItem() {\n    Item.apply( this, arguments );\n  };\n\n  Layout.Item.prototype = new Item();\n\n  // -------------------------- declarative -------------------------- //\n\n  utils.htmlInit( Layout, namespace );\n\n  // -------------------------- jQuery bridge -------------------------- //\n\n  // make into jQuery plugin\n  if ( jQuery && jQuery.bridget ) {\n    jQuery.bridget( namespace, Layout );\n  }\n\n  return Layout;\n};\n\n// ----- fin ----- //\n\n// back in global\nOutlayer.Item = Item;\n\nreturn Outlayer;\n\n}));\n\n\n/**\n * Rect\n * low-level utility class for basic geometry\n */\n\n( function( window, factory ) {\n  \n  // universal module definition\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( 'packery/js/rect',factory );\n  } else if ( typeof exports == 'object' ) {\n    // CommonJS\n    module.exports = factory();\n  } else {\n    // browser global\n    window.Packery = window.Packery || {};\n    window.Packery.Rect = factory();\n  }\n\n}( window, function factory() {\n\n\n// -------------------------- Packery -------------------------- //\n\n// global namespace\nvar Packery = window.Packery = function() {};\n\n// -------------------------- Rect -------------------------- //\n\nfunction Rect( props ) {\n  // extend properties from defaults\n  for ( var prop in Rect.defaults ) {\n    this[ prop ] = Rect.defaults[ prop ];\n  }\n\n  for ( prop in props ) {\n    this[ prop ] = props[ prop ];\n  }\n\n}\n\n// make available\nPackery.Rect = Rect;\n\nRect.defaults = {\n  x: 0,\n  y: 0,\n  width: 0,\n  height: 0\n};\n\n/**\n * Determines whether or not this rectangle wholly encloses another rectangle or point.\n * @param {Rect} rect\n * @returns {Boolean}\n**/\nRect.prototype.contains = function( rect ) {\n  // points don't have width or height\n  var otherWidth = rect.width || 0;\n  var otherHeight = rect.height || 0;\n  return this.x <= rect.x &&\n    this.y <= rect.y &&\n    this.x + this.width >= rect.x + otherWidth &&\n    this.y + this.height >= rect.y + otherHeight;\n};\n\n/**\n * Determines whether or not the rectangle intersects with another.\n * @param {Rect} rect\n * @returns {Boolean}\n**/\nRect.prototype.overlaps = function( rect ) {\n  var thisRight = this.x + this.width;\n  var thisBottom = this.y + this.height;\n  var rectRight = rect.x + rect.width;\n  var rectBottom = rect.y + rect.height;\n\n  // http://stackoverflow.com/a/306332\n  return this.x < rectRight &&\n    thisRight > rect.x &&\n    this.y < rectBottom &&\n    thisBottom > rect.y;\n};\n\n/**\n * @param {Rect} rect - the overlapping rect\n * @returns {Array} freeRects - rects representing the area around the rect\n**/\nRect.prototype.getMaximalFreeRects = function( rect ) {\n\n  // if no intersection, return false\n  if ( !this.overlaps( rect ) ) {\n    return false;\n  }\n\n  var freeRects = [];\n  var freeRect;\n\n  var thisRight = this.x + this.width;\n  var thisBottom = this.y + this.height;\n  var rectRight = rect.x + rect.width;\n  var rectBottom = rect.y + rect.height;\n\n  // top\n  if ( this.y < rect.y ) {\n    freeRect = new Rect({\n      x: this.x,\n      y: this.y,\n      width: this.width,\n      height: rect.y - this.y\n    });\n    freeRects.push( freeRect );\n  }\n\n  // right\n  if ( thisRight > rectRight ) {\n    freeRect = new Rect({\n      x: rectRight,\n      y: this.y,\n      width: thisRight - rectRight,\n      height: this.height\n    });\n    freeRects.push( freeRect );\n  }\n\n  // bottom\n  if ( thisBottom > rectBottom ) {\n    freeRect = new Rect({\n      x: this.x,\n      y: rectBottom,\n      width: this.width,\n      height: thisBottom - rectBottom\n    });\n    freeRects.push( freeRect );\n  }\n\n  // left\n  if ( this.x < rect.x ) {\n    freeRect = new Rect({\n      x: this.x,\n      y: this.y,\n      width: rect.x - this.x,\n      height: this.height\n    });\n    freeRects.push( freeRect );\n  }\n\n  return freeRects;\n};\n\nRect.prototype.canFit = function( rect ) {\n  return this.width >= rect.width && this.height >= rect.height;\n};\n\nreturn Rect;\n\n}));\n\n/**\n * Packer\n * bin-packing algorithm\n */\n\n( function( window, factory ) {\n  \n  // universal module definition\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( 'packery/js/packer',[ './rect' ], factory );\n  } else if ( typeof exports == 'object' ) {\n    // CommonJS\n    module.exports = factory(\n      require('./rect')\n    );\n  } else {\n    // browser global\n    var Packery = window.Packery = window.Packery || {};\n    Packery.Packer = factory( Packery.Rect );\n  }\n\n}( window, function factory( Rect ) {\n\n\n// -------------------------- Packer -------------------------- //\n\n/**\n * @param {Number} width\n * @param {Number} height\n * @param {String} sortDirection\n *   topLeft for vertical, leftTop for horizontal\n */\nfunction Packer( width, height, sortDirection ) {\n  this.width = width || 0;\n  this.height = height || 0;\n  this.sortDirection = sortDirection || 'downwardLeftToRight';\n\n  this.reset();\n}\n\nPacker.prototype.reset = function() {\n  this.spaces = [];\n  this.newSpaces = [];\n\n  var initialSpace = new Rect({\n    x: 0,\n    y: 0,\n    width: this.width,\n    height: this.height\n  });\n\n  this.spaces.push( initialSpace );\n  // set sorter\n  this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight;\n};\n\n// change x and y of rect to fit with in Packer's available spaces\nPacker.prototype.pack = function( rect ) {\n  for ( var i=0, len = this.spaces.length; i < len; i++ ) {\n    var space = this.spaces[i];\n    if ( space.canFit( rect ) ) {\n      this.placeInSpace( rect, space );\n      break;\n    }\n  }\n};\n\nPacker.prototype.placeInSpace = function( rect, space ) {\n  // place rect in space\n  rect.x = space.x;\n  rect.y = space.y;\n\n  this.placed( rect );\n};\n\n// update spaces with placed rect\nPacker.prototype.placed = function( rect ) {\n  // update spaces\n  var revisedSpaces = [];\n  for ( var i=0, len = this.spaces.length; i < len; i++ ) {\n    var space = this.spaces[i];\n    var newSpaces = space.getMaximalFreeRects( rect );\n    // add either the original space or the new spaces to the revised spaces\n    if ( newSpaces ) {\n      revisedSpaces.push.apply( revisedSpaces, newSpaces );\n    } else {\n      revisedSpaces.push( space );\n    }\n  }\n\n  this.spaces = revisedSpaces;\n\n  this.mergeSortSpaces();\n};\n\nPacker.prototype.mergeSortSpaces = function() {\n  // remove redundant spaces\n  Packer.mergeRects( this.spaces );\n  this.spaces.sort( this.sorter );\n};\n\n// add a space back\nPacker.prototype.addSpace = function( rect ) {\n  this.spaces.push( rect );\n  this.mergeSortSpaces();\n};\n\n// -------------------------- utility functions -------------------------- //\n\n/**\n * Remove redundant rectangle from array of rectangles\n * @param {Array} rects: an array of Rects\n * @returns {Array} rects: an array of Rects\n**/\nPacker.mergeRects = function( rects ) {\n  for ( var i=0, len = rects.length; i < len; i++ ) {\n    var rect = rects[i];\n    // skip over this rect if it was already removed\n    if ( !rect ) {\n      continue;\n    }\n    // clone rects we're testing, remove this rect\n    var compareRects = rects.slice(0);\n    // do not compare with self\n    compareRects.splice( i, 1 );\n    // compare this rect with others\n    var removedCount = 0;\n    for ( var j=0, jLen = compareRects.length; j < jLen; j++ ) {\n      var compareRect = compareRects[j];\n      // if this rect contains another,\n      // remove that rect from test collection\n      var indexAdjust = i > j ? 0 : 1;\n      if ( rect.contains( compareRect ) ) {\n        // console.log( 'current test rects:' + testRects.length, testRects );\n        // console.log( i, j, indexAdjust, rect, compareRect );\n        rects.splice( j + indexAdjust - removedCount, 1 );\n        removedCount++;\n      }\n    }\n  }\n\n  return rects;\n};\n\n\n// -------------------------- sorters -------------------------- //\n\n// functions for sorting rects in order\nvar sorters = {\n  // top down, then left to right\n  downwardLeftToRight: function( a, b ) {\n    return a.y - b.y || a.x - b.x;\n  },\n  // left to right, then top down\n  rightwardTopToBottom: function( a, b ) {\n    return a.x - b.x || a.y - b.y;\n  }\n};\n\n\n// --------------------------  -------------------------- //\n\nreturn Packer;\n\n}));\n/**\n * Packery Item Element\n**/\n\n( function( window, factory ) {\n  \n  // universal module definition\n\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( 'packery/js/item',[\n        'get-style-property/get-style-property',\n        'outlayer/outlayer',\n        './rect'\n      ],\n      factory );\n  } else if ( typeof exports == 'object' ) {\n    // CommonJS\n    module.exports = factory(\n      require('desandro-get-style-property'),\n      require('outlayer'),\n      require('./rect')\n    );\n  } else {\n    // browser global\n    window.Packery.Item = factory(\n      window.getStyleProperty,\n      window.Outlayer,\n      window.Packery.Rect\n    );\n  }\n\n}( window, function factory( getStyleProperty, Outlayer, Rect ) {\n\n\n// -------------------------- Item -------------------------- //\n\nvar transformProperty = getStyleProperty('transform');\n\n// sub-class Item\nvar Item = function PackeryItem() {\n  Outlayer.Item.apply( this, arguments );\n};\n\nItem.prototype = new Outlayer.Item();\n\nvar protoCreate = Item.prototype._create;\nItem.prototype._create = function() {\n  // call default _create logic\n  protoCreate.call( this );\n  this.rect = new Rect();\n  // rect used for placing, in drag or Packery.fit()\n  this.placeRect = new Rect();\n};\n\n// -------------------------- drag -------------------------- //\n\nItem.prototype.dragStart = function() {\n  this.getPosition();\n  this.removeTransitionStyles();\n  // remove transform property from transition\n  if ( this.isTransitioning && transformProperty ) {\n    this.element.style[ transformProperty ] = 'none';\n  }\n  this.getSize();\n  // create place rect, used for position when dragged then dropped\n  // or when positioning\n  this.isPlacing = true;\n  this.needsPositioning = false;\n  this.positionPlaceRect( this.position.x, this.position.y );\n  this.isTransitioning = false;\n  this.didDrag = false;\n};\n\n/**\n * handle item when it is dragged\n * @param {Number} x - horizontal position of dragged item\n * @param {Number} y - vertical position of dragged item\n */\nItem.prototype.dragMove = function( x, y ) {\n  this.didDrag = true;\n  var packerySize = this.layout.size;\n  x -= packerySize.paddingLeft;\n  y -= packerySize.paddingTop;\n  this.positionPlaceRect( x, y );\n};\n\nItem.prototype.dragStop = function() {\n  this.getPosition();\n  var isDiffX = this.position.x != this.placeRect.x;\n  var isDiffY = this.position.y != this.placeRect.y;\n  // set post-drag positioning flag\n  this.needsPositioning = isDiffX || isDiffY;\n  // reset flag\n  this.didDrag = false;\n};\n\n// -------------------------- placing -------------------------- //\n\n/**\n * position a rect that will occupy space in the packer\n * @param {Number} x\n * @param {Number} y\n * @param {Boolean} isMaxYContained\n */\nItem.prototype.positionPlaceRect = function( x, y, isMaxYOpen ) {\n  this.placeRect.x = this.getPlaceRectCoord( x, true );\n  this.placeRect.y = this.getPlaceRectCoord( y, false, isMaxYOpen );\n};\n\n/**\n * get x/y coordinate for place rect\n * @param {Number} coord - x or y\n * @param {Boolean} isX\n * @param {Boolean} isMaxOpen - does not limit value to outer bound\n * @returns {Number} coord - processed x or y\n */\nItem.prototype.getPlaceRectCoord = function( coord, isX, isMaxOpen ) {\n  var measure = isX ? 'Width' : 'Height';\n  var size = this.size[ 'outer' + measure ];\n  var segment = this.layout[ isX ? 'columnWidth' : 'rowHeight' ];\n  var parentSize = this.layout.size[ 'inner' + measure ];\n\n  // additional parentSize calculations for Y\n  if ( !isX ) {\n    parentSize = Math.max( parentSize, this.layout.maxY );\n    // prevent gutter from bumping up height when non-vertical grid\n    if ( !this.layout.rowHeight ) {\n      parentSize -= this.layout.gutter;\n    }\n  }\n\n  var max;\n\n  if ( segment ) {\n    segment += this.layout.gutter;\n    // allow for last column to reach the edge\n    parentSize += isX ? this.layout.gutter : 0;\n    // snap to closest segment\n    coord = Math.round( coord / segment );\n    // contain to outer bound\n    // contain non-growing bound, allow growing bound to grow\n    var mathMethod;\n    if ( this.layout.options.isHorizontal ) {\n      mathMethod = !isX ? 'floor' : 'ceil';\n    } else {\n      mathMethod = isX ? 'floor' : 'ceil';\n    }\n    var maxSegments = Math[ mathMethod ]( parentSize / segment );\n    maxSegments -= Math.ceil( size / segment );\n    max = maxSegments;\n  } else {\n    max = parentSize - size;\n  }\n\n  coord = isMaxOpen ? coord : Math.min( coord, max );\n  coord *= segment || 1;\n\n  return Math.max( 0, coord );\n};\n\nItem.prototype.copyPlaceRectPosition = function() {\n  this.rect.x = this.placeRect.x;\n  this.rect.y = this.placeRect.y;\n};\n\n// -----  ----- //\n\n// remove element from DOM\nItem.prototype.removeElem = function() {\n  this.element.parentNode.removeChild( this.element );\n  // add space back to packer\n  this.layout.packer.addSpace( this.rect );\n  this.emitEvent( 'remove', [ this ] );\n};\n\n// -----  ----- //\n\nreturn Item;\n\n}));\n\n/*!\n * Packery v1.4.3\n * bin-packing layout library\n *\n * Licensed GPLv3 for open source use\n * or Flickity Commercial License for commercial use\n *\n * http://packery.metafizzy.co\n * Copyright 2015 Metafizzy\n */\n\n( function( window, factory ) {\n  \n  // universal module definition\n  if ( typeof define == 'function' && define.amd ) {\n    // AMD\n    define( [\n        'classie/classie',\n        'get-size/get-size',\n        'outlayer/outlayer',\n        'packery/js/rect',\n        'packery/js/packer',\n        'packery/js/item'\n      ],\n      factory );\n  } else if ( typeof exports == 'object' ) {\n    // CommonJS\n    module.exports = factory(\n      require('desandro-classie'),\n      require('get-size'),\n      require('outlayer'),\n      require('./rect'),\n      require('./packer'),\n      require('./item')\n    );\n  } else {\n    // browser global\n    window.Packery = factory(\n      window.classie,\n      window.getSize,\n      window.Outlayer,\n      window.Packery.Rect,\n      window.Packery.Packer,\n      window.Packery.Item\n    );\n  }\n\n}( window, function factory( classie, getSize, Outlayer, Rect, Packer, Item ) {\n\n\n// ----- Rect ----- //\n\n// allow for pixel rounding errors IE8-IE11 & Firefox; #227\nRect.prototype.canFit = function( rect ) {\n  return this.width >= rect.width - 1 && this.height >= rect.height - 1;\n};\n\n// -------------------------- Packery -------------------------- //\n\n// create an Outlayer layout class\nvar Packery = Outlayer.create('packery');\nPackery.Item = Item;\n\nPackery.prototype._create = function() {\n  // call super\n  Outlayer.prototype._create.call( this );\n\n  // initial properties\n  this.packer = new Packer();\n\n  // Left over from v1.0\n  this.stamp( this.options.stamped );\n\n  // create drag handlers\n  var _this = this;\n  this.handleDraggabilly = {\n    dragStart: function() {\n      _this.itemDragStart( this.element );\n    },\n    dragMove: function() {\n      _this.itemDragMove( this.element, this.position.x, this.position.y );\n    },\n    dragEnd: function() {\n      _this.itemDragEnd( this.element );\n    }\n  };\n\n  this.handleUIDraggable = {\n    start: function handleUIDraggableStart( event, ui ) {\n      // HTML5 may trigger dragstart, dismiss HTML5 dragging\n      if ( !ui ) {\n        return;\n      }\n      _this.itemDragStart( event.currentTarget );\n    },\n    drag: function handleUIDraggableDrag( event, ui ) {\n      if ( !ui ) {\n        return;\n      }\n      _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top );\n    },\n    stop: function handleUIDraggableStop( event, ui ) {\n      if ( !ui ) {\n        return;\n      }\n      _this.itemDragEnd( event.currentTarget );\n    }\n  };\n\n};\n\n\n// ----- init & layout ----- //\n\n/**\n * logic before any new layout\n */\nPackery.prototype._resetLayout = function() {\n  this.getSize();\n\n  this._getMeasurements();\n\n  // reset packer\n  var packer = this.packer;\n  // packer settings, if horizontal or vertical\n  if ( this.options.isHorizontal ) {\n    packer.width = Number.POSITIVE_INFINITY;\n    packer.height = this.size.innerHeight + this.gutter;\n    packer.sortDirection = 'rightwardTopToBottom';\n  } else {\n    packer.width = this.size.innerWidth + this.gutter;\n    packer.height = Number.POSITIVE_INFINITY;\n    packer.sortDirection = 'downwardLeftToRight';\n  }\n\n  packer.reset();\n\n  // layout\n  this.maxY = 0;\n  this.maxX = 0;\n};\n\n/**\n * update columnWidth, rowHeight, & gutter\n * @private\n */\nPackery.prototype._getMeasurements = function() {\n  this._getMeasurement( 'columnWidth', 'width' );\n  this._getMeasurement( 'rowHeight', 'height' );\n  this._getMeasurement( 'gutter', 'width' );\n};\n\nPackery.prototype._getItemLayoutPosition = function( item ) {\n  this._packItem( item );\n  return item.rect;\n};\n\n\n/**\n * layout item in packer\n * @param {Packery.Item} item\n */\nPackery.prototype._packItem = function( item ) {\n  this._setRectSize( item.element, item.rect );\n  // pack the rect in the packer\n  this.packer.pack( item.rect );\n  this._setMaxXY( item.rect );\n};\n\n/**\n * set max X and Y value, for size of container\n * @param {Packery.Rect} rect\n * @private\n */\nPackery.prototype._setMaxXY = function( rect ) {\n  this.maxX = Math.max( rect.x + rect.width, this.maxX );\n  this.maxY = Math.max( rect.y + rect.height, this.maxY );\n};\n\n/**\n * set the width and height of a rect, applying columnWidth and rowHeight\n * @param {Element} elem\n * @param {Packery.Rect} rect\n */\nPackery.prototype._setRectSize = function( elem, rect ) {\n  var size = getSize( elem );\n  var w = size.outerWidth;\n  var h = size.outerHeight;\n  // size for columnWidth and rowHeight, if available\n  // only check if size is non-zero, #177\n  if ( w || h ) {\n    w = this._applyGridGutter( w, this.columnWidth );\n    h = this._applyGridGutter( h, this.rowHeight );\n  }\n  // rect must fit in packer\n  rect.width = Math.min( w, this.packer.width );\n  rect.height = Math.min( h, this.packer.height );\n};\n\n/**\n * fits item to columnWidth/rowHeight and adds gutter\n * @param {Number} measurement - item width or height\n * @param {Number} gridSize - columnWidth or rowHeight\n * @returns measurement\n */\nPackery.prototype._applyGridGutter = function( measurement, gridSize ) {\n  // just add gutter if no gridSize\n  if ( !gridSize ) {\n    return measurement + this.gutter;\n  }\n  gridSize += this.gutter;\n  // fit item to columnWidth/rowHeight\n  var remainder = measurement % gridSize;\n  var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';\n  measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize;\n  return measurement;\n};\n\nPackery.prototype._getContainerSize = function() {\n  if ( this.options.isHorizontal ) {\n    return {\n      width: this.maxX - this.gutter\n    };\n  } else {\n    return {\n      height: this.maxY - this.gutter\n    };\n  }\n};\n\n\n// -------------------------- stamp -------------------------- //\n\n/**\n * makes space for element\n * @param {Element} elem\n */\nPackery.prototype._manageStamp = function( elem ) {\n\n  var item = this.getItem( elem );\n  var rect;\n  if ( item && item.isPlacing ) {\n    rect = item.placeRect;\n  } else {\n    var offset = this._getElementOffset( elem );\n    rect = new Rect({\n      x: this.options.isOriginLeft ? offset.left : offset.right,\n      y: this.options.isOriginTop ? offset.top : offset.bottom\n    });\n  }\n\n  this._setRectSize( elem, rect );\n  // save its space in the packer\n  this.packer.placed( rect );\n  this._setMaxXY( rect );\n};\n\n// -------------------------- methods -------------------------- //\n\nfunction verticalSorter( a, b ) {\n  return a.position.y - b.position.y || a.position.x - b.position.x;\n}\n\nfunction horizontalSorter( a, b ) {\n  return a.position.x - b.position.x || a.position.y - b.position.y;\n}\n\nPackery.prototype.sortItemsByPosition = function() {\n  var sorter = this.options.isHorizontal ? horizontalSorter : verticalSorter;\n  this.items.sort( sorter );\n};\n\n/**\n * Fit item element in its current position\n * Packery will position elements around it\n * useful for expanding elements\n *\n * @param {Element} elem\n * @param {Number} x - horizontal destination position, optional\n * @param {Number} y - vertical destination position, optional\n */\nPackery.prototype.fit = function( elem, x, y ) {\n  var item = this.getItem( elem );\n  if ( !item ) {\n    return;\n  }\n\n  // prepare internal properties\n  this._getMeasurements();\n\n  // stamp item to get it out of layout\n  this.stamp( item.element );\n  // required for positionPlaceRect\n  item.getSize();\n  // set placing flag\n  item.isPlacing = true;\n  // fall back to current position for fitting\n  x = x === undefined ? item.rect.x: x;\n  y = y === undefined ? item.rect.y: y;\n\n  // position it best at its destination\n  item.positionPlaceRect( x, y, true );\n\n  this._bindFitEvents( item );\n  item.moveTo( item.placeRect.x, item.placeRect.y );\n  // layout everything else\n  this.layout();\n\n  // return back to regularly scheduled programming\n  this.unstamp( item.element );\n  this.sortItemsByPosition();\n  // un set placing flag, back to normal\n  item.isPlacing = false;\n  // copy place rect position\n  item.copyPlaceRectPosition();\n};\n\n/**\n * emit event when item is fit and other items are laid out\n * @param {Packery.Item} item\n * @private\n */\nPackery.prototype._bindFitEvents = function( item ) {\n  var _this = this;\n  var ticks = 0;\n  function tick() {\n    ticks++;\n    if ( ticks != 2 ) {\n      return;\n    }\n    _this.dispatchEvent( 'fitComplete', null, [ item ] );\n  }\n  // when item is laid out\n  item.on( 'layout', function() {\n    tick();\n    return true;\n  });\n  // when all items are laid out\n  this.on( 'layoutComplete', function() {\n    tick();\n    return true;\n  });\n};\n\n// -------------------------- resize -------------------------- //\n\n// debounced, layout on resize\nPackery.prototype.resize = function() {\n  // don't trigger if size did not change\n  var size = getSize( this.element );\n  // check that this.size and size are there\n  // IE8 triggers resize on body size change, so they might not be\n  var hasSizes = this.size && size;\n  var innerSize = this.options.isHorizontal ? 'innerHeight' : 'innerWidth';\n  if ( hasSizes && size[ innerSize ] == this.size[ innerSize ] ) {\n    return;\n  }\n\n  this.layout();\n};\n\n// -------------------------- drag -------------------------- //\n\n/**\n * handle an item drag start event\n * @param {Element} elem\n */\nPackery.prototype.itemDragStart = function( elem ) {\n  this.stamp( elem );\n  var item = this.getItem( elem );\n  if ( item ) {\n    item.dragStart();\n  }\n};\n\n/**\n * handle an item drag move event\n * @param {Element} elem\n * @param {Number} x - horizontal change in position\n * @param {Number} y - vertical change in position\n */\nPackery.prototype.itemDragMove = function( elem, x, y ) {\n  var item = this.getItem( elem );\n  if ( item ) {\n    item.dragMove( x, y );\n  }\n\n  // debounce\n  var _this = this;\n  // debounce triggering layout\n  function delayed() {\n    _this.layout();\n    delete _this.dragTimeout;\n  }\n\n  this.clearDragTimeout();\n\n  this.dragTimeout = setTimeout( delayed, 40 );\n};\n\nPackery.prototype.clearDragTimeout = function() {\n  if ( this.dragTimeout ) {\n    clearTimeout( this.dragTimeout );\n  }\n};\n\n/**\n * handle an item drag end event\n * @param {Element} elem\n */\nPackery.prototype.itemDragEnd = function( elem ) {\n  var item = this.getItem( elem );\n  var itemDidDrag;\n  if ( item ) {\n    itemDidDrag = item.didDrag;\n    item.dragStop();\n  }\n  // if elem didn't move, or if it doesn't need positioning\n  // unignore and unstamp and call it a day\n  if ( !item || ( !itemDidDrag && !item.needsPositioning ) ) {\n    this.unstamp( elem );\n    return;\n  }\n  // procced with dragged item\n\n  classie.add( item.element, 'is-positioning-post-drag' );\n\n  // save this var, as it could get reset in dragStart\n  var onLayoutComplete = this._getDragEndLayoutComplete( elem, item );\n\n  if ( item.needsPositioning ) {\n    item.on( 'layout', onLayoutComplete );\n    item.moveTo( item.placeRect.x, item.placeRect.y );\n  } else if ( item ) {\n    // item didn't need placement\n    item.copyPlaceRectPosition();\n  }\n\n  this.clearDragTimeout();\n  this.on( 'layoutComplete', onLayoutComplete );\n  this.layout();\n\n};\n\n/**\n * get drag end callback\n * @param {Element} elem\n * @param {Packery.Item} item\n * @returns {Function} onLayoutComplete\n */\nPackery.prototype._getDragEndLayoutComplete = function( elem, item ) {\n  var itemNeedsPositioning = item && item.needsPositioning;\n  var completeCount = 0;\n  var asyncCount = itemNeedsPositioning ? 2 : 1;\n  var _this = this;\n\n  return function onLayoutComplete() {\n    completeCount++;\n    // don't proceed if not complete\n    if ( completeCount != asyncCount ) {\n      return true;\n    }\n    // reset item\n    if ( item ) {\n      classie.remove( item.element, 'is-positioning-post-drag' );\n      item.isPlacing = false;\n      item.copyPlaceRectPosition();\n    }\n\n    _this.unstamp( elem );\n    // only sort when item moved\n    _this.sortItemsByPosition();\n\n    // emit item drag event now that everything is done\n    if ( itemNeedsPositioning ) {\n      _this.dispatchEvent( 'dragItemPositioned', null, [ item ] );\n    }\n    // listen once\n    return true;\n  };\n};\n\n/**\n * binds Draggabilly events\n * @param {Draggabilly} draggie\n */\nPackery.prototype.bindDraggabillyEvents = function( draggie ) {\n  draggie.on( 'dragStart', this.handleDraggabilly.dragStart );\n  draggie.on( 'dragMove', this.handleDraggabilly.dragMove );\n  draggie.on( 'dragEnd', this.handleDraggabilly.dragEnd );\n};\n\n/**\n * binds jQuery UI Draggable events\n * @param {jQuery} $elems\n */\nPackery.prototype.bindUIDraggableEvents = function( $elems ) {\n  $elems\n    .on( 'dragstart', this.handleUIDraggable.start )\n    .on( 'drag', this.handleUIDraggable.drag )\n    .on( 'dragstop', this.handleUIDraggable.stop );\n};\n\nPackery.Rect = Rect;\nPackery.Packer = Packer;\n\nreturn Packery;\n\n}));\n\n","Smartwave_Porto/js/animate.js":"/**\n *\n * Do not edit or add to this file if you wish to upgrade this extension to newer\n * version in the future.\n *\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    \"use strict\";\n    theme = theme || {};\n\n    $.extend(theme, {\n  \t\trequestTimeout: function(fn, delay) {\n  \t\t\tvar handler = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;\n  \t\t\tif ( ! handler ) {\n  \t\t\t\treturn setTimeout(fn, delay);\n  \t\t\t}\n  \t\t\tvar start, rt = new Object();\n\n  \t\t\tfunction loop( timestamp ) {\n  \t\t\t\tif ( ! start ) {\n  \t\t\t\t\tstart = timestamp;\n  \t\t\t\t}\n  \t\t\t\tvar progress = timestamp - start;\n  \t\t\t\tprogress >= delay ? fn.call() : rt.val = handler( loop );\n  \t\t\t};\n\n  \t\t\trt.val = handler( loop );\n  \t\t\treturn rt;\n  \t\t}\n  \t});\n\n  \tvar instanceName = '__animate';\n\n  \tvar Animate = function($el, opts) {\n  \t\treturn this.initialize($el, opts);\n  \t};\n\n  \tAnimate.defaults = {\n  \t\taccX: 0,\n  \t\taccY: -120,\n  \t\tdelay: 1,\n  \t\tduration: 1000\n  \t};\n\n  \tAnimate.prototype = {\n  \t\tinitialize: function($el, opts) {\n  \t\t\tif ($el.data(instanceName)) {\n  \t\t\t\treturn this;\n  \t\t\t}\n\n  \t\t\tthis.$el = $el;\n\n  \t\t\tthis\n  \t\t\t\t.setData()\n  \t\t\t\t.setOptions(opts)\n  \t\t\t\t.build();\n\n  \t\t\treturn this;\n  \t\t},\n\n  \t\tsetData: function() {\n  \t\t\tthis.$el.data(instanceName, true);\n\n  \t\t\treturn this;\n  \t\t},\n\n  \t\tsetOptions: function(opts) {\n  \t\t\tthis.options = $.extend(true, {}, Animate.defaults, opts, {\n  \t\t\t\twrapper: this.$el\n  \t\t\t});\n\n  \t\t\treturn this;\n  \t\t},\n\n  \t\tbuild: function() {\n  \t\t\tvar self = this,\n  \t\t\t\t$el = this.options.wrapper,\n  \t\t\t\tdelay = 0,\n  \t\t\t\tduration = 0;\n\n  \t\t\t$el.addClass('appear-animation');\n  \t\t\tif (!$('html').hasClass('no-csstransitions') && window.innerWidth > 767) {\n  \t\t\t\tvar el_obj = $el.get(0);\n\n  \t\t\t\ttheme.appear(el_obj, function() {\n  \t\t\t\t\tdelay = Math.abs($el.data('appear-animation-delay') ? $el.data('appear-animation-delay') : self.options.delay);\n  \t\t\t\t\tif (delay > 1) {\n  \t\t\t\t\t\tel_obj.style.animationDelay = delay + 'ms';\n  \t\t\t\t\t}\n\n  \t\t\t\t\tduration = Math.abs($el.data('appear-animation-duration') ? $el.data('appear-animation-duration') : self.options.duration);\n  \t\t\t\t\tif (duration != 1000) {\n  \t\t\t\t\t\tel_obj.style.animationDuration = duration + 'ms';\n  \t\t\t\t\t}\n\n  \t\t\t\t\tif ($el.find('.porto-lazyload:not(.lazy-load-loaded)').length) {\n  \t\t\t\t\t\t$el.find('.porto-lazyload:not(.lazy-load-loaded)').trigger('appear');\n  \t\t\t\t\t}\n  \t\t\t\t\t$el.addClass($el.data('appear-animation') + ' appear-animation-visible');\n\n  \t\t\t\t}, {\n  \t\t\t\t\taccX: self.options.accX,\n  \t\t\t\t\taccY: self.options.accY\n  \t\t\t\t});\n\n  \t\t\t} else {\n  \t\t\t\t$el.addClass('appear-animation-visible');\n  \t\t\t}\n\n  \t\t\treturn this;\n  \t\t}\n  \t};\n\n  \t// expose to scope\n  \t$.extend(theme, {\n  \t\tAnimate: Animate\n  \t});\n\n  \t// jquery plugin\n  \t$.fn.themeAnimate = function(opts) {\n  \t\treturn this.map(function() {\n  \t\t\tvar $this = $(this);\n\n  \t\t\tif ($this.data(instanceName)) {\n  \t\t\t\treturn $this;\n  \t\t\t} else {\n  \t\t\t\treturn new theme.Animate($this, opts);\n  \t\t\t}\n\n  \t\t});\n  \t};\n});\n","Smartwave_Porto/js/imagesloaded.js":"/*!\n * imagesLoaded PACKAGED v5.0.0\n * JavaScript is all like \"You images are done yet or what?\"\n * MIT License\n */\n\n/**\n * EvEmitter v2.1.1\n * Lil' event emitter\n * MIT License\n */\n\n( function( global, factory ) {\n  // universal module definition\n  if ( typeof module == 'object' && module.exports ) {\n    // CommonJS - Browserify, Webpack\n    module.exports = factory();\n  } else {\n    // Browser globals\n    global.EvEmitter = factory();\n  }\n\n}( typeof window != 'undefined' ? window : this, function() {\n\nfunction EvEmitter() {}\n\nlet proto = EvEmitter.prototype;\n\nproto.on = function( eventName, listener ) {\n  if ( !eventName || !listener ) return this;\n\n  // set events hash\n  let events = this._events = this._events || {};\n  // set listeners array\n  let listeners = events[ eventName ] = events[ eventName ] || [];\n  // only add once\n  if ( !listeners.includes( listener ) ) {\n    listeners.push( listener );\n  }\n\n  return this;\n};\n\nproto.once = function( eventName, listener ) {\n  if ( !eventName || !listener ) return this;\n\n  // add event\n  this.on( eventName, listener );\n  // set once flag\n  // set onceEvents hash\n  let onceEvents = this._onceEvents = this._onceEvents || {};\n  // set onceListeners object\n  let onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};\n  // set flag\n  onceListeners[ listener ] = true;\n\n  return this;\n};\n\nproto.off = function( eventName, listener ) {\n  let listeners = this._events && this._events[ eventName ];\n  if ( !listeners || !listeners.length ) return this;\n\n  let index = listeners.indexOf( listener );\n  if ( index != -1 ) {\n    listeners.splice( index, 1 );\n  }\n\n  return this;\n};\n\nproto.emitEvent = function( eventName, args ) {\n  let listeners = this._events && this._events[ eventName ];\n  if ( !listeners || !listeners.length ) return this;\n\n  // copy over to avoid interference if .off() in listener\n  listeners = listeners.slice( 0 );\n  args = args || [];\n  // once stuff\n  let onceListeners = this._onceEvents && this._onceEvents[ eventName ];\n\n  for ( let listener of listeners ) {\n    let isOnce = onceListeners && onceListeners[ listener ];\n    if ( isOnce ) {\n      // remove listener\n      // remove before trigger to prevent recursion\n      this.off( eventName, listener );\n      // unset once flag\n      delete onceListeners[ listener ];\n    }\n    // trigger listener\n    listener.apply( this, args );\n  }\n\n  return this;\n};\n\nproto.allOff = function() {\n  delete this._events;\n  delete this._onceEvents;\n  return this;\n};\n\nreturn EvEmitter;\n\n} ) );\n/*!\n * imagesLoaded v5.0.0\n * JavaScript is all like \"You images are done yet or what?\"\n * MIT License\n */\n\n( function( window, factory ) {\n  // universal module definition\n  if ( typeof module == 'object' && module.exports ) {\n    // CommonJS\n    module.exports = factory( window, require('ev-emitter') );\n  } else {\n    // browser global\n    window.imagesLoaded = factory( window, window.EvEmitter );\n  }\n\n} )( typeof window !== 'undefined' ? window : this,\n    function factory( window, EvEmitter ) {\n\nlet $ = window.jQuery;\nlet console = window.console;\n\n// -------------------------- helpers -------------------------- //\n\n// turn element or nodeList into an array\nfunction makeArray( obj ) {\n  // use object if already an array\n  if ( Array.isArray( obj ) ) return obj;\n\n  let isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';\n  // convert nodeList to array\n  if ( isArrayLike ) return [ ...obj ];\n\n  // array of single index\n  return [ obj ];\n}\n\n// -------------------------- imagesLoaded -------------------------- //\n\n/**\n * @param {[Array, Element, NodeList, String]} elem\n * @param {[Object, Function]} options - if function, use as callback\n * @param {Function} onAlways - callback function\n * @returns {ImagesLoaded}\n */\nfunction ImagesLoaded( elem, options, onAlways ) {\n  // coerce ImagesLoaded() without new, to be new ImagesLoaded()\n  if ( !( this instanceof ImagesLoaded ) ) {\n    return new ImagesLoaded( elem, options, onAlways );\n  }\n  // use elem as selector string\n  let queryElem = elem;\n  if ( typeof elem == 'string' ) {\n    queryElem = document.querySelectorAll( elem );\n  }\n  // bail if bad element\n  if ( !queryElem ) {\n    console.error(`Bad element for imagesLoaded ${queryElem || elem}`);\n    return;\n  }\n\n  this.elements = makeArray( queryElem );\n  this.options = {};\n  // shift arguments if no options set\n  if ( typeof options == 'function' ) {\n    onAlways = options;\n  } else {\n    Object.assign( this.options, options );\n  }\n\n  if ( onAlways ) this.on( 'always', onAlways );\n\n  this.getImages();\n  // add jQuery Deferred object\n  if ( $ ) this.jqDeferred = new $.Deferred();\n\n  // HACK check async to allow time to bind listeners\n  setTimeout( this.check.bind( this ) );\n}\n\nImagesLoaded.prototype = Object.create( EvEmitter.prototype );\n\nImagesLoaded.prototype.getImages = function() {\n  this.images = [];\n\n  // filter & find items if we have an item selector\n  this.elements.forEach( this.addElementImages, this );\n};\n\nconst elementNodeTypes = [ 1, 9, 11 ];\n\n/**\n * @param {Node} elem\n */\nImagesLoaded.prototype.addElementImages = function( elem ) {\n  // filter siblings\n  if ( elem.nodeName === 'IMG' ) {\n    this.addImage( elem );\n  }\n  // get background image on element\n  if ( this.options.background === true ) {\n    this.addElementBackgroundImages( elem );\n  }\n\n  // find children\n  // no non-element nodes, #143\n  let { nodeType } = elem;\n  if ( !nodeType || !elementNodeTypes.includes( nodeType ) ) return;\n\n  let childImgs = elem.querySelectorAll('img');\n  // concat childElems to filterFound array\n  for ( let img of childImgs ) {\n    this.addImage( img );\n  }\n\n  // get child background images\n  if ( typeof this.options.background == 'string' ) {\n    let children = elem.querySelectorAll( this.options.background );\n    for ( let child of children ) {\n      this.addElementBackgroundImages( child );\n    }\n  }\n};\n\nconst reURL = /url\\((['\"])?(.*?)\\1\\)/gi;\n\nImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {\n  let style = getComputedStyle( elem );\n  // Firefox returns null if in a hidden iframe https://bugzil.la/548397\n  if ( !style ) return;\n\n  // get url inside url(\"...\")\n  let matches = reURL.exec( style.backgroundImage );\n  while ( matches !== null ) {\n    let url = matches && matches[2];\n    if ( url ) {\n      this.addBackground( url, elem );\n    }\n    matches = reURL.exec( style.backgroundImage );\n  }\n};\n\n/**\n * @param {Image} img\n */\nImagesLoaded.prototype.addImage = function( img ) {\n  let loadingImage = new LoadingImage( img );\n  this.images.push( loadingImage );\n};\n\nImagesLoaded.prototype.addBackground = function( url, elem ) {\n  let background = new Background( url, elem );\n  this.images.push( background );\n};\n\nImagesLoaded.prototype.check = function() {\n  this.progressedCount = 0;\n  this.hasAnyBroken = false;\n  // complete if no images\n  if ( !this.images.length ) {\n    this.complete();\n    return;\n  }\n\n  /* eslint-disable-next-line func-style */\n  let onProgress = ( image, elem, message ) => {\n    // HACK - Chrome triggers event before object properties have changed. #83\n    setTimeout( () => {\n      this.progress( image, elem, message );\n    } );\n  };\n\n  this.images.forEach( function( loadingImage ) {\n    loadingImage.once( 'progress', onProgress );\n    loadingImage.check();\n  } );\n};\n\nImagesLoaded.prototype.progress = function( image, elem, message ) {\n  this.progressedCount++;\n  this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;\n  // progress event\n  this.emitEvent( 'progress', [ this, image, elem ] );\n  if ( this.jqDeferred && this.jqDeferred.notify ) {\n    this.jqDeferred.notify( this, image );\n  }\n  // check if completed\n  if ( this.progressedCount === this.images.length ) {\n    this.complete();\n  }\n\n  if ( this.options.debug && console ) {\n    console.log( `progress: ${message}`, image, elem );\n  }\n};\n\nImagesLoaded.prototype.complete = function() {\n  let eventName = this.hasAnyBroken ? 'fail' : 'done';\n  this.isComplete = true;\n  this.emitEvent( eventName, [ this ] );\n  this.emitEvent( 'always', [ this ] );\n  if ( this.jqDeferred ) {\n    let jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';\n    this.jqDeferred[ jqMethod ]( this );\n  }\n};\n\n// --------------------------  -------------------------- //\n\nfunction LoadingImage( img ) {\n  this.img = img;\n}\n\nLoadingImage.prototype = Object.create( EvEmitter.prototype );\n\nLoadingImage.prototype.check = function() {\n  // If complete is true and browser supports natural sizes,\n  // try to check for image status manually.\n  let isComplete = this.getIsImageComplete();\n  if ( isComplete ) {\n    // report based on naturalWidth\n    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );\n    return;\n  }\n\n  // If none of the checks above matched, simulate loading on detached element.\n  this.proxyImage = new Image();\n  // add crossOrigin attribute. #204\n  if ( this.img.crossOrigin ) {\n    this.proxyImage.crossOrigin = this.img.crossOrigin;\n  }\n  this.proxyImage.addEventListener( 'load', this );\n  this.proxyImage.addEventListener( 'error', this );\n  // bind to image as well for Firefox. #191\n  this.img.addEventListener( 'load', this );\n  this.img.addEventListener( 'error', this );\n  this.proxyImage.src = this.img.currentSrc || this.img.src;\n};\n\nLoadingImage.prototype.getIsImageComplete = function() {\n  // check for non-zero, non-undefined naturalWidth\n  // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671\n  return this.img.complete && this.img.naturalWidth;\n};\n\nLoadingImage.prototype.confirm = function( isLoaded, message ) {\n  this.isLoaded = isLoaded;\n  let { parentNode } = this.img;\n  // emit progress with parent <picture> or self <img>\n  let elem = parentNode.nodeName === 'PICTURE' ? parentNode : this.img;\n  this.emitEvent( 'progress', [ this, elem, message ] );\n};\n\n// ----- events ----- //\n\n// trigger specified handler for event type\nLoadingImage.prototype.handleEvent = function( event ) {\n  let method = 'on' + event.type;\n  if ( this[ method ] ) {\n    this[ method ]( event );\n  }\n};\n\nLoadingImage.prototype.onload = function() {\n  this.confirm( true, 'onload' );\n  this.unbindEvents();\n};\n\nLoadingImage.prototype.onerror = function() {\n  this.confirm( false, 'onerror' );\n  this.unbindEvents();\n};\n\nLoadingImage.prototype.unbindEvents = function() {\n  this.proxyImage.removeEventListener( 'load', this );\n  this.proxyImage.removeEventListener( 'error', this );\n  this.img.removeEventListener( 'load', this );\n  this.img.removeEventListener( 'error', this );\n};\n\n// -------------------------- Background -------------------------- //\n\nfunction Background( url, element ) {\n  this.url = url;\n  this.element = element;\n  this.img = new Image();\n}\n\n// inherit LoadingImage prototype\nBackground.prototype = Object.create( LoadingImage.prototype );\n\nBackground.prototype.check = function() {\n  this.img.addEventListener( 'load', this );\n  this.img.addEventListener( 'error', this );\n  this.img.src = this.url;\n  // check if image is already complete\n  let isComplete = this.getIsImageComplete();\n  if ( isComplete ) {\n    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );\n    this.unbindEvents();\n  }\n};\n\nBackground.prototype.unbindEvents = function() {\n  this.img.removeEventListener( 'load', this );\n  this.img.removeEventListener( 'error', this );\n};\n\nBackground.prototype.confirm = function( isLoaded, message ) {\n  this.isLoaded = isLoaded;\n  this.emitEvent( 'progress', [ this, this.element, message ] );\n};\n\n// -------------------------- jQuery -------------------------- //\n\nImagesLoaded.makeJQueryPlugin = function( jQuery ) {\n  jQuery = jQuery || window.jQuery;\n  if ( !jQuery ) return;\n\n  // set local variable\n  $ = jQuery;\n  // $().imagesLoaded()\n  $.fn.imagesLoaded = function( options, onAlways ) {\n    let instance = new ImagesLoaded( this, options, onAlways );\n    return instance.jqDeferred.promise( $( this ) );\n  };\n};\n// try making plugin\nImagesLoaded.makeJQueryPlugin();\n\n// --------------------------  -------------------------- //\n\nreturn ImagesLoaded;\n\n} );\n","Magento_Search/js/form-mini.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'underscore',\n    'mage/template',\n    'matchMedia',\n    'jquery-ui-modules/widget',\n    'jquery-ui-modules/core',\n    'mage/translate'\n], function ($, _, mageTemplate, mediaCheck) {\n    'use strict';\n\n    /**\n     * Check whether the incoming string is not empty or if doesn't consist of spaces.\n     *\n     * @param {String} value - Value to check.\n     * @returns {Boolean}\n     */\n    function isEmpty(value) {\n        return value.length === 0 || value == null || /^\\s+$/.test(value);\n    }\n\n    $.widget('mage.quickSearch', {\n        options: {\n            autocomplete: 'off',\n            minSearchLength: 3,\n            responseFieldElements: 'ul li',\n            selectClass: 'selected',\n            template:\n                '<li class=\"<%- data.row_class %>\" id=\"qs-option-<%- data.index %>\" role=\"option\">' +\n                '<span class=\"qs-option-name\">' +\n                ' <%- data.title %>' +\n                '</span>' +\n                '<span aria-hidden=\"true\" class=\"amount\">' +\n                '<%- data.num_results %>' +\n                '</span>' +\n                '</li>',\n            submitBtn: 'button[type=\"submit\"]',\n            searchLabel: '[data-role=minisearch-label]',\n            isExpandable: null,\n            suggestionDelay: 300\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            this.responseList = {\n                indexList: null,\n                selected: null\n            };\n            this.autoComplete = $(this.options.destinationSelector);\n            this.searchForm = $(this.options.formSelector);\n            this.submitBtn = this.searchForm.find(this.options.submitBtn)[0];\n            this.searchLabel = this.searchForm.find(this.options.searchLabel);\n            this.isExpandable = this.options.isExpandable;\n\n            _.bindAll(this, '_onKeyDown', '_onPropertyChange', '_onSubmit');\n\n            this.submitBtn.disabled = true;\n\n            this.element.attr('autocomplete', this.options.autocomplete);\n\n            mediaCheck({\n                media: '(max-width: 768px)',\n                entry: function () {\n                    this.isExpandable = true;\n                }.bind(this),\n                exit: function () {\n                    this.isExpandable = true;\n                }.bind(this)\n            });\n\n            this.searchLabel.on('click', function (e) {\n                // allow input to lose its' focus when clicking on label\n                if (this.isExpandable && this.isActive()) {\n                    e.preventDefault();\n                }\n            }.bind(this));\n\n            this.element.on('blur', $.proxy(function () {\n                if (!this.searchLabel.hasClass('active')) {\n                    return;\n                }\n\n                setTimeout($.proxy(function () {\n                    if (this.autoComplete.is(':hidden')) {\n                        this.setActiveState(false);\n                    } else {\n                        this.element.trigger('focus');\n                    }\n                    this.autoComplete.hide();\n                    this._updateAriaHasPopup(false);\n                }, this), 250);\n            }, this));\n\n            if (this.element.get(0) === document.activeElement) {\n                this.setActiveState(true);\n            }\n\n            this.element.on('focus', this.setActiveState.bind(this, true));\n            this.element.on('keydown', this._onKeyDown);\n            // Prevent spamming the server with requests by waiting till the user has stopped typing for period of time\n            this.element.on('input propertychange', _.debounce(this._onPropertyChange, this.options.suggestionDelay));\n\n            this.searchForm.on('submit', $.proxy(function (e) {\n                this._onSubmit(e);\n                this._updateAriaHasPopup(false);\n            }, this));\n        },\n\n        /**\n         * Checks if search field is active.\n         *\n         * @returns {Boolean}\n         */\n        isActive: function () {\n            return this.searchLabel.hasClass('active');\n        },\n\n        /**\n         * Sets state of the search field to provided value.\n         *\n         * @param {Boolean} isActive\n         */\n        setActiveState: function (isActive) {\n            var searchValue;\n\n            this.searchForm.toggleClass('active', isActive);\n            this.searchLabel.toggleClass('active', isActive);\n\n            if (this.isExpandable) {\n                this.element.attr('aria-expanded', isActive);\n                searchValue = this.element.val();\n                this.element.val('');\n                this.element.val(searchValue);\n            }\n        },\n\n        /**\n         * @private\n         * @return {Element} The first element in the suggestion list.\n         */\n        _getFirstVisibleElement: function () {\n            return this.responseList.indexList ? this.responseList.indexList.first() : false;\n        },\n\n        /**\n         * @private\n         * @return {Element} The last element in the suggestion list.\n         */\n        _getLastElement: function () {\n            return this.responseList.indexList ? this.responseList.indexList.last() : false;\n        },\n\n        /**\n         * @private\n         * @param {Boolean} show - Set attribute aria-haspopup to \"true/false\" for element.\n         */\n        _updateAriaHasPopup: function (show) {\n            if (show) {\n                this.element.attr('aria-haspopup', 'true');\n            } else {\n                this.element.attr('aria-haspopup', 'false');\n            }\n        },\n\n        /**\n         * Clears the item selected from the suggestion list and resets the suggestion list.\n         * @private\n         * @param {Boolean} all - Controls whether to clear the suggestion list.\n         */\n        _resetResponseList: function (all) {\n            this.responseList.selected = null;\n\n            if (all === true) {\n                this.responseList.indexList = null;\n            }\n        },\n\n        /**\n         * Executes when the search box is submitted. Sets the search input field to the\n         * value of the selected item.\n         * @private\n         * @param {Event} e - The submit event\n         */\n        _onSubmit: function (e) {\n            var value = this.element.val();\n\n            if (isEmpty(value)) {\n                e.preventDefault();\n            }\n\n            if (this.responseList.selected) {\n                this.element.val(this.responseList.selected.find('.qs-option-name').text());\n            }\n        },\n\n        /**\n         * Executes when keys are pressed in the search input field. Performs specific actions\n         * depending on which keys are pressed.\n         * @private\n         * @param {Event} e - The key down event\n         * @return {Boolean} Default return type for any unhandled keys\n         */\n        _onKeyDown: function (e) {\n            var keyCode = e.keyCode || e.which;\n\n            switch (keyCode) {\n                case $.ui.keyCode.HOME:\n                    if (this._getFirstVisibleElement()) {\n                        this._getFirstVisibleElement().addClass(this.options.selectClass);\n                        this.responseList.selected = this._getFirstVisibleElement();\n                    }\n                    break;\n\n                case $.ui.keyCode.END:\n                    if (this._getLastElement()) {\n                        this._getLastElement().addClass(this.options.selectClass);\n                        this.responseList.selected = this._getLastElement();\n                    }\n                    break;\n\n                case $.ui.keyCode.ESCAPE:\n                    this._resetResponseList(true);\n                    this.autoComplete.hide();\n                    break;\n\n                case $.ui.keyCode.ENTER:\n                    if (this.element.val().length >= parseInt(this.options.minSearchLength, 10)) {\n                        this.searchForm.trigger('submit');\n                        e.preventDefault();\n                    }\n                    break;\n\n                case $.ui.keyCode.DOWN:\n                    if (this.responseList.indexList) {\n                        if (!this.responseList.selected) {  //eslint-disable-line max-depth\n                            this._getFirstVisibleElement().addClass(this.options.selectClass);\n                            this.responseList.selected = this._getFirstVisibleElement();\n                        } else if (!this._getLastElement().hasClass(this.options.selectClass)) {\n                            this.responseList.selected = this.responseList.selected\n                                .removeClass(this.options.selectClass).next().addClass(this.options.selectClass);\n                        } else {\n                            this.responseList.selected.removeClass(this.options.selectClass);\n                            this._getFirstVisibleElement().addClass(this.options.selectClass);\n                            this.responseList.selected = this._getFirstVisibleElement();\n                        }\n                        this.element.val(this.responseList.selected.find('.qs-option-name').text());\n                        this.element.attr('aria-activedescendant', this.responseList.selected.attr('id'));\n                        this._updateAriaHasPopup(true);\n                        this.autoComplete.show();\n                    }\n                    break;\n\n                case $.ui.keyCode.UP:\n                    if (this.responseList.indexList !== null) {\n                        if (!this._getFirstVisibleElement().hasClass(this.options.selectClass)) {\n                            this.responseList.selected = this.responseList.selected\n                                .removeClass(this.options.selectClass).prev().addClass(this.options.selectClass);\n\n                        } else {\n                            this.responseList.selected.removeClass(this.options.selectClass);\n                            this._getLastElement().addClass(this.options.selectClass);\n                            this.responseList.selected = this._getLastElement();\n                        }\n                        this.element.val(this.responseList.selected.find('.qs-option-name').text());\n                        this.element.attr('aria-activedescendant', this.responseList.selected.attr('id'));\n                        this._updateAriaHasPopup(true);\n                        this.autoComplete.show();\n                    }\n                    break;\n                default:\n                    return true;\n            }\n        },\n\n        /**\n         * Executes when the value of the search input field changes. Executes a GET request\n         * to populate a suggestion list based on entered text. Handles click (select), hover,\n         * and mouseout events on the populated suggestion list dropdown.\n         * @private\n         */\n        _onPropertyChange: function () {\n            var searchField = this.element,\n                clonePosition = {\n                    position: 'absolute',\n                    // Removed to fix display issues\n                    // left: searchField.offset().left,\n                    // top: searchField.offset().top + searchField.outerHeight(),\n                    width: searchField.outerWidth()\n                },\n                source = this.options.template,\n                template = mageTemplate(source),\n                dropdown = $('<ul role=\"listbox\"></ul>'),\n                value = this.element.val();\n\n            this.submitBtn.disabled = true;\n\n            if (value.length >= parseInt(this.options.minSearchLength, 10)) {\n                this.submitBtn.disabled = false;\n\n                if (this.options.url !== '') { //eslint-disable-line eqeqeq\n                    $.getJSON(this.options.url, {\n                        q: value\n                    }, $.proxy(function (data) {\n                        if (data.length) {\n                            $.each(data, function (index, element) {\n                                var html;\n\n                                element.index = index;\n                                html = template({\n                                    data: element\n                                });\n                                dropdown.append(html);\n                            });\n\n                            this._resetResponseList(true);\n\n                            this.responseList.indexList = this.autoComplete.html(dropdown)\n                                .css(clonePosition)\n                                .show()\n                                .find(this.options.responseFieldElements + ':visible');\n\n                            this.element.removeAttr('aria-activedescendant');\n\n                            if (this.responseList.indexList.length) {\n                                this._updateAriaHasPopup(true);\n                            } else {\n                                this._updateAriaHasPopup(false);\n                            }\n\n                            this.responseList.indexList\n                                .on('click', function (e) {\n                                    this.responseList.selected = $(e.currentTarget);\n                                    this.searchForm.trigger('submit');\n                                }.bind(this))\n                                .on('mouseenter mouseleave', function (e) {\n                                    this.responseList.indexList.removeClass(this.options.selectClass);\n                                    $(e.target).addClass(this.options.selectClass);\n                                    this.responseList.selected = $(e.target);\n                                    this.element.attr('aria-activedescendant', $(e.target).attr('id'));\n                                }.bind(this))\n                                .on('mouseout', function (e) {\n                                    if (!this._getLastElement() &&\n                                        this._getLastElement().hasClass(this.options.selectClass)) {\n                                        $(e.target).removeClass(this.options.selectClass);\n                                        this._resetResponseList(false);\n                                    }\n                                }.bind(this));\n                        } else {\n                            this._resetResponseList(true);\n                            this.autoComplete.hide();\n                            this._updateAriaHasPopup(false);\n                            this.element.removeAttr('aria-activedescendant');\n                        }\n                    }, this));\n                }\n            } else {\n                this._resetResponseList(true);\n                this.autoComplete.hide();\n                this._updateAriaHasPopup(false);\n                this.element.removeAttr('aria-activedescendant');\n            }\n        }\n    });\n\n    return $.mage.quickSearch;\n});\n","Mageplaza_LayeredNavigation/js/layer.js":"/**\r\n * Copyright 2016 Mageplaza. All rights reserved.\r\n * See https://www.mageplaza.com/LICENSE.txt for license details.\r\n */\r\ndefine([\r\n    'jquery',\r\n    'productListToolbarForm'\r\n], function ($) {\r\n    \"use strict\";\r\n    var next_page = \"\";\r\n    var loading = false;\r\n    var infinite_loaded_count = 0;\r\n    var active = false;\r\n    $.widget('mageplaza.layer', {\r\n\r\n        options: {\r\n            productsListSelector: '#layer-product-list',\r\n            navigationSelector: '#layered-filter-block'\r\n        },\r\n\r\n        _create: function () {\r\n            this.initProductListUrl();\r\n            this.initObserve();\r\n            this.initLoading();\r\n            this.inFinite();\r\n        },\r\n\r\n        initProductListUrl: function () {\r\n            var self = this;\r\n            $.mage.productListToolbarForm.prototype.changeUrl = function (paramName, paramValue, defaultValue) {\r\n                var urlPaths = this.options.url.split('?'),\r\n                    baseUrl = urlPaths[0],\r\n                    urlParams = urlPaths[1] ? urlPaths[1].split('&') : [],\r\n                    paramData = {},\r\n                    parameters;\r\n                for (var i = 0; i < urlParams.length; i++) {\r\n                    parameters = urlParams[i].split('=');\r\n                    paramData[parameters[0]] = parameters[1] !== undefined\r\n                        ? window.decodeURIComponent(parameters[1].replace(/\\+/g, '%20'))\r\n                        : '';\r\n                }\r\n                paramData[paramName] = paramValue;\r\n                if (paramValue == defaultValue) {\r\n                    delete paramData[paramName];\r\n                }\r\n                paramData = $.param(paramData);\r\n\r\n                self.ajaxSubmit(baseUrl + (paramData.length ? '?' + paramData : ''));\r\n            }\r\n        },\r\n\r\n        initObserve: function () {\r\n            var self = this;\r\n            var aElements = this.element.find('a');\r\n            aElements.each(function (index) {\r\n                var el = $(this);\r\n                var link = self.checkUrl(el.prop('href'));\r\n                if(!link) return;\r\n\r\n                el.bind('click', function (e) {\r\n                    if (el.hasClass('swatch-option-link-layered')) {\r\n                        var childEl = el.find('.swatch-option');\r\n                        childEl.addClass('selected');\r\n                    } else {\r\n                        var checkboxEl = el.find('input[type=checkbox]');\r\n                        checkboxEl.prop('checked', !checkboxEl.prop('checked'));\r\n                    }\r\n\r\n                    self.ajaxSubmit(link);\r\n                    e.stopPropagation();\r\n                    e.preventDefault();\r\n                });\r\n\r\n                var checkbox = el.find('input[type=checkbox]');\r\n                checkbox.bind('click', function (e) {\r\n                    self.ajaxSubmit(link);\r\n                    e.stopPropagation();\r\n                });\r\n            });\r\n\r\n            $(\".filter-current a\").bind('click', function (e) {\r\n                var link = self.checkUrl($(this).prop('href'));\r\n                if(!link) return;\r\n\r\n                self.ajaxSubmit(link);\r\n                e.stopPropagation();\r\n                e.preventDefault();\r\n            });\r\n\r\n            $(\".filter-actions a\").bind('click', function (e) {\r\n                var link = self.checkUrl($(this).prop('href'));\r\n                if(!link) return;\r\n\r\n                self.ajaxSubmit(link);\r\n                e.stopPropagation();\r\n                e.preventDefault();\r\n            });\r\n        },\r\n\r\n        checkUrl: function (url) {\r\n            var regex = /(http|https):\\/\\/(\\w+:{0,1}\\w*)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%!\\-\\/]))?/;\r\n\r\n            return regex.test(url) ? url : null;\r\n        },\r\n\r\n        initLoading: function () {\r\n\r\n        },\r\n\r\n        inFinite: function() {\r\n            var self = this;\r\n            next_page = \"\";\r\n            if($(self.options.productsListSelector +' .infinite-loader').length > 0){\r\n                active = true;\r\n            }\r\n            $(\".pages-items li > a.next\").each(function(){\r\n                next_page = $(this).attr(\"href\");\r\n            });\r\n            $(window).scroll(function(){\r\n                if(!loading && next_page && active && $(\".infinite-loader\").hasClass('scrolling') && $(window).scrollTop() >= $(\".infinite-loader\").offset().top-$(window).height()+100){\r\n                    loading = true;\r\n                    $(\".pages-items li > a.next\").each(function(){\r\n                        next_page = $(this).attr(\"href\");\r\n                    });\r\n                    self.ajaxInfinite(next_page);\r\n                }\r\n            });\r\n            $(\".infinite-loader .btn-load-more\").click(function(){\r\n                if(!loading && next_page && infinite_loaded_count >= 2){\r\n                    loading = true;\r\n                    self.ajaxInfinite(next_page);\r\n                }\r\n            });\r\n        },\r\n\r\n        ajaxInfinite: function (submitUrl) {\r\n            var self = this;\r\n            infinite_loaded_count++;\r\n            $('.infinite-loader .btn-load-more').hide();\r\n            $('.infinite-loader .loading').hide();\r\n            $.ajax({\r\n                url: submitUrl,\r\n                data: {isAjax: 1},\r\n                type: 'post',\r\n                dataType: 'json',\r\n                beforeSend: function () {\r\n                    $('.infinite-loader .btn-load-more').hide();\r\n                    $('.infinite-loader .loading').show();\r\n                },\r\n                success: function (res) {\r\n                    loading = false;\r\n                    if (res.backUrl) {\r\n                        window.location = res.backUrl;\r\n                        return;\r\n                    }\r\n                    if (res.products) {\r\n                        if($(res.products).find('div.products-grid')){\r\n                            var items_grid = $(res.products).find('div.products-grid.wrapper .product-items .item');\r\n                            $(self.options.productsListSelector + ' .products.wrapper .product-items').append(items_grid);\r\n                            $(self.options.productsListSelector).trigger('contentUpdated');\r\n                        }\r\n                        if($(res.products).find('div.products-list')){\r\n                            var items_list = $(res.products).find('div.products-list.wrapper .product-items .item');\r\n                            $(self.options.productsListSelector + ' .products.wrapper .product-items').append(items_list);\r\n                            $(self.options.productsListSelector).trigger('contentUpdated');\r\n                        }\r\n                        if($(res.products).find('.pages a.next').length > 0){\r\n                            $(self.options.productsListSelector + ' .pages a.next').attr('href', $(res.products).find('.pages a.next').attr('href'));\r\n                        }else{\r\n                            $(self.options.productsListSelector + ' .pages a.next').remove();\r\n                        }\r\n                        if($(\"form[data-role=tocart-form]\").length > 0) {\r\n                            $(\"form[data-role=tocart-form]\").catalogAddToCart();\r\n                        }\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(2n)').addClass('nth-child-2n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(2n+1)').addClass('nth-child-2np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(3n)').addClass('nth-child-3n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(3n+1)').addClass('nth-child-3np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(4n)').addClass('nth-child-4n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(4n+1)').addClass('nth-child-4np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(5n)').addClass('nth-child-5n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(5n+1)').addClass('nth-child-5np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(6n)').addClass('nth-child-6n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(6n+1)').addClass('nth-child-6np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(7n)').addClass('nth-child-7n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(7n+1)').addClass('nth-child-7np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(8n)').addClass('nth-child-8n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(8n+1)').addClass('nth-child-8np1');\r\n                        var hist = submitUrl;\r\n                        if(submitUrl.indexOf(\"p=\") > -1){\r\n                            var len = submitUrl.length-submitUrl.indexOf(\"p=\");\r\n                            var str_temp = submitUrl.substr(submitUrl.indexOf(\"p=\"),len);\r\n                            var page_param = \"\";\r\n                            if(str_temp.indexOf(\"&\") == -1){\r\n                                page_param = str_temp;\r\n                            } else {\r\n                                page_param = str_temp.substr(0,str_temp.indexOf(\"&\"));\r\n                            }\r\n                            hist = submitUrl.replace(page_param, \"\");\r\n                        }\r\n                        if (typeof window.history.pushState === 'function') {\r\n                            window.history.pushState({url: hist}, '', hist);\r\n                        }\r\n                        if(typeof enable_quickview != 'undefined' && enable_quickview == true) {\r\n                            requirejs(['jquery', 'weltpixel_quickview' ],\r\n                                function($, quickview) {\r\n                                    $('.weltpixel-quickview').off('click').on('click', function() {\r\n                                        var prodUrl = $(this).attr('data-quickview-url');\r\n                                        if (prodUrl.length) {\r\n                                            quickview.displayContent(prodUrl);\r\n                                        }\r\n                                    });\r\n                                });\r\n                        }\r\n                        $(\".products-grid .weltpixel-quickview\").each(function(){\r\n                            $(this).appendTo($(this).parent().parent().children(\".product-item-photo\"));\r\n                        });\r\n                        $(\"#layer-product-list img.porto-lazyload:not(.porto-lazyload-loaded)\").lazyload({effect:\"fadeIn\"});\r\n                        if ($('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').length) {\r\n                            $('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('initialized.owl.carousel', function() {\r\n                                $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\r\n                            });\r\n                            $('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('changed.owl.carousel', function() {\r\n                                $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\r\n                            });\r\n                        }\r\n                        next_page = \"\";\r\n                        $(\".pages-items li > a.next\").each(function(){\r\n                            next_page = $(this).attr(\"href\");\r\n                        });\r\n                        if(infinite_loaded_count >= 2){\r\n                            $('.infinite-loader .loading').hide();\r\n                            if(next_page){\r\n                                $('.infinite-loader .btn-load-more').show();\r\n                                $(\".infinite-loader .btn-load-more\").unbind(\"click\").click(function(){\r\n                                    if(!loading && next_page && infinite_loaded_count >= 2){\r\n                                        loading = true;\r\n                                        self.ajaxInfinite(next_page);\r\n                                    }\r\n                                });\r\n                            }\r\n                        } else {\r\n                            $('.infinite-loader .loading').fadeOut(300);\r\n                        }\r\n                    }\r\n\r\n                },\r\n                error: function () {\r\n                    window.location.reload();\r\n                }\r\n            });\r\n        },\r\n\r\n        ajaxSubmit: function (submitUrl) {\r\n            var self = this;\r\n            infinite_loaded_count = 0;\r\n            $.ajax({\r\n                url: submitUrl,\r\n                data: {isAjax: 1},\r\n                type: 'post',\r\n                dataType: 'json',\r\n                beforeSend: function () {\r\n                    $('.ln_overlay').show();\r\n                    if (typeof window.history.pushState === 'function') {\r\n                        window.history.pushState({url: submitUrl}, '', submitUrl);\r\n                    }\r\n                },\r\n                success: function (res) {\r\n                    if (res.backUrl) {\r\n                        window.location = res.backUrl;\r\n                        return;\r\n                    }\r\n                    if (res.navigation) {\r\n                        $(self.options.navigationSelector).replaceWith(res.navigation);\r\n                        $(self.options.navigationSelector).trigger('contentUpdated');\r\n                    }\r\n                    if (res.products) {\r\n                        $(self.options.productsListSelector).replaceWith(res.products);\r\n                        $(self.options.productsListSelector).trigger('contentUpdated');\r\n                    }\r\n                    $('.ln_overlay').hide();\r\n                    if(typeof enable_quickview != 'undefined' && enable_quickview == true) {\r\n                        requirejs(['jquery', 'weltpixel_quickview' ],\r\n                        function($, quickview) {\r\n                            $('.weltpixel-quickview').off('click').on('click', function() {\r\n                                var prodUrl = $(this).attr('data-quickview-url');\r\n                                if (prodUrl.length) {\r\n                                    quickview.displayContent(prodUrl);\r\n                                }\r\n                            });\r\n                        });\r\n                    }\r\n                    $(\".products-grid .weltpixel-quickview\").each(function(){\r\n                        $(this).appendTo($(this).parent().parent().children(\".product-item-photo\"));\r\n                    });\r\n                    $(\"#layer-product-list img.porto-lazyload\").lazyload({effect:\"fadeIn\"});\r\n                    if ($('#layer-product-list .porto-lazyload').closest('.owl-carousel').length) {\r\n                        $('#layer-product-list .porto-lazyload').closest('.owl-carousel').on('changed.owl.carousel', function() {\r\n                            $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\r\n                        });\r\n                    }\r\n                },\r\n                error: function () {\r\n                    window.location.reload();\r\n                }\r\n            });\r\n        }\r\n    });\r\n\r\n    return $.mageplaza.layer;\r\n});\r\n","Mageplaza_LayeredNavigation/js/view/layer.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license sliderConfig is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_LayeredNavigation\r\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\n\r\ndefine([\r\n    'jquery',\r\n    'Mageplaza_AjaxLayer/js/action/submit-filter',\r\n    'Magento_Catalog/js/price-utils',\r\n    'accordion',\r\n    'productListToolbarForm',\r\n    'jquery/jquery-ui'\r\n], function ($, submitFilterAction, ultil) {\r\n    \"use strict\";\r\n    var next_page = \"\";\r\n    var loading = false;\r\n    var infinite_loaded_count = 0;\r\n    var active = false;\r\n\r\n    $.widget('mageplaza.layer', $.mage.accordion, {\r\n        options: {\r\n            openedState: 'active',\r\n            collapsible: true,\r\n            multipleCollapsible: true,\r\n            animate: 200,\r\n            productsListSelector: '#layer-product-list',\r\n            mobileShopbyElement: '#layered-filter-block .filter-title [data-role=title]',\r\n            collapsibleElement: '[data-role=ln_collapsible]',\r\n            header: '[data-role=ln_title]',\r\n            content: '[data-role=ln_content]',\r\n            isCustomerLoggedIn: false,\r\n            isAjax: true,\r\n            params: [],\r\n            active: [],\r\n            activeDesktop: [],\r\n            activeMobile: [],\r\n            checkboxEl: 'input[type=checkbox], input[type=radio]',\r\n            sliderElementPrefix: '#ln_slider_',\r\n            sliderTextElementPrefix: '#ln_slider_text_'\r\n        },\r\n\r\n        _create: function () {\r\n            this.initActiveItems();\r\n\r\n            this._super();\r\n\r\n            this.initProductListUrl();\r\n            this.initObserve();\r\n            this.initSlider();\r\n            this.initWishlistCompare();\r\n            this.selectedAttr();\r\n            this.renderCategoryTree();\r\n        },\r\n\r\n        inFinite: function() {\r\n            var self = this;\r\n            next_page = \"\";\r\n            if($(self.options.productsListSelector +' .infinite-loader').length > 0){\r\n                active = true;\r\n            }\r\n            $(\".pages-items li > a.next\").each(function(){\r\n                next_page = $(this).attr(\"href\");\r\n            });\r\n            if(!next_page){\r\n                $('.infinite-loader').hide();\r\n            }\r\n            $(window).scroll(function(){\r\n                if(!loading && next_page && active && $(\".infinite-loader\").hasClass('scrolling') && $(window).scrollTop() >= $(\".infinite-loader\").offset().top-$(window).height()+100){\r\n                    loading = true;\r\n                    $(\".pages-items li > a.next\").each(function(){\r\n                        next_page = $(this).attr(\"href\");\r\n                    });\r\n                    self.ajaxInfinite(next_page);\r\n                }\r\n            });\r\n            $(\".infinite-loader .btn-load-more\").click(function(){\r\n                if(!loading && next_page){\r\n                    loading = true;\r\n                    self.ajaxInfinite(next_page);\r\n                }\r\n            });\r\n        },\r\n\r\n        ajaxInfinite: function (submitUrl) {\r\n            var self = this;\r\n            infinite_loaded_count++;\r\n            $('.infinite-loader .btn-load-more').hide();\r\n            $('.infinite-loader .loading').hide();\r\n            $.ajax({\r\n                url: submitUrl,\r\n                type: 'get',\r\n                beforeSend: function () {\r\n                    $('.infinite-loader .btn-load-more').hide();\r\n                    $('.infinite-loader .loading').show();\r\n                },\r\n                success: function (res) {\r\n                    loading = false;\r\n                    var $products = $(res.products);\r\n                    if (res.backUrl) {\r\n                        window.location = res.backUrl;\r\n                        return;\r\n                    }\r\n                    if($products){\r\n                        $products.each(function(i,el){\r\n                            if($(el).hasClass('products-grid')){\r\n                                var items_grid = $(this).find('.product-items .item');\r\n                                $(self.options.productsListSelector + ' .products.wrapper .product-items').append(items_grid);\r\n                                $(self.options.productsListSelector).trigger('contentUpdated');\r\n                            }\r\n                            if($(el).hasClass('products-list')){\r\n                                var items_list = $(this).find('.product-items .item');\r\n                                $(self.options.productsListSelector + ' .products.wrapper .product-items').append(items_list);\r\n                                $(self.options.productsListSelector).trigger('contentUpdated');\r\n                            }\r\n                            if($(el).hasClass('toolbar-products')){\r\n                                if($(this).find('.pages a.next').length > 0){\r\n                                    $(self.options.productsListSelector + ' .pages a.next').attr('href', $(this).find('.pages a.next').attr('href'));\r\n                                }else{\r\n                                    $(self.options.productsListSelector + ' .pages a.next').remove();\r\n                                }\r\n                            }\r\n                        });\r\n                        if($(\"form[data-role=tocart-form]\").length > 0 && !redirect_cart) {\r\n                            $(\"form[data-role=tocart-form]\").catalogAddToCart();\r\n                        }\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(2n)').addClass('nth-child-2n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(2n+1)').addClass('nth-child-2np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(3n)').addClass('nth-child-3n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(3n+1)').addClass('nth-child-3np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(4n)').addClass('nth-child-4n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(4n+1)').addClass('nth-child-4np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(5n)').addClass('nth-child-5n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(5n+1)').addClass('nth-child-5np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(6n)').addClass('nth-child-6n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(6n+1)').addClass('nth-child-6np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(7n)').addClass('nth-child-7n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(7n+1)').addClass('nth-child-7np1');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(8n)').addClass('nth-child-8n');\r\n                        $('.main .products.grid .product-items li.product-item:nth-child(8n+1)').addClass('nth-child-8np1');\r\n                        var hist = submitUrl;\r\n                        if(submitUrl.indexOf(\"p=\") > -1){\r\n                            var len = submitUrl.length-submitUrl.indexOf(\"p=\");\r\n                            var str_temp = submitUrl.substr(submitUrl.indexOf(\"p=\"),len);\r\n                            var page_param = \"\";\r\n                            if(str_temp.indexOf(\"&\") == -1){\r\n                                page_param = str_temp;\r\n                            } else {\r\n                                page_param = str_temp.substr(0,str_temp.indexOf(\"&\"));\r\n                            }\r\n                            hist = submitUrl.replace(page_param, \"\");\r\n                        }\r\n                        if (typeof window.history.pushState === 'function') {\r\n                            window.history.pushState({url: hist}, '', hist);\r\n                        }\r\n                        if(typeof enable_quickview != 'undefined' && enable_quickview == true) {\r\n                            requirejs(['jquery', 'weltpixel_quickview' ],\r\n                                function($, quickview) {\r\n                                    $('.weltpixel-quickview').off('click').on('click', function() {\r\n                                        var prodUrl = $(this).attr('data-quickview-url');\r\n                                        if (prodUrl.length) {\r\n                                            quickview.displayContent(prodUrl);\r\n                                        }\r\n                                    });\r\n                                });\r\n                        }\r\n                        $(\".products-grid .weltpixel-quickview\").each(function(){\r\n                            $(this).appendTo($(this).parent().parent().children(\".product-item-photo\"));\r\n                        });\r\n                        $(\"#layer-product-list img.porto-lazyload:not(.porto-lazyload-loaded)\").lazyload({effect:\"fadeIn\"});\r\n                        if ($('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').length) {\r\n                            $('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('initialized.owl.carousel', function() {\r\n                                $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\r\n                            });\r\n                            $('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('changed.owl.carousel', function() {\r\n                                $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\r\n                            });\r\n                        }\r\n                        self.initWishlistCompare();\r\n                        next_page = \"\";\r\n                        $(\".pages-items li > a.next\").each(function(){\r\n                            next_page = $(this).attr(\"href\");\r\n                        });\r\n                        $('.infinite-loader .loading').hide();\r\n                        if(next_page){\r\n                            $('.infinite-loader .btn-load-more').show();\r\n                            $(\".infinite-loader .btn-load-more\").unbind(\"click\").click(function(){\r\n                                if(!loading && next_page){\r\n                                    loading = true;\r\n                                    self.ajaxInfinite(next_page);\r\n                                }\r\n                            });\r\n                        }\r\n                    }\r\n\r\n                },\r\n                error: function () {\r\n                    window.location.reload();\r\n                }\r\n            });\r\n        },\r\n\r\n        initActiveItems: function () {\r\n            var layerActivesDesktop = this.options.activeDesktop,\r\n                layerActivesMobile  = this.options.activeMobile,\r\n                activesDesktop = [],\r\n                activesMobile = [];\r\n            if ($(\".page-layout-1column\").length){\r\n                this.options.multipleCollapsible = false;\r\n            }\r\n\r\n            if (typeof window.layerActiveTabs !== 'undefined') {\r\n                layerActivesDesktop, layerActivesMobile = window.layerActiveTabs;\r\n            }\r\n            if(/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)\r\n                || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(navigator.userAgent.substr(0,4))) {\r\n                if (layerActivesMobile.length) {\r\n                    this.element.find('.filter-options-item').each(function (index) {\r\n                        if (~$.inArray($(this).attr('attribute'), layerActivesMobile)) {\r\n                            activesMobile.push(index);\r\n                        }\r\n                    });\r\n                }\r\n                this.options.active = activesMobile;\r\n                return this;\r\n            }else{\r\n                if (layerActivesDesktop.length) {\r\n                    this.element.find('.filter-options-item').each(function (index) {\r\n                        if (~$.inArray($(this).attr('attribute'), layerActivesDesktop)) {\r\n                            activesDesktop.push(index);\r\n                        }\r\n                    });\r\n                }\r\n                this.options.active = activesDesktop;\r\n                return this;\r\n            }\r\n        },\r\n\r\n        initProductListUrl: function () {\r\n            var isProcessToolbar = false,\r\n                isAjax = this.options.isAjax;\r\n            $.mage.productListToolbarForm.prototype.changeUrl = function (paramName, paramValue, defaultValue) {\r\n                if (isProcessToolbar) {\r\n                    return;\r\n                }\r\n                if (isAjax) {\r\n                    isProcessToolbar = true;\r\n                }\r\n\r\n                var urlPaths = this.options.url.split('?'),\r\n                    baseUrl = urlPaths[0],\r\n                    urlParams = urlPaths[1] ? urlPaths[1].split('&') : [],\r\n                    paramData = {},\r\n                    parameters;\r\n                for (var i = 0; i < urlParams.length; i++) {\r\n                    parameters = urlParams[i].split('=');\r\n                    paramData[parameters[0]] = parameters[1] !== undefined\r\n                        ? window.decodeURIComponent(parameters[1].replace(/\\+/g, '%20'))\r\n                        : '';\r\n                }\r\n                paramData[paramName] = paramValue;\r\n                if (paramValue === defaultValue) {\r\n                    delete paramData[paramName];\r\n                }\r\n                paramData = $.param(paramData);\r\n                if (isAjax) {\r\n                    submitFilterAction(baseUrl + (paramData.length ? '?' + paramData : ''));\r\n                } else location.href = baseUrl + (paramData.length ? '?' + paramData : '');\r\n            }\r\n        },\r\n\r\n        initObserve: function () {\r\n            var self = this;\r\n            var isAjax = this.options.isAjax;\r\n\r\n            // fix browser back, forward button\r\n            if (typeof window.history.replaceState === \"function\") {\r\n                window.history.replaceState({url: document.URL}, document.title);\r\n\r\n                setTimeout(function () {\r\n                    window.onpopstate = function (e) {\r\n                        if (e.state) {\r\n                            submitFilterAction(e.state.url, 1);\r\n                        }\r\n                    };\r\n                }, 0)\r\n            }\r\n\r\n            var pageElements = $('#layer-product-list').find('.pages a');\r\n            pageElements.each(function () {\r\n                var el = $(this),\r\n                    link = self.checkUrl(el.prop('href'));\r\n                if (!link) {\r\n                    return;\r\n                }\r\n\r\n                el.bind('click', function (e) {\r\n                    e.stopPropagation();\r\n                    e.preventDefault();\r\n                    if (isAjax) {\r\n                        submitFilterAction(link);\r\n                    } else location.href = link;\r\n                })\r\n            });\r\n\r\n            var currentElements = this.element.find('.filter-current a, .filter-actions a');\r\n            currentElements.each(function (index) {\r\n                var el = $(this),\r\n                    link = self.checkUrl(el.prop('href'));\r\n                if (!link) {\r\n                    return;\r\n                }\r\n\r\n                el.bind('click', function (e) {\r\n                    e.stopPropagation();\r\n                    e.preventDefault();\r\n                    if (isAjax) {\r\n                        submitFilterAction(link);\r\n                    } else {\r\n                        location.href = link;\r\n                    }\r\n                });\r\n            });\r\n\r\n            var optionElements = this.element.find('.filter-options a');\r\n            optionElements.each(function (index) {\r\n                var el = $(this),\r\n                    link = self.checkUrl(el.prop('href'));\r\n                if (!link) {\r\n                    return;\r\n                }\r\n\r\n                el.bind('click', function (e) {\r\n                    if (el.hasClass('swatch-option-link-layered')) {\r\n                        self.selectSwatchOption(el);\r\n                    } else {\r\n                        var checkboxEl = el.siblings(self.options.checkboxEl);\r\n                        checkboxEl.prop('checked', !checkboxEl.prop('checked'));\r\n                    }\r\n\r\n                    e.stopPropagation();\r\n                    e.preventDefault();\r\n                    self.ajaxSubmit(link);\r\n                });\r\n\r\n                var checkbox = el.siblings(self.options.checkboxEl);\r\n                checkbox.bind('click', function (e) {\r\n                    e.stopPropagation();\r\n                    self.ajaxSubmit(link);\r\n                });\r\n            });\r\n\r\n            var swatchElements = this.element.find('.swatch-attribute');\r\n            swatchElements.each(function (index) {\r\n                var el = $(this);\r\n                var attCode = el.attr('attribute-code');\r\n                if (attCode) {\r\n                    if (self.options.params.hasOwnProperty(attCode)) {\r\n                        var attValues = self.options.params[attCode].split(\",\");\r\n                        var swatchOptions = el.find('.swatch-option');\r\n                        swatchOptions.each(function (option) {\r\n                            var elOption = $(this);\r\n                            if ($.inArray(elOption.attr('option-id'), attValues) !== -1) {\r\n                                elOption.addClass('selected');\r\n                            }\r\n                        });\r\n                    }\r\n                }\r\n            });\r\n            if(typeof enable_quickview != 'undefined' && enable_quickview == true) {\r\n                requirejs(['jquery', 'weltpixel_quickview' ],\r\n                    function($, quickview) {\r\n                        $('.weltpixel-quickview').off('click').on('click', function() {\r\n                            var prodUrl = $(this).attr('data-quickview-url');\r\n                            if (prodUrl.length) {\r\n                                quickview.displayContent(prodUrl);\r\n                            }\r\n                        });\r\n                    });\r\n            }\r\n\r\n            $(\".products-grid .weltpixel-quickview\").each(function(){\r\n                $(this).appendTo($(this).parents('.product-item-info').children(\".product-item-photo\"));\r\n            });\r\n            $(\"#layer-product-list img.porto-lazyload:not(.porto-lazyload-loaded)\").lazyload({effect:\"fadeIn\"});\r\n            if ($('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').length) {\r\n                $('#layer-product-list .porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('changed.owl.carousel', function() {\r\n                    $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\r\n                });\r\n            }\r\n            if(isAjax) {\r\n                self.inFinite();\r\n            }else{\r\n                $('.infinite-loader').hide();\r\n            }\r\n        },\r\n\r\n        selectSwatchOption: function (el) {\r\n            var childEl = el.find('.swatch-option');\r\n            if (childEl.hasClass('selected')) {\r\n                childEl.removeClass('selected');\r\n            } else {\r\n                childEl.addClass('selected');\r\n            }\r\n        },\r\n\r\n        initSlider: function () {\r\n            var self = this,\r\n                slider = this.options.slider;\r\n\r\n            for (var code in slider) {\r\n                if (slider.hasOwnProperty(code)) {\r\n                    var sliderConfig = slider[code],\r\n                        sliderElement = self.element.find(this.options.sliderElementPrefix + code),\r\n                        priceFormat = sliderConfig.hasOwnProperty('priceFormat') ? JSON.parse(sliderConfig.priceFormat) : null;\r\n\r\n                    if (sliderElement.length) {\r\n                        sliderElement.slider({\r\n                            range: true,\r\n                            min: sliderConfig.minValue,\r\n                            max: sliderConfig.maxValue,\r\n                            values: [sliderConfig.selectedFrom, sliderConfig.selectedTo],\r\n                            slide: function (event, ui) {\r\n                                self.displaySliderText(code, ui.values[0], ui.values[1], priceFormat);\r\n                            },\r\n                            change: function (event, ui) {\r\n                                self.ajaxSubmit(self.getSliderUrl(sliderConfig.ajaxUrl, ui.values[0], ui.values[1]));\r\n                            }\r\n                        });\r\n                    }\r\n                    self.displaySliderText(code, sliderConfig.selectedFrom, sliderConfig.selectedTo, priceFormat);\r\n                }\r\n            }\r\n        },\r\n\r\n        displaySliderText: function (code, from, to, format) {\r\n            var textElement = this.element.find(this.options.sliderTextElementPrefix + code);\r\n            if (textElement.length) {\r\n                if (format !== null) {\r\n                    from = this.formatPrice(from, format);\r\n                    to = this.formatPrice(to, format);\r\n                }\r\n\r\n                textElement.html(from + ' - ' + to);\r\n            }\r\n        },\r\n\r\n        getSliderUrl: function (url, from, to) {\r\n            return url.replace('from-to', from + '-' + to);\r\n        },\r\n\r\n        formatPrice: function (value, format) {\r\n            return ultil.formatPrice(value, format);\r\n        },\r\n\r\n        ajaxSubmit: function (submitUrl) {\r\n            var isAjax = this.options.isAjax;\r\n            this.element.find(this.options.mobileShopbyElement).trigger('click');\r\n\r\n            if (isAjax) {\r\n                return submitFilterAction(submitUrl);\r\n            }\r\n            location.href = submitUrl;\r\n        },\r\n\r\n        checkUrl: function (url) {\r\n            var regex = /(http|https):\\/\\/(\\w+:{0,1}\\w*)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%!\\-\\/]))?/;\r\n\r\n            return regex.test(url) ? url : null;\r\n        },\r\n\r\n        //Handling 'add to wishlist' & 'add to compare' event\r\n        initWishlistCompare: function () {\r\n            var isAjax = this.options.isAjax;\r\n            var isCustomerLoggedIn = this.options.isCustomerLoggedIn,\r\n                elClass = 'a.action.tocompare' + (isCustomerLoggedIn ? ',a.action.towishlist' : '');\r\n            $(elClass).each(function () {\r\n                var el = $(this);\r\n                if (isAjax){\r\n                    $(el).bind('click', function (e) {\r\n                        var dataPost = $(el).data('post'),\r\n                            formKey = $('input[name=\"form_key\"]').val(), method = 'post';\r\n                        if (formKey) {\r\n                            dataPost.data.form_key = formKey;\r\n                        }\r\n\r\n                        var paramData = $.param(dataPost.data),\r\n                            url = dataPost.action + (paramData.length ? '?' + paramData : '');\r\n\r\n                        e.stopPropagation();\r\n                        e.preventDefault();\r\n\r\n                        if (el.hasClass('towishlist')) {\r\n                            submitFilterAction(url, true, method);\r\n                        } else{\r\n                            submitFilterAction(url, true, method);\r\n                        }\r\n                    });\r\n                }\r\n            })\r\n        },\r\n\r\n        //Selected attribute color after page load.\r\n        selectedAttr: function () {\r\n            var filterCurrent = $('.layered-filter-block-container .filter-current .items .item .filter-value');\r\n\r\n            filterCurrent.each(function(){\r\n                var el         = $(this),\r\n                    colorLabel = el.html(),\r\n                    swatchAttr  = $('.filter-options .filter-options-item .swatch-option-link-layered .swatch-option');\r\n\r\n                swatchAttr.each(function(){\r\n                    var elA = $(this);\r\n                    if(elA.attr('data-option-label') === colorLabel && !elA.hasClass('selected')){\r\n                        elA.addClass('selected');\r\n                    }\r\n                });\r\n            });\r\n        },\r\n\r\n        renderCategoryTree: function () {\r\n            var iconExpand = this.element.find('.filter-options .icon-expand');\r\n\r\n            iconExpand.each(function () {\r\n                var el = $(this);\r\n\r\n                el.nextAll('ol').each(function() {\r\n                    if($(this).find('input[checked]').length !== 0\r\n                        && !$(this).prevAll('.icon-expand').hasClass('active')\r\n                    ) {\r\n                        $(this).show();\r\n                        $(this).prevAll('.icon-expand').toggleClass('active');\r\n                    }\r\n                });\r\n\r\n                el.bind('click', function (e) {\r\n                    el.nextAll('ol').toggle();\r\n                    el.toggleClass('active');\r\n                    e.stopPropagation();\r\n                });\r\n            });\r\n        }\r\n    });\r\n\r\n    return $.mageplaza.layer;\r\n});\r\n","Magento_Tax/js/price/adjustment.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Ui/js/grid/columns/column',\n    'mage/translate'\n], function (Element, $t) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            bodyTmpl: 'Magento_Tax/price/adjustment',\n            taxPriceType: 'final_price',\n            taxPriceCssClass: 'price-including-tax',\n            bothPrices: 3,\n            inclTax: 2,\n            exclTax: 1,\n            modules: {\n                price: '${ $.parentName }'\n            },\n            listens: {\n                price: 'initializePriceAttributes'\n            }\n        },\n\n        /**\n         * {@inheritdoc}\n         */\n        initialize: function () {\n            this._super()\n                .initializePriceAttributes();\n\n            return this;\n        },\n\n        /**\n         * Update parent price.\n         *\n         * @returns {Object} Chainable.\n         */\n        initializePriceAttributes: function () {\n            if (this.displayBothPrices && this.price()) {\n                this.price().priceWrapperCssClasses = this.taxPriceCssClass;\n                this.price().priceWrapperAttr = {\n                    'data-label': $t('Incl. Tax')\n                };\n            }\n\n            return this;\n        },\n\n        /**\n         * Get price tax adjustment.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} tax html\n         */\n        getTax: function (row) {\n            return row['price_info']['extension_attributes']['tax_adjustments']['formatted_prices'][this.taxPriceType];\n        },\n\n        /**\n         * UnsanitizedHtml version of getTax.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} tax html\n         */\n        getTaxUnsanitizedHtml: function (row) {\n            return this.getTax(row);\n        },\n\n        /**\n         * Set price tax type.\n         *\n         * @param {String} priceType\n         * @return {Object}\n         */\n        setPriceType: function (priceType) {\n            this.taxPriceType = priceType;\n\n            return this;\n        },\n\n        /**\n         * Return whether display setting is to display\n         * both price including tax and price excluding tax.\n         *\n         * @return {Boolean}\n         */\n        displayBothPrices: function () {\n            return +this.source.data.displayTaxes === this.bothPrices;\n        },\n\n        /**\n         * Return whether display setting is to display price including tax.\n         *\n         * @return {Boolean}\n         */\n        displayPriceIncludeTax: function () {\n            return +this.source.data.displayTaxes === this.inclTax;\n        },\n\n        /**\n         * Return whether display setting is to display price excluding tax.\n         *\n         * @return {Boolean}\n         */\n        displayPriceExclTax: function () {\n            return +this.source.data.displayTaxes === this.exclTax;\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/summary/shipping.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'jquery',\n    'Magento_Checkout/js/view/summary/shipping',\n    'Magento_Checkout/js/model/quote'\n], function ($, Component, quote) {\n    'use strict';\n\n    var displayMode = window.checkoutConfig.reviewShippingDisplayMode;\n\n    return Component.extend({\n        defaults: {\n            displayMode: displayMode,\n            template: 'Magento_Tax/checkout/summary/shipping'\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isBothPricesDisplayed: function () {\n            return this.displayMode == 'both'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isIncludingDisplayed: function () {\n            return this.displayMode == 'including'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isExcludingDisplayed: function () {\n            return this.displayMode == 'excluding'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {*|Boolean}\n         */\n        isCalculated: function () {\n            return this.totals() && this.isFullMode() && quote.shippingMethod() != null;\n        },\n\n        /**\n         * @return {*}\n         */\n        getIncludingValue: function () {\n            var price;\n\n            if (!this.isCalculated()) {\n                return this.notCalculatedMessage;\n            }\n            price = this.totals()['shipping_incl_tax'];\n\n            return this.getFormattedPrice(price);\n        },\n\n        /**\n         * @return {*}\n         */\n        getExcludingValue: function () {\n            var price;\n\n            if (!this.isCalculated()) {\n                return this.notCalculatedMessage;\n            }\n            price = this.totals()['shipping_amount'];\n\n            return this.getFormattedPrice(price);\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/summary/grand-total.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Checkout/js/view/summary/abstract-total',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Catalog/js/price-utils',\n    'Magento_Checkout/js/model/totals'\n], function (Component, quote, priceUtils, totals) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            isFullTaxSummaryDisplayed: window.checkoutConfig.isFullTaxSummaryDisplayed || false,\n            template: 'Magento_Tax/checkout/summary/grand-total'\n        },\n        totals: quote.getTotals(),\n        isTaxDisplayedInGrandTotal: window.checkoutConfig.includeTaxInGrandTotal || false,\n\n        /**\n         * @return {*}\n         */\n        isDisplayed: function () {\n            return this.isFullMode();\n        },\n\n        /**\n         * @return {*|String}\n         */\n        getValue: function () {\n            var price = 0;\n\n            if (this.totals()) {\n                price = totals.getSegment('grand_total').value;\n            }\n\n            return this.getFormattedPrice(price);\n        },\n\n        /**\n         * @return {*|String}\n         */\n        getBaseValue: function () {\n            var price = 0;\n\n            if (this.totals()) {\n                price = this.totals()['base_grand_total'];\n            }\n\n            return priceUtils.formatPriceLocale(price, quote.getBasePriceFormat());\n        },\n\n        /**\n         * @return {*}\n         */\n        getGrandTotalExclTax: function () {\n            var total = this.totals(),\n                amount;\n\n            if (!total) {\n                return 0;\n            }\n\n            amount = total['grand_total'] - total['tax_amount'];\n\n            if (amount < 0) {\n                amount = 0;\n            }\n\n            return this.getFormattedPrice(amount);\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isBaseGrandTotalDisplayNeeded: function () {\n            var total = this.totals();\n\n            if (!total) {\n                return false;\n            }\n\n            return total['base_currency_code'] != total['quote_currency_code']; //eslint-disable-line eqeqeq\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/summary/tax.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'ko',\n    'Magento_Checkout/js/view/summary/abstract-total',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/model/totals',\n    'mage/translate',\n    'underscore'\n], function (ko, Component, quote, totals, $t, _) {\n    'use strict';\n\n    var isTaxDisplayedInGrandTotal = window.checkoutConfig.includeTaxInGrandTotal,\n        isFullTaxSummaryDisplayed = window.checkoutConfig.isFullTaxSummaryDisplayed,\n        isZeroTaxDisplayed = window.checkoutConfig.isZeroTaxDisplayed,\n        taxAmount = 0,\n        rates = 0;\n\n    return Component.extend({\n        defaults: {\n            isTaxDisplayedInGrandTotal: isTaxDisplayedInGrandTotal,\n            notCalculatedMessage: $t('Not yet calculated'),\n            template: 'Magento_Tax/checkout/summary/tax'\n        },\n        totals: quote.getTotals(),\n        isFullTaxSummaryDisplayed: isFullTaxSummaryDisplayed,\n\n        /**\n         * @return {Boolean}\n         */\n        ifShowValue: function () {\n            if (this.isFullMode() && this.getPureValue() == 0) { //eslint-disable-line eqeqeq\n                return isZeroTaxDisplayed;\n            }\n\n            return true;\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        ifShowDetails: function () {\n            if (!this.isFullMode()) {\n                return false;\n            }\n\n            return this.getPureValue() > 0 && isFullTaxSummaryDisplayed;\n        },\n\n        /**\n         * @return {Number}\n         */\n        getPureValue: function () {\n            var amount = 0,\n                taxTotal;\n\n            if (this.totals()) {\n                taxTotal = totals.getSegment('tax');\n\n                if (taxTotal) {\n                    amount = taxTotal.value;\n                }\n            }\n\n            return amount;\n        },\n\n        /**\n         * @return {*|Boolean}\n         */\n        isCalculated: function () {\n            return this.totals() && this.isFullMode() && totals.getSegment('tax') != null;\n        },\n\n        /**\n         * @return {*}\n         */\n        getValue: function () {\n            var amount;\n\n            if (!this.isCalculated()) {\n                return this.notCalculatedMessage;\n            }\n            amount = totals.getSegment('tax').value;\n\n            return this.getFormattedPrice(amount);\n        },\n\n        /**\n         * @param {*} amount\n         * @return {*|String}\n         */\n        formatPrice: function (amount) {\n            return this.getFormattedPrice(amount);\n        },\n\n        /**\n         * @param {*} parent\n         * @param {*} percentage\n         * @return {*|String}\n         */\n        getTaxAmount: function (parent, percentage) {\n            var totalPercentage = 0;\n\n            taxAmount = parent.amount;\n            rates = parent.rates;\n            _.each(rates, function (rate) {\n                totalPercentage += parseFloat(rate.percent);\n            });\n\n            return this.getFormattedPrice(this.getPercentAmount(taxAmount, totalPercentage, percentage));\n        },\n\n        /**\n         * @param {*} amount\n         * @param {*} totalPercentage\n         * @param {*} percentage\n         * @return {*|String}\n         */\n        getPercentAmount: function (amount, totalPercentage, percentage) {\n            return parseFloat(amount * percentage / totalPercentage);\n        },\n\n        /**\n         * @return {Array}\n         */\n        getDetails: function () {\n            var taxSegment = totals.getSegment('tax');\n\n            if (taxSegment && taxSegment['extension_attributes']) {\n                return taxSegment['extension_attributes']['tax_grandtotal_details'];\n            }\n\n            return [];\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/summary/subtotal.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Checkout/js/view/summary/abstract-total',\n    'Magento_Checkout/js/model/quote'\n], function (Component, quote) {\n    'use strict';\n\n    var displaySubtotalMode = window.checkoutConfig.reviewTotalsDisplayMode;\n\n    return Component.extend({\n        defaults: {\n            displaySubtotalMode: displaySubtotalMode,\n            template: 'Magento_Tax/checkout/summary/subtotal'\n        },\n        totals: quote.getTotals(),\n\n        /**\n         * @return {*|String}\n         */\n        getValue: function () {\n            var price = 0;\n\n            if (this.totals()) {\n                price = this.totals().subtotal;\n            }\n\n            return this.getFormattedPrice(price);\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isBothPricesDisplayed: function () {\n            return this.displaySubtotalMode == 'both'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isIncludingTaxDisplayed: function () {\n            return this.displaySubtotalMode == 'including'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {*|String}\n         */\n        getValueInclTax: function () {\n            var price = 0;\n\n            if (this.totals()) {\n                price = this.totals()['subtotal_incl_tax'];\n            }\n\n            return this.getFormattedPrice(price);\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/summary/item/details/subtotal.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Checkout/js/view/summary/item/details/subtotal'\n], function (subtotal) {\n    'use strict';\n\n    var displayPriceMode = window.checkoutConfig.reviewItemPriceDisplayMode || 'including';\n\n    return subtotal.extend({\n        defaults: {\n            displayPriceMode: displayPriceMode,\n            template: 'Magento_Tax/checkout/summary/item/details/subtotal'\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isPriceInclTaxDisplayed: function () {\n            return displayPriceMode == 'both' || displayPriceMode == 'including'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isPriceExclTaxDisplayed: function () {\n            return displayPriceMode == 'both' || displayPriceMode == 'excluding'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @param {Object} quoteItem\n         * @return {*|String}\n         */\n        getValueInclTax: function (quoteItem) {\n            return this.getFormattedPrice(quoteItem['row_total_incl_tax']);\n        },\n\n        /**\n         * @param {Object} quoteItem\n         * @return {*|String}\n         */\n        getValueExclTax: function (quoteItem) {\n            return this.getFormattedPrice(quoteItem['row_total']);\n        }\n\n    });\n});\n","Magento_Tax/js/view/checkout/shipping_method/price.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Catalog/js/price-utils'\n], function (Component, quote, priceUtils) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_Tax/checkout/shipping_method/price'\n        },\n        isDisplayShippingPriceExclTax: window.checkoutConfig.isDisplayShippingPriceExclTax,\n        isDisplayShippingBothPrices: window.checkoutConfig.isDisplayShippingBothPrices,\n\n        /**\n         * @param {Object} item\n         * @return {Boolean}\n         */\n        isPriceEqual: function (item) {\n            return item['price_excl_tax'] != item['price_incl_tax']; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @param {*} price\n         * @return {*|String}\n         */\n        getFormattedPrice: function (price) {\n            //todo add format data\n            return priceUtils.formatPriceLocale(price, quote.getPriceFormat());\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/cart/totals/shipping.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Tax/js/view/checkout/summary/shipping',\n    'Magento_Checkout/js/model/quote'\n], function (Component, quote) {\n    'use strict';\n\n    return Component.extend({\n        /**\n         * @override\n         */\n        isCalculated: function () {\n            return !!quote.shippingMethod();\n        },\n\n        /**\n         * @override\n         */\n        getShippingMethodTitle: function () {\n            return '(' + this._super() + ')';\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/cart/totals/grand-total.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Tax/js/view/checkout/summary/grand-total'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        /**\n         * @override\n         */\n        isDisplayed: function () {\n            return true;\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/cart/totals/tax.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Tax/js/view/checkout/summary/tax',\n    'Magento_Checkout/js/model/totals'\n], function (Component, totals) {\n    'use strict';\n\n    var isFullTaxSummaryDisplayed = window.checkoutConfig.isFullTaxSummaryDisplayed,\n        isZeroTaxDisplayed = window.checkoutConfig.isZeroTaxDisplayed;\n\n    return Component.extend({\n        /**\n         * @override\n         */\n        ifShowValue: function () {\n            if (parseInt(this.getPureValue()) === 0) { //eslint-disable-line radix\n                return isZeroTaxDisplayed;\n            }\n\n            return true;\n        },\n\n        /**\n         * @override\n         */\n        ifShowDetails: function () {\n            return this.getPureValue() > 0 && isFullTaxSummaryDisplayed;\n        },\n\n        /**\n         * @override\n         */\n        isCalculated: function () {\n            return this.totals() && totals.getSegment('tax') !== null;\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/minicart/subtotal/totals.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'ko',\n    'uiComponent',\n    'Magento_Customer/js/customer-data'\n], function (ko, Component, customerData) {\n    'use strict';\n\n    return Component.extend({\n        displaySubtotal: ko.observable(true),\n\n        /**\n         * @override\n         */\n        initialize: function () {\n            this._super();\n            this.cart = customerData.get('cart');\n        }\n    });\n});\n","Magento_Customer/js/customer-global-session-loader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Customer/js/customer-data'\n], function ($, customerData) {\n    'use strict';\n\n    return function () {\n        var customer;\n\n        // When the session is available, this customer menu will be available\n        if ($('.customer-menu').length > 0) {\n            customer = customerData.get('customer');\n\n            customerData.getInitCustomerData().done(function () {\n                // Check if the customer data is set in local storage, if not reload data from server\n                if (!customer().firstname) {\n                    customerData.reload([], false);\n                }\n            });\n        }\n    };\n});\n","Magento_Customer/js/invalidation-processor.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiElement',\n    'Magento_Customer/js/customer-data'\n], function (_, Element, customerData) {\n    'use strict';\n\n    return Element.extend({\n        /**\n         * Initialize object\n         */\n        initialize: function () {\n            this._super();\n            this.process(customerData);\n        },\n\n        /**\n         * Process all rules in loop, each rule can invalidate some sections in customer data\n         *\n         * @param {Object} customerDataObject\n         */\n        process: function (customerDataObject) {\n            _.each(this.invalidationRules, function (rule, ruleName) {\n                _.each(rule, function (ruleArgs, rulePath) {\n                    require([rulePath], function (Rule) {\n                        var currentRule = new Rule(ruleArgs);\n\n                        if (!_.isFunction(currentRule.process)) {\n                            throw new Error('Rule ' + ruleName + ' should implement invalidationProcessor interface');\n                        }\n                        currentRule.process(customerDataObject);\n                    });\n                });\n            });\n        }\n    });\n});\n","Magento_Customer/js/addressValidation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'mageUtils',\n    'mage/translate',\n    'Magento_Checkout/js/model/postcode-validator',\n    'jquery-ui-modules/widget',\n    'validation'\n], function ($, __, utils, $t, postCodeValidator) {\n    'use strict';\n\n    $.widget('mage.addressValidation', {\n        options: {\n            selectors: {\n                button: '[data-action=save-address]',\n                zip: '#zip',\n                country: 'select[name=\"country_id\"]:visible'\n            }\n        },\n\n        zipInput: null,\n        countrySelect: null,\n\n        /**\n         * Validation creation\n         *\n         * @protected\n         */\n        _create: function () {\n            var button = $(this.options.selectors.button, this.element);\n\n            this.zipInput = $(this.options.selectors.zip, this.element);\n            this.countrySelect = $(this.options.selectors.country, this.element);\n\n            this.element.validation({\n\n                /**\n                 * Submit Handler\n                 * @param {Element} form - address form\n                 */\n                submitHandler: function (form) {\n\n                    button.attr('disabled', true);\n                    form.submit();\n                }\n            });\n\n            this._addPostCodeValidation();\n        },\n\n        /**\n         * Add postcode validation\n         *\n         * @protected\n         */\n        _addPostCodeValidation: function () {\n            var self = this;\n\n            this.zipInput.on('keyup', __.debounce(function (event) {\n                    var valid = self._validatePostCode(event.target.value);\n\n                    self._renderValidationResult(valid);\n                }, 500)\n            );\n\n            this.countrySelect.on('change', function () {\n                var valid = self._validatePostCode(self.zipInput.val());\n\n                self._renderValidationResult(valid);\n            });\n        },\n\n        /**\n         * Validate post code value.\n         *\n         * @protected\n         * @param {String} postCode - post code\n         * @return {Boolean} Whether is post code valid\n         */\n        _validatePostCode: function (postCode) {\n            var countryId = this.countrySelect.val();\n\n            if (postCode === null) {\n                return true;\n            }\n\n            return postCodeValidator.validate(postCode, countryId, this.options.postCodes);\n        },\n\n        /**\n         * Renders warning messages for invalid post code.\n         *\n         * @protected\n         * @param {Boolean} valid\n         */\n        _renderValidationResult: function (valid) {\n            var warnMessage,\n                alertDiv = this.zipInput.next();\n\n            if (!valid) {\n                warnMessage = $t('Provided Zip/Postal Code seems to be invalid.');\n\n                if (postCodeValidator.validatedPostCodeExample.length) {\n                    warnMessage += $t(' Example: ') + postCodeValidator.validatedPostCodeExample.join('; ') + '. ';\n                }\n                warnMessage += $t('If you believe it is the right one you can ignore this notice.');\n            }\n\n            alertDiv.children(':first').text(warnMessage);\n\n            if (valid) {\n                alertDiv.hide();\n            } else {\n                alertDiv.show();\n            }\n        }\n    });\n\n    return $.mage.addressValidation;\n});\n","Magento_Customer/js/checkout-balance.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.checkoutBalance', {\n        /**\n         * Initialize store credit events\n         * @private\n         */\n        _create: function () {\n            this.eventData = {\n                price: this.options.balance,\n                totalPrice: 0\n            };\n            this.element.on('change', $.proxy(function (e) {\n                if ($(e.target).is(':checked')) {\n                    this.eventData.price = -1 * this.options.balance;\n                } else {\n                    if (this.options.amountSubstracted) { //eslint-disable-line no-lonely-if\n                        this.eventData.price = parseFloat(this.options.usedAmount);\n                        this.options.amountSubstracted = false;\n                    } else {\n                        this.eventData.price = parseFloat(this.options.balance);\n                    }\n                }\n                this.element.trigger('updateCheckoutPrice', this.eventData);\n            }, this));\n        }\n    });\n\n    return $.mage.checkoutBalance;\n});\n","Magento_Customer/js/password-strength-indicator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Customer/js/zxcvbn',\n    'mage/translate',\n    'mage/validation'\n], function ($, zxcvbn, $t) {\n    'use strict';\n\n    $.widget('mage.passwordStrengthIndicator', {\n        options: {\n            cache: {},\n            passwordSelector: '[type=password]',\n            passwordStrengthMeterSelector: '[data-role=password-strength-meter]',\n            passwordStrengthMeterLabelSelector: '[data-role=password-strength-meter-label]',\n            formSelector: 'form',\n            emailSelector: 'input[type=\"email\"]'\n        },\n\n        /**\n         * Widget initialization\n         * @private\n         */\n        _create: function () {\n            this.options.cache.input = $(this.options.passwordSelector, this.element);\n            this.options.cache.meter = $(this.options.passwordStrengthMeterSelector, this.element);\n            this.options.cache.label = $(this.options.passwordStrengthMeterLabelSelector, this.element);\n\n            // We need to look outside the module for backward compatibility, since someone can already use the module.\n            // @todo Narrow this selector in 2.3 so it doesn't accidentally finds the email field from the\n            // newsletter email field or any other \"email\" field.\n            this.options.cache.email = $(this.options.formSelector).find(this.options.emailSelector);\n            this._bind();\n        },\n\n        /**\n         * Event binding, will monitor change, keyup and paste events.\n         * @private\n         */\n        _bind: function () {\n            this._on(this.options.cache.input, {\n                'change': this._calculateStrength,\n                'keyup': this._calculateStrength,\n                'paste': this._calculateStrength\n            });\n\n            if (this.options.cache.email.length) {\n                this._on(this.options.cache.email, {\n                    'change': this._calculateStrength,\n                    'keyup': this._calculateStrength,\n                    'paste': this._calculateStrength\n                });\n            }\n        },\n\n        /**\n         * Calculate password strength\n         * @private\n         */\n        _calculateStrength: function () {\n            var password = this._getPassword(),\n                isEmpty = password.length === 0,\n                zxcvbnScore,\n                displayScore,\n                isValid;\n\n            // Display score is based on combination of whether password is empty, valid, and zxcvbn strength\n            if (isEmpty) {\n                displayScore = 0;\n            } else {\n                this.options.cache.input.rules('add', {\n                    'password-not-equal-to-user-name': this.options.cache.email.val()\n                });\n\n                // We should only perform this check in case there is an email field on screen\n                if (this.options.cache.email.length &&\n                    password.toLowerCase() === this.options.cache.email.val().toLowerCase()) {\n                    displayScore = 1;\n                } else {\n                    isValid = $.validator.validateSingleElement(this.options.cache.input);\n                    zxcvbnScore = zxcvbn(password).score;\n                    displayScore = isValid && zxcvbnScore > 0 ? zxcvbnScore : 1;\n                }\n            }\n\n            // Update label\n            this._displayStrength(displayScore);\n        },\n\n        /**\n         * Display strength\n         * @param {Number} displayScore\n         * @private\n         */\n        _displayStrength: function (displayScore) {\n            var strengthLabel = '',\n                className;\n\n            switch (displayScore) {\n                case 0:\n                    strengthLabel = $t('No Password');\n                    className = 'password-none';\n                    break;\n\n                case 1:\n                    strengthLabel = $t('Weak');\n                    className = 'password-weak';\n                    break;\n\n                case 2:\n                    strengthLabel = $t('Medium');\n                    className = 'password-medium';\n                    break;\n\n                case 3:\n                    strengthLabel = $t('Strong');\n                    className = 'password-strong';\n                    break;\n\n                case 4:\n                    strengthLabel = $t('Very Strong');\n                    className = 'password-very-strong';\n                    break;\n            }\n\n            this.options.cache.meter\n                .removeClass()\n                .addClass(className);\n            this.options.cache.label.text(strengthLabel);\n        },\n\n        /**\n         * Get password value\n         * @returns {*}\n         * @private\n         */\n        _getPassword: function () {\n            return this.options.cache.input.val();\n        }\n    });\n\n    return $.mage.passwordStrengthIndicator;\n});\n","Magento_Customer/js/validation.js":"define([\n    'jquery',\n    'moment',\n    'mageUtils',\n    'jquery/validate',\n    'validation',\n    'mage/translate'\n], function ($, moment, utils) {\n    'use strict';\n\n    $.validator.addMethod(\n        'validate-date',\n        function (value, element, params) {\n            var dateFormat = utils.normalizeDate(params.dateFormat);\n\n            if (value === '') {\n                return true;\n            }\n\n            return moment(value, dateFormat, true).isValid();\n        },\n        $.mage.__('Invalid date')\n    );\n\n    $.validator.addMethod(\n        'validate-dob',\n        function (value, element, params) {\n            var dateFormat = utils.convertToMomentFormat(params.dateFormat);\n\n            if (value === '') {\n                return true;\n            }\n\n            return moment(value, dateFormat).isBefore(moment());\n        },\n        $.mage.__('The Date of Birth should not be greater than today.')\n    );\n});\n","Magento_Customer/js/change-email-password.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.changeEmailPassword', {\n        options: {\n            changeEmailSelector: '[data-role=change-email]',\n            changePasswordSelector: '[data-role=change-password]',\n            mainContainerSelector: '[data-container=change-email-password]',\n            titleSelector: '[data-title=change-email-password]',\n            emailContainerSelector: '[data-container=change-email]',\n            newPasswordContainerSelector: '[data-container=new-password]',\n            confirmPasswordContainerSelector: '[data-container=confirm-password]',\n            currentPasswordSelector: '[data-input=current-password]',\n            emailSelector: '[data-input=change-email]',\n            newPasswordSelector: '[data-input=new-password]',\n            confirmPasswordSelector: '[data-input=confirm-password]'\n        },\n\n        /**\n         * Create widget\n         * @private\n         */\n        _create: function () {\n            this.element.on('change', $.proxy(function () {\n                this._checkChoice();\n            }, this));\n\n            this._checkChoice();\n            this._bind();\n        },\n\n        /**\n         * Event binding, will monitor change, keyup and paste events.\n         * @private\n         */\n        _bind: function () {\n            this._on($(this.options.emailSelector), {\n                'change': this._updatePasswordFieldWithEmailValue,\n                'keyup': this._updatePasswordFieldWithEmailValue,\n                'paste': this._updatePasswordFieldWithEmailValue\n            });\n        },\n\n        /**\n         * Check choice\n         * @private\n         */\n        _checkChoice: function () {\n            if ($(this.options.changeEmailSelector).is(':checked') &&\n                $(this.options.changePasswordSelector).is(':checked')) {\n                this._showAll();\n            } else if ($(this.options.changeEmailSelector).is(':checked')) {\n                this._showEmail();\n            } else if ($(this.options.changePasswordSelector).is(':checked')) {\n                this._showPassword();\n            } else {\n                this._hideAll();\n            }\n        },\n\n        /**\n         * Show email and password input fields\n         * @private\n         */\n        _showAll: function () {\n            $(this.options.titleSelector).html(this.options.titleChangeEmailAndPassword);\n\n            $(this.options.mainContainerSelector).show();\n            $(this.options.emailContainerSelector).show();\n            $(this.options.newPasswordContainerSelector).show();\n            $(this.options.confirmPasswordContainerSelector).show();\n\n            $(this.options.currentPasswordSelector).attr('data-validate', '{required:true}').prop('disabled', false);\n            $(this.options.emailSelector).attr('data-validate', '{required:true}').prop('disabled', false);\n            this._updatePasswordFieldWithEmailValue();\n            $(this.options.confirmPasswordSelector).attr(\n                'data-validate',\n                '{required:true, equalTo:\"' + this.options.newPasswordSelector + '\"}'\n            ).prop('disabled', false);\n        },\n\n        /**\n         * Hide email and password input fields\n         * @private\n         */\n        _hideAll: function () {\n            $(this.options.mainContainerSelector).hide();\n            $(this.options.emailContainerSelector).hide();\n            $(this.options.newPasswordContainerSelector).hide();\n            $(this.options.confirmPasswordContainerSelector).hide();\n\n            $(this.options.currentPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.emailSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.newPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.confirmPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n        },\n\n        /**\n         * Show email input fields\n         * @private\n         */\n        _showEmail: function () {\n            this._showAll();\n            $(this.options.titleSelector).html(this.options.titleChangeEmail);\n\n            $(this.options.newPasswordContainerSelector).hide();\n            $(this.options.confirmPasswordContainerSelector).hide();\n\n            $(this.options.newPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.confirmPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n        },\n\n        /**\n         * Show password input fields\n         * @private\n         */\n        _showPassword: function () {\n            this._showAll();\n            $(this.options.titleSelector).html(this.options.titleChangePassword);\n\n            $(this.options.emailContainerSelector).hide();\n\n            $(this.options.emailSelector).removeAttr('data-validate').prop('disabled', true);\n        },\n\n        /**\n         * Update password validation rules with email input field value\n         * @private\n         */\n        _updatePasswordFieldWithEmailValue: function () {\n            $(this.options.newPasswordSelector).attr(\n                'data-validate',\n                '{required:true, ' +\n                '\\'validate-customer-password\\':true, ' +\n                '\\'password-not-equal-to-user-name\\':\\'' + $(this.options.emailSelector).val() + '\\'}'\n            ).prop('disabled', false);\n        }\n    });\n\n    return $.mage.changeEmailPassword;\n});\n","Magento_Customer/js/customer-data.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'underscore',\n    'ko',\n    'Magento_Customer/js/section-config',\n    'mage/url',\n    'mage/storage',\n    'jquery/jquery-storageapi'\n], function ($, _, ko, sectionConfig, url) {\n    'use strict';\n\n    var options = {},\n        storage,\n        storageInvalidation,\n        invalidateCacheBySessionTimeOut,\n        invalidateCacheByCloseCookieSession,\n        dataProvider,\n        buffer,\n        customerData,\n        deferred = $.Deferred();\n\n    url.setBaseUrl(window.BASE_URL);\n    options.sectionLoadUrl = url.build('customer/section/load');\n\n    /**\n     * @param {Object} invalidateOptions\n     */\n    invalidateCacheBySessionTimeOut = function (invalidateOptions) {\n        var date;\n\n        if (new Date($.localStorage.get('mage-cache-timeout')) < new Date()) {\n            storage.removeAll();\n        }\n        date = new Date(Date.now() + parseInt(invalidateOptions.cookieLifeTime, 10) * 1000);\n        $.localStorage.set('mage-cache-timeout', date);\n    };\n\n    /**\n     * Invalidate Cache By Close Cookie Session\n     */\n    invalidateCacheByCloseCookieSession = function () {\n        if (!$.cookieStorage.isSet('mage-cache-sessid')) {\n            storage.removeAll();\n        }\n\n        $.cookieStorage.set('mage-cache-sessid', true);\n    };\n\n    dataProvider = {\n\n        /**\n         * @param {Object} sectionNames\n         * @return {Object}\n         */\n        getFromStorage: function (sectionNames) {\n            var result = {};\n\n            _.each(sectionNames, function (sectionName) {\n                result[sectionName] = storage.get(sectionName);\n            });\n\n            return result;\n        },\n\n        /**\n         * @param {Object} sectionNames\n         * @param {Boolean} forceNewSectionTimestamp\n         * @return {*}\n         */\n        getFromServer: function (sectionNames, forceNewSectionTimestamp) {\n            var parameters;\n\n            sectionNames = sectionConfig.filterClientSideSections(sectionNames);\n            parameters = _.isArray(sectionNames) && sectionNames.indexOf('*') < 0 ? {\n                sections: sectionNames.join(',')\n            } : [];\n            parameters['force_new_section_timestamp'] = forceNewSectionTimestamp;\n\n            return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) {\n                throw new Error(jqXHR);\n            });\n        }\n    };\n\n    /**\n     * @param {Function} target\n     * @param {String} sectionName\n     * @return {*}\n     */\n    ko.extenders.disposableCustomerData = function (target, sectionName) {\n        var sectionDataIds, newSectionDataIds = {};\n\n        target.subscribe(function () {\n            setTimeout(function () {\n                storage.remove(sectionName);\n                sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n                _.each(sectionDataIds, function (data, name) {\n                    if (name !== sectionName) {\n                        newSectionDataIds[name] = data;\n                    }\n                });\n                $.cookieStorage.set('section_data_ids', newSectionDataIds);\n            }, 3000);\n        });\n\n        return target;\n    };\n\n    buffer = {\n        data: {},\n\n        /**\n         * @param {String} sectionName\n         */\n        bind: function (sectionName) {\n            this.data[sectionName] = ko.observable({});\n        },\n\n        /**\n         * @param {String} sectionName\n         * @return {Object}\n         */\n        get: function (sectionName) {\n            if (!this.data[sectionName]) {\n                this.bind(sectionName);\n            }\n\n            return this.data[sectionName];\n        },\n\n        /**\n         * @return {Array}\n         */\n        keys: function () {\n            return _.keys(this.data);\n        },\n\n        /**\n         * @param {String} sectionName\n         * @param {Object} sectionData\n         */\n        notify: function (sectionName, sectionData) {\n            if (!this.data[sectionName]) {\n                this.bind(sectionName);\n            }\n            this.data[sectionName](sectionData);\n        },\n\n        /**\n         * @param {Object} sections\n         */\n        update: function (sections) {\n            var sectionId = 0,\n                sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n\n            _.each(sections, function (sectionData, sectionName) {\n                sectionId = sectionData['data_id'];\n                sectionDataIds[sectionName] = sectionId;\n                storage.set(sectionName, sectionData);\n                storageInvalidation.remove(sectionName);\n                buffer.notify(sectionName, sectionData);\n            });\n            $.cookieStorage.set('section_data_ids', sectionDataIds);\n        },\n\n        /**\n         * @param {Object} sections\n         */\n        remove: function (sections) {\n            _.each(sections, function (sectionName) {\n                storage.remove(sectionName);\n\n                if (!sectionConfig.isClientSideSection(sectionName)) {\n                    storageInvalidation.set(sectionName, true);\n                }\n            });\n        }\n    };\n\n    customerData = {\n\n        /**\n         * Customer data initialization\n         */\n        init: function () {\n            var expiredSectionNames = this.getExpiredSectionNames();\n\n            if (expiredSectionNames.length > 0) {\n                _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {\n                    buffer.notify(sectionName, sectionData);\n                });\n                this.reload(expiredSectionNames, false);\n            } else {\n                _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {\n                    buffer.notify(sectionName, sectionData);\n                });\n\n                if (!_.isEmpty(storageInvalidation.keys())) {\n                    this.reload(storageInvalidation.keys(), false);\n                }\n            }\n\n            if (!_.isEmpty($.cookieStorage.get('section_data_clean'))) {\n                this.reload(sectionConfig.getSectionNames(), true);\n                $.cookieStorage.set('section_data_clean', '');\n            }\n        },\n\n        /**\n         * Storage init\n         */\n        initStorage: function () {\n            $.cookieStorage.setConf({\n                path: '/',\n                expires: new Date(Date.now() + parseInt(options.cookieLifeTime, 10) * 1000)\n            });\n            storage = $.initNamespaceStorage('mage-cache-storage').localStorage;\n            storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage;\n        },\n\n        /**\n         * Retrieve the list of sections that has expired since last page reload.\n         *\n         * Sections can expire due to lifetime constraints or due to inconsistent storage information\n         * (validated by cookie data).\n         *\n         * @return {Array}\n         */\n        getExpiredSectionNames: function () {\n            var expiredSectionNames = [],\n                cookieSectionTimestamps = $.cookieStorage.get('section_data_ids') || {},\n                sectionLifetime = options.expirableSectionLifetime * 60,\n                currentTimestamp = Math.floor(Date.now() / 1000),\n                sectionData;\n\n            // process sections that can expire due to lifetime constraints\n            _.each(options.expirableSectionNames, function (sectionName) {\n                sectionData = storage.get(sectionName);\n\n                if (typeof sectionData === 'object' && sectionData['data_id'] + sectionLifetime <= currentTimestamp) {\n                    expiredSectionNames.push(sectionName);\n                }\n            });\n\n            // process sections that can expire due to storage information inconsistency\n            _.each(cookieSectionTimestamps, function (cookieSectionTimestamp, sectionName) {\n                sectionData = storage.get(sectionName);\n\n                if (typeof sectionData === 'undefined' ||\n                    typeof sectionData === 'object' &&\n                    cookieSectionTimestamp !== sectionData['data_id']\n                ) {\n                    expiredSectionNames.push(sectionName);\n                }\n            });\n\n            //remove expired section names of previously installed/enable modules\n            expiredSectionNames = _.intersection(expiredSectionNames, sectionConfig.getSectionNames());\n\n            return _.uniq(expiredSectionNames);\n        },\n\n        /**\n         * Check if some sections have to be reloaded.\n         *\n         * @deprecated Use getExpiredSectionNames instead.\n         *\n         * @return {Boolean}\n         */\n        needReload: function () {\n            var expiredSectionNames = this.getExpiredSectionNames();\n\n            return expiredSectionNames.length > 0;\n        },\n\n        /**\n         * Retrieve the list of expired keys.\n         *\n         * @deprecated Use getExpiredSectionNames instead.\n         *\n         * @return {Array}\n         */\n        getExpiredKeys: function () {\n            return this.getExpiredSectionNames();\n        },\n\n        /**\n         * @param {String} sectionName\n         * @return {*}\n         */\n        get: function (sectionName) {\n            return buffer.get(sectionName);\n        },\n\n        /**\n         * @param {String} sectionName\n         * @param {Object} sectionData\n         */\n        set: function (sectionName, sectionData) {\n            var data = {};\n\n            data[sectionName] = sectionData;\n            buffer.update(data);\n        },\n\n        /**\n         * Avoid using this function directly 'cause of possible performance drawbacks.\n         * Each customer section reload brings new non-cached ajax request.\n         *\n         * @param {Array} sectionNames\n         * @param {Boolean} forceNewSectionTimestamp\n         * @return {*}\n         */\n        reload: function (sectionNames, forceNewSectionTimestamp) {\n            return dataProvider.getFromServer(sectionNames, forceNewSectionTimestamp).done(function (sections) {\n                $(document).trigger('customer-data-reload', [sectionNames]);\n                buffer.update(sections);\n            });\n        },\n\n        /**\n         * @param {Array} sectionNames\n         */\n        invalidate: function (sectionNames) {\n            var sectionDataIds,\n                sectionsNamesForInvalidation;\n\n            sectionsNamesForInvalidation = _.contains(sectionNames, '*') ? sectionConfig.getSectionNames() :\n                sectionNames;\n\n            $(document).trigger('customer-data-invalidate', [sectionsNamesForInvalidation]);\n            buffer.remove(sectionsNamesForInvalidation);\n            sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n\n            // Invalidate section in cookie (increase version of section with 1000)\n            _.each(sectionsNamesForInvalidation, function (sectionName) {\n                if (!sectionConfig.isClientSideSection(sectionName)) {\n                    sectionDataIds[sectionName] += 1000;\n                }\n            });\n            $.cookieStorage.set('section_data_ids', sectionDataIds);\n        },\n\n        /**\n         * Checks if customer data is initialized.\n         *\n         * @returns {jQuery.Deferred}\n         */\n        getInitCustomerData: function () {\n            return deferred.promise();\n        },\n\n        /**\n         * Reload sections on ajax complete\n         *\n         * @param {Object} jsonResponse\n         * @param {Object} settings\n         */\n        onAjaxComplete: function (jsonResponse, settings) {\n            var sections,\n                redirects;\n\n            if (settings.type.match(/post|put|delete/i)) {\n                sections = sectionConfig.getAffectedSections(settings.url);\n\n                if (sections && sections.length) {\n                    this.invalidate(sections);\n                    redirects = ['redirect', 'backUrl'];\n\n                    if (_.isObject(jsonResponse) && !_.isEmpty(_.pick(jsonResponse, redirects))) { //eslint-disable-line\n                        return;\n                    }\n                    this.reload(sections, true);\n                }\n            }\n        },\n\n        /**\n         * @param {Object} settings\n         * @constructor\n         */\n        'Magento_Customer/js/customer-data': function (settings) {\n            options = settings;\n            customerData.initStorage();\n            invalidateCacheBySessionTimeOut(settings);\n            invalidateCacheByCloseCookieSession();\n            customerData.init();\n            deferred.resolve();\n        }\n    };\n\n    /**\n     * Events listener\n     */\n    $(document).on('ajaxComplete', function (event, xhr, settings) {\n        customerData.onAjaxComplete(xhr.responseJSON, settings);\n    });\n\n    /**\n     * Events listener\n     */\n    $(document).on('submit', function (event) {\n        var sections;\n\n        if (event.target.method.match(/post|put|delete/i)) {\n            sections = sectionConfig.getAffectedSections(event.target.action);\n\n            if (sections) {\n                customerData.invalidate(sections);\n            }\n        }\n    });\n\n    return customerData;\n});\n","Magento_Customer/js/section-config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['underscore'], function (_) {\n    'use strict';\n\n    var baseUrls = [],\n        sections = [],\n        clientSideSections = [],\n        sectionNames = [],\n        canonize;\n\n    /**\n     * @param {String} url\n     * @return {String}\n     */\n    canonize = function (url) {\n        var route = url;\n\n        _.some(baseUrls, function (baseUrl) {\n            route = url.replace(baseUrl, '');\n\n            return route !== url;\n        });\n\n        return route.replace(/^\\/?index.php\\/?/, '').toLowerCase();\n    };\n\n    return {\n        /**\n         * Returns a list of sections which should be invalidated for given URL.\n         * @param {String} url - URL which was requested.\n         * @return {Object} - List of sections to invalidate.\n         */\n        getAffectedSections: function (url) {\n            var route = canonize(url),\n                actions = _.find(sections, function (val, section) {\n                    var matched;\n\n                    // Covers the case where \"*\" works as a glob pattern.\n                    if (section.indexOf('*') >= 0) {\n                        section = section.replace(/\\*/g, '[^/]+') + '$';\n                        matched = route.match(section);\n\n                        return matched && matched[0] === route;\n                    }\n\n                    return route.indexOf(section) === 0;\n                });\n\n            return _.union(_.toArray(actions), sections['*']);\n        },\n\n        /**\n         * Filters the list of given sections to the ones defined as client side.\n         * @param {Object} allSections - List of sections to check.\n         * @return {Object} - List of filtered sections.\n         */\n        filterClientSideSections: function (allSections) {\n            return _.difference(allSections, clientSideSections);\n        },\n\n        /**\n         * Tells if section is defined as client side.\n         * @param {String} sectionName - Name of the section to check.\n         * @return {Boolean}\n         */\n        isClientSideSection: function (sectionName) {\n            return _.contains(clientSideSections, sectionName);\n        },\n\n        /**\n         * Returns array of section names.\n         * @returns {Array}\n         */\n        getSectionNames: function () {\n            return sectionNames;\n        },\n\n        /**\n         * @param {Object} options\n         * @constructor\n         */\n        'Magento_Customer/js/section-config': function (options) {\n            baseUrls = options.baseUrls;\n            sections = options.sections;\n            clientSideSections = options.clientSideSections;\n            sectionNames = options.sectionNames;\n        }\n    };\n});\n","Magento_Customer/js/block-submit-on-send.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/mage'\n], function ($) {\n    'use strict';\n\n    return function (config) {\n        var dataForm = $('#' + config.formId);\n\n        dataForm.on('submit', function () {\n            $(this).find(':submit').attr('disabled', 'disabled');\n\n            if (this.isValid === false) {\n                $(this).find(':submit').prop('disabled', false);\n            }\n            this.isValid = true;\n        });\n        dataForm.on('invalid-form.validate', function () {\n            $(this).find(':submit').prop('disabled', false);\n            this.isValid = false;\n        });\n    };\n});\n","Magento_Customer/js/address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/confirm',\n    'jquery-ui-modules/widget',\n    'mage/translate'\n], function ($, confirm) {\n    'use strict';\n\n    $.widget('mage.address', {\n        /**\n         * Options common to all instances of this widget.\n         * @type {Object}\n         */\n        options: {\n            deleteConfirmMessage: $.mage.__('Are you sure you want to delete this address?')\n        },\n\n        /**\n         * Bind event handlers for adding and deleting addresses.\n         * @private\n         */\n        _create: function () {\n            var options         = this.options,\n                addAddress      = options.addAddress,\n                deleteAddress   = options.deleteAddress;\n\n            if (addAddress) {\n                $(document).on('click', addAddress, this._addAddress.bind(this));\n            }\n\n            if (deleteAddress) {\n                $(document).on('click', deleteAddress, this._deleteAddress.bind(this));\n            }\n        },\n\n        /**\n         * Add a new address.\n         * @private\n         */\n        _addAddress: function () {\n            window.location = this.options.addAddressLocation;\n        },\n\n        /**\n         * Delete the address whose id is specified in a data attribute after confirmation from the user.\n         * @private\n         * @param {jQuery.Event} e\n         * @return {Boolean}\n         */\n        _deleteAddress: function (e) {\n            var self = this;\n\n            confirm({\n                content: this.options.deleteConfirmMessage,\n                actions: {\n\n                    /** @inheritdoc */\n                    confirm: function () {\n                        if (typeof $(e.target).parent().data('address') !== 'undefined') {\n                            window.location = self.options.deleteUrlPrefix + $(e.target).parent().data('address') +\n                                '/form_key/' + $.mage.cookies.get('form_key');\n                        } else {\n                            window.location = self.options.deleteUrlPrefix + $(e.target).data('address') +\n                                '/form_key/' + $.mage.cookies.get('form_key');\n                        }\n                    }\n                }\n            });\n\n            return false;\n        }\n    });\n\n    return $.mage.address;\n});\n","Magento_Customer/js/logout-redirect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/mage'\n], function ($) {\n    'use strict';\n\n    return function (data) {\n        $($.mage.redirect(data.url, 'assign', 5000));\n    };\n});\n","Magento_Customer/js/show-password.js":"/**\n* Copyright \u00a9 Magento, Inc. All rights reserved.\n* See COPYING.txt for license details.\n*/\n\ndefine([\n    'jquery',\n    'uiComponent'\n], function ($, Component) {\n    'use strict';\n\n    return Component.extend({\n        passwordSelector: '',\n        passwordInputType: 'password',\n        textInputType: 'text',\n\n        defaults: {\n            template: 'Magento_Customer/show-password',\n            isPasswordVisible: false\n        },\n\n        /**\n         * @return {Object}\n         */\n        initObservable: function () {\n            this._super()\n                .observe(['isPasswordVisible']);\n\n            this.isPasswordVisible.subscribe(function (isChecked) {\n                this._showPassword(isChecked);\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Show/Hide password\n         * @private\n         */\n        _showPassword: function (isChecked) {\n            $(this.passwordSelector).attr('type',\n                isChecked ? this.textInputType : this.passwordInputType\n            );\n        }\n    });\n});\n","Magento_Customer/js/invalidation-rules/website-rule.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'uiClass'\n], function (Element) {\n    'use strict';\n\n    return Element.extend({\n\n        defaults: {\n            scopeConfig: {}\n        },\n\n        /**\n         * Takes website id from current customer data and compare it with current website id\n         * If customer belongs to another scope, we need to invalidate current section\n         *\n         * @param {Object} customerData\n         */\n        process: function (customerData) {\n            var customer = customerData.get('customer');\n\n            if (this.scopeConfig && customer() &&\n                ~~customer().websiteId !== ~~this.scopeConfig.websiteId && ~~customer().websiteId !== 0) {\n                customerData.reload(['customer']);\n            }\n        }\n    });\n});\n","Magento_Customer/js/view/authentication-popup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'ko',\n    'Magento_Ui/js/form/form',\n    'Magento_Customer/js/action/login',\n    'Magento_Customer/js/customer-data',\n    'Magento_Customer/js/model/authentication-popup',\n    'mage/translate',\n    'mage/url',\n    'Magento_Ui/js/modal/alert',\n    'mage/validation'\n], function ($, ko, Component, loginAction, customerData, authenticationPopup, $t, url, alert) {\n    'use strict';\n\n    return Component.extend({\n        registerUrl: window.authenticationPopup.customerRegisterUrl,\n        forgotPasswordUrl: window.authenticationPopup.customerForgotPasswordUrl,\n        autocomplete: window.authenticationPopup.autocomplete,\n        modalWindow: null,\n        isLoading: ko.observable(false),\n\n        defaults: {\n            template: 'Magento_Customer/authentication-popup'\n        },\n\n        /**\n         * Init\n         */\n        initialize: function () {\n            var self = this;\n\n            this._super();\n            url.setBaseUrl(window.authenticationPopup.baseUrl);\n            loginAction.registerLoginCallback(function () {\n                self.isLoading(false);\n            });\n        },\n\n        /** Init popup login window */\n        setModalElement: function (element) {\n            if (authenticationPopup.modalWindow == null) {\n                authenticationPopup.createPopUp(element);\n            }\n        },\n\n        /** Is login form enabled for current customer */\n        isActive: function () {\n            var customer = customerData.get('customer');\n\n            return customer() == false; //eslint-disable-line eqeqeq\n        },\n\n        /** Show login popup window */\n        showModal: function () {\n            if (this.modalWindow) {\n                $(this.modalWindow).modal('openModal');\n            } else {\n                alert({\n                    content: $t('Guest checkout is disabled.')\n                });\n            }\n        },\n\n        /**\n         * Provide login action\n         *\n         * @return {Boolean}\n         */\n        login: function (formUiElement, event) {\n            var loginData = {},\n                formElement = $(event.currentTarget),\n                formDataArray = formElement.serializeArray();\n\n            event.stopPropagation();\n            formDataArray.forEach(function (entry) {\n                loginData[entry.name] = entry.value;\n            });\n            loginData['customerLoginUrl'] = window.authenticationPopup.customerLoginUrl;\n            if (formElement.validation() &&\n                formElement.validation('isValid')\n            ) {\n                this.isLoading(true);\n                loginAction(loginData);\n            }\n\n            return false;\n        }\n    });\n});\n","Magento_Customer/js/view/customer.js":"/**\n* Copyright \u00a9 Magento, Inc. All rights reserved.\n* See COPYING.txt for license details.\n*/\n\ndefine([\n    'uiComponent',\n    'Magento_Customer/js/customer-data'\n], function (Component, customerData) {\n    'use strict';\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this.customer = customerData.get('customer');\n        }\n    });\n});\n","Magento_Customer/js/action/login.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/storage',\n    'Magento_Ui/js/model/messageList',\n    'Magento_Customer/js/customer-data',\n    'mage/translate'\n], function ($, storage, globalMessageList, customerData, $t) {\n    'use strict';\n\n    var callbacks = [],\n\n        /**\n         * @param {Object} loginData\n         * @param {String} redirectUrl\n         * @param {*} isGlobal\n         * @param {Object} messageContainer\n         */\n        action = function (loginData, redirectUrl, isGlobal, messageContainer) {\n            messageContainer = messageContainer || globalMessageList;\n            let customerLoginUrl = 'customer/ajax/login';\n\n            if (loginData.customerLoginUrl) {\n                customerLoginUrl = loginData.customerLoginUrl;\n                delete loginData.customerLoginUrl;\n            }\n\n            return storage.post(\n                customerLoginUrl,\n                JSON.stringify(loginData),\n                isGlobal\n            ).done(function (response) {\n                if (response.errors) {\n                    messageContainer.addErrorMessage(response);\n                    callbacks.forEach(function (callback) {\n                        callback(loginData);\n                    });\n                } else {\n                    callbacks.forEach(function (callback) {\n                        callback(loginData);\n                    });\n                    customerData.invalidate(['customer']);\n\n                    if (response.redirectUrl) {\n                        window.location.href = response.redirectUrl;\n                    } else if (redirectUrl) {\n                        window.location.href = redirectUrl;\n                    } else {\n                        location.reload();\n                    }\n                }\n            }).fail(function () {\n                messageContainer.addErrorMessage({\n                    'message': $t('Could not authenticate. Please try again later')\n                });\n                callbacks.forEach(function (callback) {\n                    callback(loginData);\n                });\n            });\n        };\n\n    /**\n     * @param {Function} callback\n     */\n    action.registerLoginCallback = function (callback) {\n        callbacks.push(callback);\n    };\n\n    return action;\n});\n","Magento_Customer/js/action/check-email-availability.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'mage/storage',\n    'Magento_Checkout/js/model/url-builder'\n], function (storage, urlBuilder) {\n    'use strict';\n\n    return function (deferred, email) {\n        return storage.post(\n            urlBuilder.createUrl('/customers/isEmailAvailable', {}),\n            JSON.stringify({\n                customerEmail: email\n            }),\n            false\n        ).done(function (isEmailAvailable) {\n            if (isEmailAvailable) {\n                deferred.resolve();\n            } else {\n                deferred.reject();\n            }\n        }).fail(function () {\n            deferred.reject();\n        });\n    };\n});\n","Magento_Customer/js/model/authentication-popup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/modal'\n], function ($, modal) {\n    'use strict';\n\n    return {\n        modalWindow: null,\n\n        /**\n         * Create popUp window for provided element\n         *\n         * @param {HTMLElement} element\n         */\n        createPopUp: function (element) {\n            var options = {\n                'type': 'popup',\n                'modalClass': 'popup-authentication',\n                'focus': '[name=username]',\n                'responsive': true,\n                'innerScroll': true,\n                'trigger': '.proceed-to-checkout',\n                'buttons': []\n            };\n\n            this.modalWindow = element;\n            modal(options, $(this.modalWindow));\n        },\n\n        /** Show login popup window */\n        showModal: function () {\n            $(this.modalWindow).modal('openModal').trigger('contentUpdated');\n        }\n    };\n});\n","Magento_Customer/js/model/address-list.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'ko',\n    './customer-addresses'\n], function (ko, defaultProvider) {\n    'use strict';\n\n    return ko.observableArray(defaultProvider.getAddressItems());\n});\n","Magento_Customer/js/model/customer-addresses.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'ko',\n    './customer/address'\n], function ($, ko, Address) {\n    'use strict';\n\n    var isLoggedIn = ko.observable(window.isCustomerLoggedIn);\n\n    return {\n        /**\n         * @return {Array}\n         */\n        getAddressItems: function () {\n            var items = [],\n                customerData = window.customerData;\n\n            if (isLoggedIn()) {\n                if (Object.keys(customerData).length) {\n                    $.each(customerData.addresses, function (key, item) {\n                        items.push(new Address(item));\n                    });\n                }\n            }\n\n            return items;\n        }\n    };\n});\n","Magento_Customer/js/model/customer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'ko',\n    'underscore',\n    './address-list'\n], function ($, ko, _, addressList) {\n    'use strict';\n\n    var isLoggedIn = ko.observable(window.isCustomerLoggedIn),\n        customerData = {};\n\n    if (isLoggedIn()) {\n        customerData = window.customerData;\n    } else {\n        customerData = {};\n    }\n\n    return {\n        customerData: customerData,\n        customerDetails: {},\n        isLoggedIn: isLoggedIn,\n\n        /**\n         * @param {Boolean} flag\n         */\n        setIsLoggedIn: function (flag) {\n            isLoggedIn(flag);\n        },\n\n        /**\n         * @return {Array}\n         */\n        getBillingAddressList: function () {\n            return addressList();\n        },\n\n        /**\n         * @return {Array}\n         */\n        getShippingAddressList: function () {\n            return addressList();\n        },\n\n        /**\n         * @param {String} fieldName\n         * @param {*} value\n         */\n        setDetails: function (fieldName, value) {\n            if (fieldName) {\n                this.customerDetails[fieldName] = value;\n            }\n        },\n\n        /**\n         * @param {String} fieldName\n         * @return {*}\n         */\n        getDetails: function (fieldName) {\n            if (fieldName) {\n                if (this.customerDetails.hasOwnProperty(fieldName)) {\n                    return this.customerDetails[fieldName];\n                }\n\n                return undefined;\n            }\n\n            return this.customerDetails;\n        },\n\n        /**\n         * @param {Array} address\n         * @return {Number}\n         */\n        addCustomerAddress: function (address) {\n            var fields = [\n                    'customer_id', 'country_id', 'street', 'company', 'telephone', 'fax', 'postcode', 'city',\n                    'firstname', 'lastname', 'middlename', 'prefix', 'suffix', 'vat_id', 'default_billing',\n                    'default_shipping'\n                ],\n                customerAddress = {},\n                hasAddress = 0,\n                existingAddress;\n\n            if (!this.customerData.addresses) {\n                this.customerData.addresses = [];\n            }\n\n            customerAddress = _.pick(address, fields);\n\n            if (address.hasOwnProperty('region_id')) {\n                customerAddress.region = {\n                    'region_id': address['region_id'],\n                    region: address.region\n                };\n            }\n\n            for (existingAddress in this.customerData.addresses) {\n                if (this.customerData.addresses.hasOwnProperty(existingAddress)) {\n                    if (_.isEqual(this.customerData.addresses[existingAddress], customerAddress)) { //eslint-disable-line\n                        hasAddress = existingAddress;\n                        break;\n                    }\n                }\n            }\n\n            if (hasAddress === 0) {\n                return this.customerData.addresses.push(customerAddress) - 1;\n            }\n\n            return hasAddress;\n        },\n\n        /**\n         * @param {*} addressId\n         * @return {Boolean}\n         */\n        setAddressAsDefaultBilling: function (addressId) {\n            if (this.customerData.addresses[addressId]) {\n                this.customerData.addresses[addressId]['default_billing'] = 1;\n\n                return true;\n            }\n\n            return false;\n        },\n\n        /**\n         * @param {*} addressId\n         * @return {Boolean}\n         */\n        setAddressAsDefaultShipping: function (addressId) {\n            if (this.customerData.addresses[addressId]) {\n                this.customerData.addresses[addressId]['default_shipping'] = 1;\n\n                return true;\n            }\n\n            return false;\n        }\n    };\n});\n","Magento_Customer/js/model/customer/address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine(['underscore'], function (_) {\n    'use strict';\n\n    /**\n     * Returns new address object.\n     *\n     * @param {Object} addressData\n     * @return {Object}\n     */\n    return function (addressData) {\n        var regionId;\n\n        if (addressData.region['region_id'] && addressData.region['region_id'] !== '0') {\n            regionId = addressData.region['region_id'] + '';\n        }\n\n        return {\n            customerAddressId: addressData.id,\n            email: addressData.email,\n            countryId: addressData['country_id'],\n            regionId: regionId,\n            regionCode: addressData.region['region_code'],\n            region: addressData.region.region,\n            customerId: addressData['customer_id'],\n            street: addressData.street,\n            company: addressData.company,\n            telephone: addressData.telephone,\n            fax: addressData.fax,\n            postcode: addressData.postcode,\n            city: addressData.city,\n            firstname: addressData.firstname,\n            lastname: addressData.lastname,\n            middlename: addressData.middlename,\n            prefix: addressData.prefix,\n            suffix: addressData.suffix,\n            vatId: addressData['vat_id'],\n            sameAsBilling: addressData['same_as_billing'],\n            saveInAddressBook: addressData['save_in_address_book'],\n            customAttributes: _.toArray(addressData['custom_attributes']).reverse(),\n\n            /**\n             * @return {*}\n             */\n            isDefaultShipping: function () {\n                return addressData['default_shipping'];\n            },\n\n            /**\n             * @return {*}\n             */\n            isDefaultBilling: function () {\n                return addressData['default_billing'];\n            },\n\n            /**\n             * @return {*}\n             */\n            getAddressInline: function () {\n                return addressData.inline;\n            },\n\n            /**\n             * @return {String}\n             */\n            getType: function () {\n                return 'customer-address';\n            },\n\n            /**\n             * @return {String}\n             */\n            getKey: function () {\n                return this.getType() + this.customerAddressId;\n            },\n\n            /**\n             * @return {String}\n             */\n            getCacheKey: function () {\n                return this.getKey();\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            isEditable: function () {\n                return false;\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            canUseForBilling: function () {\n                return true;\n            }\n        };\n    };\n});\n","Magento_ReCaptchaStorePickup/js/reCaptchaStorePickup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['Magento_ReCaptchaFrontendUi/js/reCaptcha'], function (reCaptcha) {\n    'use strict';\n\n    return reCaptcha.extend({\n\n        /**\n         * @inheritdoc\n         */\n        renderReCaptcha: function () {\n            this.captchaInitialized = false;\n            this._super();\n        }\n    });\n});\n","mage/toggle.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.toggleAdvanced', {\n        options: {\n            baseToggleClass: 'active' // Class used to be toggled on clicked element\n        },\n\n        /**\n         * Toggle creation\n         * @private\n         */\n        _create: function () {\n            this.beforeCreate();\n            this._bindCore();\n            this.afterCreate();\n        },\n\n        /**\n         *  Core bound events & setup\n         * @protected\n         */\n        _bindCore: function () {\n            var widget = this;\n\n            this.element.on('click', $.proxy(function (e) {\n                widget._onClick();\n                e.preventDefault();\n            }, this));\n        },\n\n        /**\n         * Binding Click event\n         *\n         * @protected\n         */\n        _onClick: function () {\n            this._prepareOptions();\n            this._toggleSelectors();\n        },\n\n        /**\n         * Method used to look for data attributes to override default options\n         *\n         * @protected\n         */\n        _prepareOptions: function () {\n            this.options.baseToggleClass = this.element.data('base-toggle-class') ?\n                this.element.data('base-toggle-class') : this.options.baseToggleClass;\n        },\n\n        /**\n         * Method responsible for hiding and revealing specified DOM elements\n         * Toggle the class on clicked element\n         *\n         * @protected\n         */\n        _toggleSelectors: function () {\n            this.element.toggleClass(this.options.baseToggleClass);\n        },\n\n        /**\n         * Method used to inject 3rd party functionality before create\n         * @public\n         */\n        beforeCreate: function () {},\n\n        /**\n         * Method used to inject 3rd party functionality after create\n         * @public\n         */\n        afterCreate: function () {}\n    });\n\n    // Extension for mage.toggle - Adding selectors support for other DOM elements we wish to toggle\n    $.widget('mage.toggleAdvanced', $.mage.toggleAdvanced, {\n\n        options: {\n            selectorsToggleClass: 'hidden',    // Class used to be toggled on selectors DOM elements\n            toggleContainers: null\n        },\n\n        /**\n         * Method responsible for hiding and revealing specified DOM elements\n         * If data-toggle-selectors attribute is present - toggle will be done on these selectors\n         * Otherwise we toggle the class on clicked element\n         *\n         * @protected\n         * @override\n         */\n        _toggleSelectors: function () {\n            this._super();\n\n            if (this.options.toggleContainers) {\n                $(this.options.toggleContainers).toggleClass(this.options.selectorsToggleClass);\n            } else {\n                this.element.toggleClass(this.options.baseToggleClass);\n            }\n        },\n\n        /**\n         * Method used to look for data attributes to override default options\n         *\n         * @protected\n         * @override\n         */\n        _prepareOptions: function () {\n            this.options.selectorsToggleClass = this.element.data('selectors-toggle-class') ?\n                this.element.data('selectors-toggle-class') : this.options.selectorsToggleClass;\n            this.options.toggleContainers = this.element.data('toggle-selectors') ?\n                this.element.data('toggle-selectors') : this.options.toggleContainers;\n            this._super();\n        }\n    });\n\n    // Extension for mage.toggle - Adding label toggle\n    $.widget('mage.toggleAdvanced', $.mage.toggleAdvanced, {\n\n        options: {\n            newLabel: null,             // Text of the new label to be used on toggle\n            curLabel: null,             // Text of the old label to be used on toggle\n            currentLabelElement: null   // Current label container\n        },\n\n        /**\n         * Binding Click event\n         *\n         * @protected\n         * @override\n         */\n        _onClick: function () {\n            this._super();\n            this._toggleLabel();\n        },\n\n        /**\n         * Method responsible for replacing clicked element labels\n         * @protected\n         */\n        _toggleLabel: function () {\n            var cachedLabel, currentLabelSelector;\n\n            if (this.options.newLabel) {\n                cachedLabel = this.options.newLabel;\n                currentLabelSelector = this.options.currentLabelElement ?\n                        $(this.options.currentLabelElement) : this.element;\n\n                this.element.data('toggle-label', this.options.curLabel);\n                currentLabelSelector.html(this.options.newLabel);\n\n                this.options.curLabel = this.options.newLabel;\n                this.options.newLabel = cachedLabel;\n            }\n        },\n\n        /**\n         * Method used to look for data attributes to override default options\n         *\n         * @protected\n         * @override\n         */\n        _prepareOptions: function () {\n            this.options.newLabel = this.element.data('toggle-label') ?\n                this.element.data('toggle-label') : this.options.newLabel;\n\n            this.options.currentLabelElement = this.element.data('current-label-el') ?\n                this.element.data('current-label-el') : this.options.currentLabelElement;\n\n            if (!this.options.currentLabelElement) {\n                this.options.currentLabelElement = this.element;\n            }\n\n            this.options.curLabel = $(this.options.currentLabelElement).html();\n\n            this._super();\n        }\n    });\n\n    return $.mage.toggleAdvanced;\n});\n","mage/deletable-item.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated since version 2.2.0\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    /**\n     * This widget is used to tag a DOM element as deletable. By default, it will use the click event on the item with a\n     * data role of delete to trigger the deletion.\n     */\n    $.widget('mage.deletableItem', {\n        options: {\n            deleteEvent: 'click',\n            deleteSelector: '[data-role=\"delete\"]',\n            hiddenClass: 'no-display'\n        },\n\n        /**\n         * This method binds elements found in this widget.\n         */\n        _bind: function () {\n            var handlers = {};\n\n            // since the first handler is dynamic, generate the object using array notation\n            handlers[this.options.deleteEvent + ' ' + this.options.deleteSelector] = '_onDeleteClicked';\n            handlers.hideDelete = '_onHideDelete';\n            handlers.showDelete = '_onShowDelete';\n\n            this._on(handlers);\n        },\n\n        /**\n         * This method constructs a new widget.\n         */\n        _create: function () {\n            this._bind();\n        },\n\n        /**\n         * This method is to initialize the control\n         * @private\n         */\n        _init: function () {\n            this._onHideDelete(); // by default, hide the control\n        },\n\n        /**\n         * This method removes the entity from the DOM.\n         * @private\n         */\n        _onDeleteClicked: function (e) {\n            e.stopPropagation();\n            this.element.trigger('deleteItem');\n        },\n\n        /**\n         * This method hides the delete capability of this item (i.e. making it not deletable)\n         * @private\n         */\n        _onHideDelete: function () {\n            this.element.find(this.options.deleteSelector).addClass(this.options.hiddenClass);\n        },\n\n        /**\n         * This method shows the delete capability of this item (i.e. making it deletable)\n         * @private\n         */\n        _onShowDelete: function () {\n            this.element.find(this.options.deleteSelector).removeClass(this.options.hiddenClass);\n        }\n    });\n\n    return $.mage.deletableItem;\n});\n","mage/touch-slider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'jquery-ui-modules/slider'\n], function ($, _) {\n    'use strict';\n\n    /**\n     * Adds support for touch events for regular jQuery UI slider.\n     */\n    $.widget('mage.touchSlider', $.ui.slider, {\n\n        /**\n         * Creates instance of widget.\n         *\n         * @override\n         */\n        _create: function () {\n            _.bindAll(\n                this,\n                '_mouseDown',\n                '_mouseMove',\n                '_onTouchEnd'\n            );\n\n            return this._superApply(arguments);\n        },\n\n        /**\n         * Initializes mouse events on element.\n         * @override\n         */\n        _mouseInit: function () {\n            var result = this._superApply(arguments);\n\n            this.element\n                .off('mousedown.' + this.widgetName)\n                .on('touchstart.' + this.widgetName, this._mouseDown);\n\n            return result;\n        },\n\n        /**\n         * Elements' 'mousedown' event handler polyfill.\n         * @override\n         */\n        _mouseDown: function (event) {\n            var prevDelegate = this._mouseMoveDelegate,\n                result;\n\n            event = this._touchToMouse(event);\n            result = this._super(event);\n\n            if (prevDelegate === this._mouseMoveDelegate) {\n                return result;\n            }\n\n            $(document)\n                .off('mousemove.' + this.widgetName)\n                .off('mouseup.' + this.widgetName);\n\n            $(document)\n                .on('touchmove.' + this.widgetName, this._mouseMove)\n                .on('touchend.' + this.widgetName, this._onTouchEnd)\n                .on('tochleave.' + this.widgetName, this._onTouchEnd);\n\n            return result;\n        },\n\n        /**\n         * Documents' 'mousemove' event handler polyfill.\n         *\n         * @override\n         * @param {Event} event - Touch event object.\n         */\n        _mouseMove: function (event) {\n            event = this._touchToMouse(event);\n\n            return this._super(event);\n        },\n\n        /**\n         * Documents' 'touchend' event handler.\n         */\n        _onTouchEnd: function (event) {\n            $(document).trigger('mouseup');\n\n            return this._mouseUp(event);\n        },\n\n        /**\n         * Removes previously assigned touch handlers.\n         *\n         * @override\n         */\n        _mouseUp: function () {\n            this._removeTouchHandlers();\n\n            return this._superApply(arguments);\n        },\n\n        /**\n         * Removes previously assigned touch handlers.\n         *\n         * @override\n         */\n        _mouseDestroy: function () {\n            this._removeTouchHandlers();\n\n            return this._superApply(arguments);\n        },\n\n        /**\n         * Removes touch events from document object.\n         */\n        _removeTouchHandlers: function () {\n            $(document)\n                .off('touchmove.' + this.widgetName)\n                .off('touchend.' + this.widgetName)\n                .off('touchleave.' + this.widgetName);\n        },\n\n        /**\n         * Adds properties to the touch event to mimic mouse event.\n         *\n         * @param {Event} event - Touch event object.\n         * @returns {Event}\n         */\n        _touchToMouse: function (event) {\n            var orig = event.originalEvent,\n                touch = orig.touches[0];\n\n            return _.extend(event, {\n                which:      1,\n                pageX:      touch.pageX,\n                pageY:      touch.pageY,\n                clientX:    touch.clientX,\n                clientY:    touch.clientY,\n                screenX:    touch.screenX,\n                screenY:    touch.screenY\n            });\n        }\n    });\n\n    return $.mage.touchSlider;\n});\n","mage/tabs.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'jquery/ui-modules/widgets/tabs',\n    'mage/mage',\n    'mage/collapsible'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.tabs', {\n        options: {\n            active: 0,\n            disabled: [],\n            openOnFocus: true,\n            collapsible: false,\n            collapsibleElement: '[data-role=collapsible]',\n            header: '[data-role=title]',\n            content: '[data-role=content]',\n            trigger: '[data-role=trigger]',\n            closedState: null,\n            openedState: null,\n            disabledState: null,\n            ajaxUrlElement: '[data-ajax=true]',\n            ajaxContent: false,\n            loadingClass: null,\n            saveState: false,\n            animate: false,\n            icons: {\n                activeHeader: null,\n                header: null\n            }\n        },\n\n        /**\n         * @private\n         */\n        _create: function () {\n            if (typeof this.options.disabled === 'string') {\n                this.options.disabled = this.options.disabled.split(' ').map(function (item) {\n                    return parseInt(item, 10);\n                });\n            }\n            this._processPanels();\n            this._handleDeepLinking();\n            this._processTabIndex();\n            this._closeOthers();\n            this._bind();\n        },\n\n        /**\n         * @private\n         */\n        _destroy: function () {\n            $.each(this.collapsibles, function () {\n                $(this).collapsible('destroy');\n            });\n        },\n\n        /**\n         * If deep linking is used, all sections must be closed but the one that contains the anchor.\n         * @private\n         */\n        _handleDeepLinking: function () {\n            var self = this,\n                anchor = window.location.hash,\n                isValid = $.mage.isValidSelector(anchor),\n                anchorId = anchor.replace('#', '');\n\n            if (anchor && isValid) {\n                $.each(self.contents, function (i) {\n                    if ($(this).attr('id') === anchorId || $(this).find('#' + anchorId).length) {\n                        self.collapsibles.not(self.collapsibles.eq(i)).collapsible('forceDeactivate');\n\n                        return false;\n                    }\n                });\n            }\n        },\n\n        /**\n         * When the widget gets instantiated, the first tab that is not disabled receive focusable property\n         * All tabs receive tabIndex 0\n         * @private\n         */\n        _processTabIndex: function () {\n            var self = this;\n\n            self.triggers.attr('tabIndex', 0);\n            $.each(this.collapsibles, function (i) {\n                self.triggers.attr('tabIndex', 0);\n                self.triggers.eq(i).attr('tabIndex', 0);\n            });\n        },\n\n        /**\n         * Prepare the elements for instantiating the collapsible widget\n         * @private\n         */\n        _processPanels: function () {\n            var isNotNested = this._isNotNested.bind(this);\n\n            this.contents = this.element\n                .find(this.options.content)\n                .filter(isNotNested);\n\n            this.collapsibles =  this.element\n                .find(this.options.collapsibleElement)\n                .filter(isNotNested);\n\n            this.collapsibles\n                .attr('role', 'presentation')\n                .parent()\n                .attr('role', 'tablist');\n\n            this.headers = this.element\n                .find(this.options.header)\n                .filter(isNotNested);\n\n            if (this.headers.length === 0) {\n                this.headers = this.collapsibles;\n            }\n            this.triggers = this.element\n                .find(this.options.trigger)\n                .filter(isNotNested);\n\n            if (this.triggers.length === 0) {\n                this.triggers = this.headers;\n            }\n            this._callCollapsible();\n        },\n\n        /**\n         * Checks if element is not in nested container to keep the correct scope of collapsible\n         * @param {Number} index\n         * @param {HTMLElement} element\n         * @private\n         * @return {Boolean}\n         */\n        _isNotNested: function (index, element) {\n            var parentContent = $(element).parents(this.options.content);\n\n            return !parentContent.length || !this.element.find(parentContent).length;\n        },\n\n        /**\n         * Setting the disabled and active tabs and calling instantiation of collapsible\n         * @private\n         */\n        _callCollapsible: function () {\n            var self = this,\n                disabled = false,\n                active = false;\n\n            $.each(this.collapsibles, function (i) {\n                disabled = active = false;\n\n                if ($.inArray(i, self.options.disabled) !== -1) {\n                    disabled = true;\n                }\n\n                if (i === self.options.active) {\n                    active = true;\n                }\n                self._instantiateCollapsible(this, i, active, disabled);\n            });\n        },\n\n        /**\n         * Instantiate collapsible.\n         *\n         * @param {HTMLElement} element\n         * @param {Number} index\n         * @param {*} active\n         * @param {*} disabled\n         * @private\n         */\n        _instantiateCollapsible: function (element, index, active, disabled) {\n            $(element).collapsible(\n                $.extend({}, this.options, {\n                    active: active,\n                    disabled: disabled,\n                    header: this.headers.eq(index),\n                    content: this.contents.eq(index),\n                    trigger: this.triggers.eq(index)\n                })\n            );\n        },\n\n        /**\n         * Adding callback to close others tabs when one gets opened\n         * @private\n         */\n        _closeOthers: function () {\n            var self = this;\n\n            $.each(this.collapsibles, function () {\n                $(this).on('beforeOpen', function () {\n                    self.collapsibles.not(this).collapsible('forceDeactivate');\n                });\n            });\n        },\n\n        /**\n         * @param {*} index\n         */\n        activate: function (index) {\n            this._toggleActivate('activate', index);\n        },\n\n        /**\n         * @param {*} index\n         */\n        deactivate: function (index) {\n            this._toggleActivate('deactivate', index);\n        },\n\n        /**\n         * @param {*} action\n         * @param {*} index\n         * @private\n         */\n        _toggleActivate: function (action, index) {\n            this.collapsibles.eq(index).collapsible(action);\n        },\n\n        /**\n         * @param {*} index\n         */\n        disable: function (index) {\n            this._toggleEnable('disable', index);\n        },\n\n        /**\n         * @param {*} index\n         */\n        enable: function (index) {\n            this._toggleEnable('enable', index);\n        },\n\n        /**\n         * @param {*} action\n         * @param {*} index\n         * @private\n         */\n        _toggleEnable: function (action, index) {\n            var self = this;\n\n            if (Array.isArray(index)) {\n                $.each(index, function () {\n                    self.collapsibles.eq(this).collapsible(action);\n                });\n            } else if (index === undefined) {\n                this.collapsibles.collapsible(action);\n            } else {\n                this.collapsibles.eq(index).collapsible(action);\n            }\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _keydown: function (event) {\n            var self = this,\n                keyCode, toFocus, toFocusIndex, enabledTriggers, length, currentIndex, nextToFocus;\n\n            if (event.altKey || event.ctrlKey) {\n                return;\n            }\n            keyCode = $.ui.keyCode;\n            toFocus = false;\n            enabledTriggers = [];\n\n            $.each(this.triggers, function () {\n                if (!self.collapsibles.eq(self.triggers.index($(this))).collapsible('option', 'disabled')) {\n                    enabledTriggers.push(this);\n                }\n            });\n            length = $(enabledTriggers).length;\n            currentIndex = $(enabledTriggers).index(event.target);\n\n            /**\n             * @param {String} direction\n             * @return {*}\n             */\n            nextToFocus = function (direction) {\n                if (length > 0) {\n                    if (direction === 'right') {\n                        toFocusIndex = (currentIndex + 1) % length;\n                    } else {\n                        toFocusIndex = (currentIndex + length - 1) % length;\n                    }\n\n                    return enabledTriggers[toFocusIndex];\n                }\n\n                return event.target;\n            };\n\n            switch (event.keyCode) {\n                case keyCode.RIGHT:\n                case keyCode.DOWN:\n                    toFocus = nextToFocus('right');\n                    break;\n\n                case keyCode.LEFT:\n                case keyCode.UP:\n                    toFocus = nextToFocus('left');\n                    break;\n\n                case keyCode.HOME:\n                    toFocus = enabledTriggers[0];\n                    break;\n\n                case keyCode.END:\n                    toFocus = enabledTriggers[length - 1];\n                    break;\n            }\n\n            if (toFocus) {\n                toFocusIndex = this.triggers.index(toFocus);\n                $(event.target).attr('tabIndex', -1);\n                $(toFocus).attr('tabIndex', 0);\n                toFocus.focus();\n\n                if (this.options.openOnFocus) {\n                    this.activate(toFocusIndex);\n                }\n                event.preventDefault();\n            }\n        },\n\n        /**\n         * @private\n         */\n        _bind: function () {\n            var events = {\n                keydown: '_keydown'\n            };\n\n            this._off(this.triggers);\n            this._on(this.triggers, events);\n        }\n    });\n\n    return $.mage.tabs;\n});\n","mage/trim-input.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.trimInput', {\n        options: {\n            cache: {}\n        },\n\n        /**\n         * Widget initialization\n         * @private\n         */\n        _create: function () {\n            this.options.cache.input = $(this.element);\n            this._bind();\n        },\n\n        /**\n         * Event binding, will monitor change, keyup and paste events.\n         * @private\n         */\n        _bind: function () {\n            if (this.options.cache.input.length) {\n                this._on(this.options.cache.input, {\n                    'change': this._trimInput,\n                    'keyup': this._trimInput,\n                    'paste': this._trimInput\n                });\n            }\n        },\n\n        /**\n         * Trim value\n         * @private\n         */\n        _trimInput: function () {\n            // Safari caret position workaround: storing carter position\n            var caretStart, caretEnd, input;\n\n            caretStart = this.options.cache.input.get(0).selectionStart;\n            caretEnd = this.options.cache.input.get(0).selectionEnd;\n\n            input = this._getInputValue().trim();\n\n            this.options.cache.input.val(input);\n\n            // Safari caret position workaround: setting caret position to previously stored values\n            if (caretStart !== null && caretEnd !== null) {\n                this.options.cache.input.get(0).setSelectionRange(caretStart, caretEnd);\n            }\n        },\n\n        /**\n         * Get input value\n         * @returns {*}\n         * @private\n         */\n        _getInputValue: function () {\n            return this.options.cache.input.val();\n        }\n    });\n\n    return $.mage.trimInput;\n});\n","mage/cookies.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/mage',\n    'js-cookie/cookie-wrapper'\n], function ($) {\n    'use strict';\n\n    /**\n     * Helper for cookies manipulation\n     * @returns {CookieHelper}\n     * @constructor\n     */\n    var CookieHelper = function () {\n\n        /**\n         * Cookie default values.\n         * @type {Object}\n         */\n        this.defaults = {\n            expires: null,\n            path: '/',\n            domain: null,\n            secure: false,\n            lifetime: null,\n            samesite: 'lax'\n        };\n\n        /**\n         * Calculate cookie expiration date based on its lifetime.\n         * @param {Object} options - Cookie option values\n         * @return {Date|null} Calculated cookie expiration date or null if no lifetime provided.\n         * @private\n         */\n        function lifetimeToExpires(options, defaults) {\n            var expires,\n                lifetime;\n\n            lifetime = options.lifetime || defaults.lifetime;\n\n            if (lifetime && lifetime > 0) {\n                expires = options.expires || new Date();\n\n                return new Date(expires.getTime() + lifetime * 1000);\n            }\n\n            return null;\n        }\n\n        /**\n         * Set a cookie's value by cookie name based on optional cookie options.\n         * @param {String} name - The name of the cookie.\n         * @param {String} value - The cookie's value.\n         * @param {Object} options - Optional options (e.g. lifetime, expires, path, etc.)\n         */\n        this.set = function (name, value, options) {\n            var expires,\n                path,\n                domain,\n                secure,\n                samesite;\n\n            options = $.extend({}, this.defaults, options || {});\n            expires = lifetimeToExpires(options, this.defaults) || options.expires;\n            path = options.path;\n            domain = options.domain;\n            secure = options.secure;\n            samesite = options.samesite;\n\n            document.cookie = name + '=' + encodeURIComponent(value) +\n                (expires ? '; expires=' + expires.toUTCString() :  '') +\n                (path ? '; path=' + path : '') +\n                (domain ? '; domain=' + domain : '') +\n                (secure ? '; secure' : '') +\n                '; samesite=' + (samesite ? samesite : 'lax');\n        };\n\n        /**\n         * Get a cookie's value by cookie name.\n         * @param {String} name  - The name of the cookie.\n         * @return {(null|String)}\n         */\n        this.get = function (name) {\n            var arg = name + '=',\n                aLength = arg.length,\n                cookie = document.cookie,\n                cLength = cookie.length,\n                i = 0,\n                j = 0;\n\n            while (i < cLength) {\n                j = i + aLength;\n\n                if (cookie.substring(i, j) === arg) {\n                    return this.getCookieVal(j);\n                }\n                i = cookie.indexOf(' ', i) + 1;\n\n                if (i === 0) {\n                    break;\n                }\n            }\n\n            return null;\n        };\n\n        /**\n         * Clear a cookie's value by name.\n         * @param {String} name - The name of the cookie being cleared.\n         */\n        this.clear = function (name) {\n            if (this.get(name)) {\n                this.set(name, '', {\n                    expires: new Date('Jan 01 1970 00:00:01 GMT')\n                });\n            }\n        };\n\n        /**\n         * Return URI decoded cookie component value (e.g. expires, path, etc.) based on a\n         * numeric offset in the document's cookie value.\n         * @param {Number} offset - Offset into the document's cookie value.\n         * @return {String}\n         */\n        this.getCookieVal = function (offset) {\n            var cookie = document.cookie,\n                endstr = cookie.indexOf(';', offset);\n\n            if (endstr === -1) {\n                endstr = cookie.length;\n            }\n\n            return decodeURIComponent(cookie.substring(offset, endstr));\n        };\n\n        return this;\n    };\n\n    $.extend(true, $, {\n        mage: {\n            cookies: new CookieHelper()\n        }\n    });\n\n    return function (pageOptions) {\n        $.extend($.mage.cookies.defaults, pageOptions);\n        $.extend($.cookie.defaults, $.mage.cookies.defaults);\n    };\n});\n","mage/redirect-url.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.redirectUrl', {\n        options: {\n            event: 'click',\n            url: undefined\n        },\n\n        /**\n         * This method binds elements found in this widget.\n         * @private\n         */\n        _bind: function () {\n            var handlers = {};\n\n            handlers[this.options.event] = '_onEvent';\n            this._on(handlers);\n        },\n\n        /**\n         * This method constructs a new widget.\n         * @private\n         */\n        _create: function () {\n            this._bind();\n        },\n\n        /**\n         * This method set the url for the redirect.\n         * @private\n         */\n        _onEvent: function () {\n            if (this.options.url) {\n                location.href = this.options.url;\n            } else {\n                location.href = this.element.val();\n            }\n        }\n    });\n\n    return $.mage.redirectUrl;\n});\n","mage/popup-window.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.popupWindow', {\n        options: {\n            centerBrowser: 0, // center window over browser window? {1 (YES) or 0 (NO)}. overrides top and left\n            centerScreen: 0, // center window over entire screen? {1 (YES) or 0 (NO)}. overrides top and left\n            height: 500, // sets the height in pixels of the window.\n            left: 0, // left position when the window appears.\n            location: 0, // determines whether the address bar is displayed {1 (YES) or 0 (NO)}.\n            menubar: 0, // determines whether the menu bar is displayed {1 (YES) or 0 (NO)}.\n            resizable: 0, // whether the window can be resized {1 (YES) or 0 (NO)}.\n            scrollbars: 0, // determines whether scrollbars appear on the window {1 (YES) or 0 (NO)}.\n            status: 0, // whether a status line appears at the bottom of the window {1 (YES) or 0 (NO)}.\n            width: 500, // sets the width in pixels of the window.\n            windowName: null, // name of window set from the name attribute of the element that invokes the click\n            windowURL: null, // url used for the popup\n            top: 0, // top position when the window appears.\n            toolbar: 0 // determines whether a toolbar is displayed {1 (YES) or 0 (NO)}.\n        },\n\n        /**\n         * @private\n         */\n        _create: function () {\n            this.element.on('click', $.proxy(this._openPopupWindow, this));\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _openPopupWindow: function (event) {\n            var element = $(event.target),\n                settings = this.options,\n                windowFeatures =\n                    'height=' + settings.height +\n                        ',width=' + settings.width +\n                        ',toolbar=' + settings.toolbar +\n                        ',scrollbars=' + settings.scrollbars +\n                        ',status=' + settings.status +\n                        ',resizable=' + settings.resizable +\n                        ',location=' + settings.location +\n                        ',menuBar=' + settings.menubar,\n                centeredX,\n                centeredY;\n\n            settings.windowName = settings.windowName || element.attr('name');\n            settings.windowURL = settings.windowURL || element.attr('href');\n\n            if (settings.centerBrowser) {\n                centeredY = window.screenY + (window.outerHeight / 2 - settings.height / 2);\n                centeredX = window.screenX + (window.outerWidth / 2 - settings.width / 2);\n                windowFeatures += ',left=' + centeredX + ',top=' + centeredY;\n            } else if (settings.centerScreen) {\n                centeredY = (screen.height - settings.height) / 2;\n                centeredX = (screen.width - settings.width) / 2;\n                windowFeatures += ',left=' + centeredX + ',top=' + centeredY;\n            } else {\n                windowFeatures += ',left=' + settings.left + ',top=' + settings.top;\n            }\n\n            window.open(settings.windowURL, settings.windowName, windowFeatures).focus();\n            event.preventDefault();\n        }\n    });\n\n    return $.mage.popupWindow;\n});\n","mage/loader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/template',\n    'jquery-ui-modules/widget',\n    'mage/translate'\n], function ($, mageTemplate) {\n    'use strict';\n\n    $.widget('mage.loader', {\n        loaderStarted: 0,\n        options: {\n            icon: '',\n            texts: {\n                loaderText: $.mage.__('Please wait...'),\n                imgAlt: $.mage.__('Loading...')\n            },\n            template:\n                '<div class=\"loading-mask\" data-role=\"loader\">' +\n                    '<div class=\"loader\">' +\n                        '<img alt=\"<%- data.texts.imgAlt %>\" src=\"<%- data.icon %>\">' +\n                        '<p><%- data.texts.loaderText %></p>' +\n                    '</div>' +\n                '</div>'\n\n        },\n\n        /**\n         * Loader creation\n         * @protected\n         */\n        _create: function () {\n            this._bind();\n        },\n\n        /**\n         * Bind on ajax events\n         * @protected\n         */\n        _bind: function () {\n            this._on({\n                'processStop': 'hide',\n                'processStart': 'show',\n                'show.loader': 'show',\n                'hide.loader': 'hide',\n                'contentUpdated.loader': '_contentUpdated'\n            });\n        },\n\n        /**\n         * Verify loader present after content updated\n         *\n         * This will be cleaned up by the task MAGETWO-11070\n         *\n         * @param {EventObject} e\n         * @private\n         */\n        _contentUpdated: function (e) {\n            this.show(e);\n        },\n\n        /**\n         * Show loader\n         */\n        show: function (e, ctx) {\n            this._render();\n            this.loaderStarted++;\n            this.spinner.show();\n\n            if (ctx) {\n                this.spinner\n                    .css({\n                        width: ctx.outerWidth(),\n                        height: ctx.outerHeight(),\n                        position: 'absolute'\n                    })\n                    .position({\n                        my: 'top left',\n                        at: 'top left',\n                        of: ctx\n                    });\n            }\n\n            return false;\n        },\n\n        /**\n         * Hide loader\n         */\n        hide: function () {\n            if (this.loaderStarted > 0) {\n                this.loaderStarted--;\n\n                if (this.loaderStarted === 0) {\n                    this.spinner.hide();\n                }\n            }\n\n            return false;\n        },\n\n        /**\n         * Render loader\n         * @protected\n         */\n        _render: function () {\n            var html;\n\n            if (!this.spinnerTemplate) {\n                this.spinnerTemplate = mageTemplate(this.options.template);\n\n                html = $(this.spinnerTemplate({\n                    data: this.options\n                }));\n\n                html.prependTo(this.element);\n\n                this.spinner = html;\n            }\n        },\n\n        /**\n         * Destroy loader\n         */\n        _destroy: function () {\n            this.spinner.remove();\n        }\n    });\n\n    /**\n     * This widget takes care of registering the needed loader listeners on the body\n     */\n    $.widget('mage.loaderAjax', {\n        options: {\n            defaultContainer: '[data-container=body]',\n            loadingClass: 'ajax-loading'\n        },\n\n        /**\n         * @private\n         */\n        _create: function () {\n            this._bind();\n            // There should only be one instance of this widget, and it should be attached\n            // to the body only. Having it on the page twice will trigger multiple processStarts.\n            if (window.console && !this.element.is(this.options.defaultContainer) && $.mage.isDevMode(undefined)) {\n                console.warn('This widget is intended to be attached to the body, not below.');\n            }\n        },\n\n        /**\n         * @private\n         */\n        _bind: function () {\n            $(document).on({\n                'ajaxSend': this._onAjaxSend.bind(this),\n                'ajaxComplete': this._onAjaxComplete.bind(this)\n            });\n        },\n\n        /**\n         * @param {Object} loaderContext\n         * @return {*}\n         * @private\n         */\n        _getJqueryObj: function (loaderContext) {\n            var ctx;\n\n            // Check to see if context is jQuery object or not.\n            if (loaderContext) {\n                if (loaderContext.jquery) {\n                    ctx = loaderContext;\n                } else {\n                    ctx = $(loaderContext);\n                }\n            } else {\n                ctx = $('[data-container=\"body\"]');\n            }\n\n            return ctx;\n        },\n\n        /**\n         * @param {jQuery.Event} e\n         * @param {Object} jqxhr\n         * @param {Object} settings\n         * @private\n         */\n        _onAjaxSend: function (e, jqxhr, settings) {\n            var ctx;\n\n            $(this.options.defaultContainer)\n                .addClass(this.options.loadingClass)\n                .attr({\n                    'aria-busy': true\n                });\n\n            if (settings && settings.showLoader) {\n                ctx = this._getJqueryObj(settings.loaderContext);\n                ctx.trigger('processStart');\n\n                // Check to make sure the loader is there on the page if not report it on the console.\n                // NOTE that this check should be removed before going live. It is just an aid to help\n                // in finding the uses of the loader that maybe broken.\n                if (window.console && !ctx.parents('[data-role=\"loader\"]').length) {\n                    console.warn('Expected to start loader but did not find one in the dom');\n                }\n            }\n        },\n\n        /**\n         * @param {jQuery.Event} e\n         * @param {Object} jqxhr\n         * @param {Object} settings\n         * @private\n         */\n        _onAjaxComplete: function (e, jqxhr, settings) {\n            $(this.options.defaultContainer)\n                .removeClass(this.options.loadingClass)\n                .attr('aria-busy', false);\n\n            if (settings && settings.showLoader) {\n                this._getJqueryObj(settings.loaderContext).trigger('processStop');\n            }\n        }\n\n    });\n\n    return {\n        loader: $.mage.loader,\n        loaderAjax: $.mage.loaderAjax\n    };\n});\n","mage/bootstrap.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/apply/main',\n    'Magento_Ui/js/lib/knockout/bootstrap'\n], function ($, mage) {\n    'use strict';\n\n    $.ajaxSetup({\n        cache: false\n    });\n\n    /**\n     * Init all components defined via data-mage-init attribute.\n     * Execute in a separate task to prevent main thread blocking.\n     */\n    setTimeout(mage.apply);\n});\n","mage/calendar.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/*eslint max-depth: 0*/\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'jquery-ui-modules/datepicker',\n    'jquery-ui-modules/timepicker'\n], function ($) {\n    'use strict';\n\n    var calendarBasePrototype,\n        datepickerPrototype = $.datepicker.constructor.prototype;\n\n    $.datepicker.markerClassName = '_has-datepicker';\n\n    /**\n     * Extend JQuery date picker prototype with store local time methods\n     */\n    $.extend(datepickerPrototype, {\n        /**\n         * Get date/time according to store settings.\n         * We use serverTimezoneOffset (in seconds) instead of serverTimezoneSeconds\n         * in order to have ability to know actual store time even if page hadn't been reloaded\n         * @returns {Date}\n         */\n        _getTimezoneDate: function (options) {\n            // local time in ms\n            var ms = Date.now();\n\n            options = options || $.calendarConfig || {};\n\n            // Adjust milliseconds according to store timezone offset,\n            // mind the GMT zero offset\n            if (typeof options.serverTimezoneOffset !== 'undefined') {\n                // Make UTC time and add store timezone offset in seconds\n                ms += new Date().getTimezoneOffset() * 60 * 1000 + options.serverTimezoneOffset * 1000;\n            } else if (typeof options.serverTimezoneSeconds !== 'undefined') {\n                //Set milliseconds according to client local timezone offset\n                ms = (options.serverTimezoneSeconds + new Date().getTimezoneOffset() * 60) * 1000;\n            }\n\n            return new Date(ms);\n        },\n\n        /**\n         * Set date/time according to store settings.\n         * @param {String|Object} target - the target input field or division or span\n         */\n        _setTimezoneDateDatepicker: function (target) {\n            this._setDateDatepicker(target, this._getTimezoneDate());\n        }\n    });\n\n    /**\n     * Widget calendar\n     */\n    $.widget('mage.calendar', {\n        options: {\n            autoComplete: true\n        },\n\n        /**\n         * Merge global options with options passed to widget invoke\n         * @protected\n         */\n        _create: function () {\n            this._enableAMPM();\n            this.options = $.extend(\n                {},\n                $.calendarConfig ? $.calendarConfig : {},\n                this.options.showsTime ? {\n                    showTime: true,\n                    showHour: true,\n                    showMinute: true\n                } : {},\n                this.options\n            );\n            this._initPicker(this.element);\n            this._overwriteGenerateHtml();\n        },\n\n        /**\n         * Get picker name\n         * @protected\n         */\n        _picker: function () {\n            return this.options.showsTime ? 'datetimepicker' : 'datepicker';\n        },\n\n        /**\n         * Fix for Timepicker - Set ampm option for Timepicker if timeformat contains string 'tt'\n         * @protected\n         */\n        _enableAMPM: function () {\n            if (this.options.timeFormat && this.options.timeFormat.indexOf('tt') >= 0) {\n                this.options.ampm = true;\n            }\n        },\n\n        /**\n         * Wrapper for overwrite jQuery UI datepicker function.\n         */\n        _overwriteGenerateHtml: function () {\n            /**\n             * Overwrite jQuery UI datepicker function.\n             * Reason: magento date could be set before calendar show\n             * but local date will be styled as current in original _generateHTML\n             *\n             * @param {Object} inst - instance datepicker.\n             * @return {String} html template\n             */\n            $.datepicker.constructor.prototype._generateHTML = function (inst) {\n                var today = this._getTimezoneDate(),\n                    isRTL = this._get(inst, 'isRTL'),\n                    showButtonPanel = this._get(inst, 'showButtonPanel'),\n                    hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'),\n                    navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'),\n                    numMonths = this._getNumberOfMonths(inst),\n                    showCurrentAtPos = this._get(inst, 'showCurrentAtPos'),\n                    stepMonths = this._get(inst, 'stepMonths'),\n                    isMultiMonth = parseInt(numMonths[0], 10) !== 1 || parseInt(numMonths[1], 10) !== 1,\n                    currentDate = this._daylightSavingAdjust(!inst.currentDay ? new Date(9999, 9, 9) :\n                        new Date(inst.currentYear, inst.currentMonth, inst.currentDay)),\n                    minDate = this._getMinMaxDate(inst, 'min'),\n                    maxDate = this._getMinMaxDate(inst, 'max'),\n                    drawMonth = inst.drawMonth - showCurrentAtPos,\n                    drawYear = inst.drawYear,\n                    maxDraw,\n                    prevText = this._get(inst, 'prevText'),\n                    prev,\n                    nextText = this._get(inst, 'nextText'),\n                    next,\n                    currentText = this._get(inst, 'currentText'),\n                    gotoDate,\n                    controls,\n                    buttonPanel,\n                    firstDay,\n                    showWeek = this._get(inst, 'showWeek'),\n                    dayNames = this._get(inst, 'dayNames'),\n                    dayNamesMin = this._get(inst, 'dayNamesMin'),\n                    monthNames = this._get(inst, 'monthNames'),\n                    monthNamesShort =  this._get(inst, 'monthNamesShort'),\n                    beforeShowDay = this._get(inst, 'beforeShowDay'),\n                    showOtherMonths = this._get(inst, 'showOtherMonths'),\n                    selectOtherMonths = this._get(inst, 'selectOtherMonths'),\n                    defaultDate = this._getDefaultDate(inst),\n                    html = '',\n                    row = 0,\n                    col = 0,\n                    selectedDate,\n                    cornerClass = ' ui-corner-all',\n                    group = '',\n                    calender = '',\n                    dow = 0,\n                    thead,\n                    day,\n                    daysInMonth,\n                    leadDays,\n                    curRows,\n                    numRows,\n                    printDate,\n                    dRow = 0,\n                    tbody,\n                    daySettings,\n                    otherMonth,\n                    unselectable;\n\n                if (drawMonth < 0) {\n                    drawMonth += 12;\n                    drawYear--;\n                }\n\n                if (maxDate) {\n                    maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),\n                        maxDate.getMonth() - numMonths[0] * numMonths[1] + 1, maxDate.getDate()));\n                    maxDraw = minDate && maxDraw < minDate ? minDate : maxDraw;\n\n                    while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {\n                        drawMonth--;\n\n                        if (drawMonth < 0) {\n                            drawMonth = 11;\n                            drawYear--;\n\n                        }\n                    }\n                }\n                inst.drawMonth = drawMonth;\n                inst.drawYear = drawYear;\n                prevText = !navigationAsDateFormat ? prevText : this.formatDate(prevText,\n                    this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),\n                    this._getFormatConfig(inst));\n                prev = this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?\n                    '<a class=\"ui-datepicker-prev ui-corner-all\" data-handler=\"prev\" data-event=\"click\"' +\n                    ' title=\"' + prevText + '\">' +\n                    '<span class=\"ui-icon ui-icon-circle-triangle-' + (isRTL ? 'e' : 'w') + '\">' +\n                    '' + prevText + '</span></a>'\n                    : hideIfNoPrevNext ? ''\n                        :   '<a class=\"ui-datepicker-prev ui-corner-all ui-state-disabled\" title=\"' +\n                            '' + prevText + '\"><span class=\"ui-icon ui-icon-circle-triangle-' +\n                            '' + (isRTL ? 'e' : 'w') + '\">' + prevText + '</span></a>';\n                nextText = !navigationAsDateFormat ?\n                    nextText\n                    :   this.formatDate(nextText,\n                        this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),\n                        this._getFormatConfig(inst));\n                next = this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?\n                    '<a class=\"ui-datepicker-next ui-corner-all\" data-handler=\"next\" data-event=\"click\"' +\n                    'title=\"' + nextText + '\"><span class=\"ui-icon ui-icon-circle-triangle-' +\n                    '' + (isRTL ? 'w' : 'e') + '\">' + nextText + '</span></a>'\n                    : hideIfNoPrevNext ? ''\n                        :   '<a class=\"ui-datepicker-next ui-corner-all ui-state-disabled\" title=\"' + nextText + '\">' +\n                            '<span class=\"ui-icon ui-icon-circle-triangle-' + (isRTL ? 'w' : 'e') + '\">' + nextText +\n                            '</span></a>';\n                gotoDate = this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today;\n                currentText = !navigationAsDateFormat ? currentText :\n                    this.formatDate(currentText, gotoDate, this._getFormatConfig(inst));\n                controls = !inst.inline ?\n                    '<button type=\"button\" class=\"ui-datepicker-close ui-state-default ui-priority-primary ' +\n                    'ui-corner-all\" data-handler=\"hide\" data-event=\"click\">' +\n                    this._get(inst, 'closeText') + '</button>'\n                    : '';\n                buttonPanel = showButtonPanel ?\n                    '<div class=\"ui-datepicker-buttonpane ui-widget-content\">' + (isRTL ? controls : '') +\n                    (this._isInRange(inst, gotoDate) ? '<button type=\"button\" class=\"ui-datepicker-current ' +\n                    'ui-state-default ui-priority-secondary ui-corner-all\" data-handler=\"today\" data-event=\"click\"' +\n                    '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';\n                firstDay = parseInt(this._get(inst, 'firstDay'), 10);\n                firstDay = isNaN(firstDay) ? 0 : firstDay;\n\n                for (row = 0; row < numMonths[0]; row++) {\n                    this.maxRows = 4;\n\n                    for (col = 0; col < numMonths[1]; col++) {\n                        selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));\n\n                        calender = '';\n\n                        if (isMultiMonth) {\n                            calender += '<div class=\"ui-datepicker-group';\n\n                            if (numMonths[1] > 1) {\n                                switch (col) {\n                                    case 0: calender += ' ui-datepicker-group-first';\n                                        cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left');\n                                        break;\n\n                                    case numMonths[1] - 1: calender += ' ui-datepicker-group-last';\n                                        cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right');\n                                        break;\n\n                                    default: calender += ' ui-datepicker-group-middle'; cornerClass = '';\n                                }\n                            }\n                            calender += '\">';\n                        }\n                        calender += '<div class=\"ui-datepicker-header ' +\n                            'ui-widget-header ui-helper-clearfix' + cornerClass + '\">' +\n                            (/all|left/.test(cornerClass) && parseInt(row, 10) === 0 ? isRTL ? next : prev : '') +\n                            (/all|right/.test(cornerClass) && parseInt(row, 10) === 0 ? isRTL ? prev : next : '') +\n                            this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,\n                            row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers\n                            '</div><table class=\"ui-datepicker-calendar\"><thead>' +\n                            '<tr>';\n                        thead = showWeek ?\n                            '<th class=\"ui-datepicker-week-col\">' + this._get(inst, 'weekHeader') + '</th>' : '';\n\n                        for (dow = 0; dow < 7; dow++) { // days of the week\n                            day = (dow + firstDay) % 7;\n                            thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ?\n                                ' class=\"ui-datepicker-week-end\"' : '') + '>' +\n                                '<span title=\"' + dayNames[day] + '\">' + dayNamesMin[day] + '</span></th>';\n                        }\n                        calender += thead + '</tr></thead><tbody>';\n                        daysInMonth = this._getDaysInMonth(drawYear, drawMonth);\n\n                        if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {\n                            inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);\n                        }\n                        leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;\n                        curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate\n                        numRows = isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows;\n                        this.maxRows = numRows;\n                        printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));\n\n                        for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows\n                            calender += '<tr>';\n                            tbody = !showWeek ? '' : '<td class=\"ui-datepicker-week-col\">' +\n                            this._get(inst, 'calculateWeek')(printDate) + '</td>';\n\n                            for (dow = 0; dow < 7; dow++) { // create date picker days\n                                daySettings = beforeShowDay ?\n                                    beforeShowDay.apply(inst.input ? inst.input[0] : null, [printDate]) : [true, ''];\n                                otherMonth = printDate.getMonth() !== drawMonth;\n                                unselectable = otherMonth && !selectOtherMonths || !daySettings[0] ||\n                                minDate && printDate < minDate || maxDate && printDate > maxDate;\n                                tbody += '<td class=\"' +\n                                ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends\n                                (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months\n                                (printDate.getTime() === selectedDate.getTime() &&\n                                drawMonth === inst.selectedMonth && inst._keyEvent || // user pressed key\n                                defaultDate.getTime() === printDate.getTime() &&\n                                defaultDate.getTime() === selectedDate.getTime() ?\n                                    // or defaultDate is current printedDate and defaultDate is selectedDate\n                                ' ' + this._dayOverClass : '') + // highlight selected day\n                                (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled' : '') +\n                                (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates\n                                (printDate.getTime() === currentDate.getTime() ? ' ' + this._currentClass : '') +\n                                (printDate.getDate() === today.getDate() && printDate.getMonth() === today.getMonth() &&\n                                printDate.getYear() === today.getYear() ? ' ui-datepicker-today' : '')) + '\"' +\n                                ((!otherMonth || showOtherMonths) && daySettings[2] ?\n                                ' title=\"' + daySettings[2] + '\"' : '') + // cell title\n                                (unselectable ? '' : ' data-handler=\"selectDay\" data-event=\"click\" data-month=\"' +\n                                '' + printDate.getMonth() + '\" data-year=\"' + printDate.getFullYear() + '\"') + '>' +\n                                (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months\n                                    unselectable ? '<span class=\"ui-state-default\">' + printDate.getDate() + '</span>'\n                                        : '<a class=\"ui-state-default' +\n                                    (printDate.getTime() === today.getTime() ? ' ' : '') +\n                                    (printDate.getTime() === currentDate.getTime() ? ' ui-state-active' : '') +\n                                    (otherMonth ? ' ui-priority-secondary' : '') +\n                                    '\" data-date=\"' + printDate.getDate() + '\" href=\"#\">' +\n                                        printDate.getDate() + '</a>') + '</td>';\n                                printDate.setDate(printDate.getDate() + 1);\n                                printDate = this._daylightSavingAdjust(printDate);\n                            }\n                            calender += tbody + '</tr>';\n                        }\n                        drawMonth++;\n\n                        if (drawMonth > 11) {\n                            drawMonth = 0;\n                            drawYear++;\n                        }\n                        calender += '</tbody></table>' + (isMultiMonth ? '</div>' +\n                        (numMonths[0] > 0 && col === numMonths[1] - 1 ? '<div class=\"ui-datepicker-row-break\"></div>'\n                            : '') : '');\n                        group += calender;\n                    }\n                    html += group;\n                }\n                html += buttonPanel + ($.ui.ie6 && !inst.inline ?\n                    '<iframe src=\"javascript:false;\" class=\"ui-datepicker-cover\" frameborder=\"0\"></iframe>' : '');\n                inst._keyEvent = false;\n\n                return html;\n            };\n        },\n\n        /**\n         * Set current date if the date is not set\n         * @protected\n         * @param {Object} element\n         */\n        _setCurrentDate: function (element) {\n            if (!element.val()) {\n                element[this._picker()]('setTimezoneDate').val('');\n            }\n        },\n\n        /**\n         * Init Datetimepicker\n         * @protected\n         * @param {Object} element\n         */\n        _initPicker: function (element) {\n            var picker = element[this._picker()](this.options),\n                pickerButtonText = picker.next('.ui-datepicker-trigger')\n                    .find('img')\n                    .attr('title');\n\n            picker.next('.ui-datepicker-trigger')\n                .addClass('v-middle')\n                .text('') // Remove jQuery UI datepicker generated image\n                .append('<span>' + pickerButtonText + '</span>');\n\n            $(element).attr('autocomplete', this.options.autoComplete ? 'on' : 'off');\n\n            this._setCurrentDate(element);\n        },\n\n        /**\n         * destroy instance of datetimepicker\n         */\n        _destroy: function () {\n            this.element[this._picker()]('destroy');\n            this._super();\n        },\n\n        /**\n         * Method is kept for backward compatibility and unit-tests acceptance\n         * see \\mage\\calendar\\calendar-test.js\n         * @return {Object} date\n         */\n        getTimezoneDate: function () {\n            return datepickerPrototype._getTimezoneDate.call(this, this.options);\n        }\n    });\n\n    calendarBasePrototype = $.mage.calendar.prototype;\n\n    /**\n     * Extension for Calendar - date and time format convert functionality\n     * @var {Object}\n     */\n    $.widget('mage.calendar', $.extend({}, calendarBasePrototype,\n            /** @lends {$.mage.calendar.prototype} */ {\n                /**\n                 * key - backend format, value - jquery format\n                 * @type {Object}\n                 * @private\n                 */\n                dateTimeFormat: {\n                    date: {\n                        'EEEE': 'DD',\n                        'EEE': 'D',\n                        'EE': 'D',\n                        'E': 'D',\n                        'D': 'o',\n                        'MMMM': 'MM',\n                        'MMM': 'M',\n                        'MM': 'mm',\n                        'M': 'mm',\n                        'yyyy': 'yy',\n                        'y': 'yy',\n                        'Y': 'yy',\n                        'yy': 'yy' // Always long year format on frontend\n                    },\n                    time: {\n                        'a': 'TT'\n                    }\n                },\n\n                /**\n                 * Add Date and Time converting to _create method\n                 * @protected\n                 */\n                _create: function () {\n                    if (this.options.dateFormat) {\n                        this.options.dateFormat = this._convertFormat(this.options.dateFormat, 'date');\n                    }\n\n                    if (this.options.timeFormat) {\n                        this.options.timeFormat = this._convertFormat(this.options.timeFormat, 'time');\n                    }\n                    calendarBasePrototype._create.apply(this, arguments);\n                },\n\n                /**\n                 * Converting date or time format\n                 * @protected\n                 * @param {String} format\n                 * @param {String} type\n                 * @return {String}\n                 */\n                _convertFormat: function (format, type) {\n                    var symbols = format.match(/([a-z]+)/ig),\n                        separators = format.match(/([^a-z]+)/ig),\n                        self = this,\n                        convertedFormat = '';\n\n                    if (symbols) {\n                        $.each(symbols, function (key, val) {\n                            convertedFormat +=\n                                (self.dateTimeFormat[type][val] || val) +\n                                (separators[key] || '');\n                        });\n                    }\n\n                    return convertedFormat;\n                }\n            })\n    );\n\n    /**\n     * Widget dateRange\n     * @extends $.mage.calendar\n     */\n    $.widget('mage.dateRange', $.mage.calendar, {\n\n        /**\n         * creates two instances of datetimepicker for date range selection\n         * @protected\n         */\n        _initPicker: function () {\n            var from,\n                to;\n\n            if (this.options.from && this.options.to) {\n                from = this.element.find('#' + this.options.from.id);\n                to = this.element.find('#' + this.options.to.id);\n                this.options.onSelect = $.proxy(function (selectedDate) {\n                    to[this._picker()]('option', 'minDate', selectedDate);\n                }, this);\n                $.mage.calendar.prototype._initPicker.call(this, from);\n                from.on('change', $.proxy(function () {\n                    to[this._picker()]('option', 'minDate', from[this._picker()]('getDate'));\n                }, this));\n                this.options.onSelect = $.proxy(function (selectedDate) {\n                    from[this._picker()]('option', 'maxDate', selectedDate);\n                }, this);\n                $.mage.calendar.prototype._initPicker.call(this, to);\n                to.on('change', $.proxy(function () {\n                    from[this._picker()]('option', 'maxDate', to[this._picker()]('getDate'));\n                }, this));\n            }\n        },\n\n        /**\n         * destroy two instances of datetimepicker\n         */\n        _destroy: function () {\n            if (this.options.from) {\n                this.element.find('#' + this.options.from.id)[this._picker()]('destroy');\n            }\n\n            if (this.options.to) {\n                this.element.find('#' + this.options.to.id)[this._picker()]('destroy');\n            }\n            this._super();\n        }\n    });\n\n    // Overrides the \"today\" button functionality to select today's date when clicked.\n    $.datepicker._gotoTodayOriginal = $.datepicker._gotoToday;\n\n    /**\n     * overwrite jQuery UI _showDatepicker function for proper HTML generation conditions.\n     *\n     */\n    $.datepicker._showDatepickerOriginal = $.datepicker._showDatepicker;\n\n    /**\n     * Triggers original method showDataPicker for rendering calendar\n     * @param {HTMLObject} input\n     * @private\n     */\n    $.datepicker._showDatepicker = function (input) {\n        if (!input.disabled) {\n            $.datepicker._showDatepickerOriginal.call(this, input);\n        }\n    };\n\n    /**\n     * _gotoToday\n     * @param {Object} el\n     */\n    $.datepicker._gotoToday = function (el) {\n        //Set date/time according to timezone offset\n        $(el).datepicker('setTimezoneDate')\n            // To ensure that user can re-select date field without clicking outside it first.\n            .trigger('blur').trigger('change');\n    };\n\n    return {\n        dateRange:  $.mage.dateRange,\n        calendar:   $.mage.calendar\n    };\n});\n","mage/fieldset-controls.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated since version 2.2.0\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    /**\n     * This widget will allow a control with the fieldsetResetControl widget attached to reset a set of input fields.\n     * The input fields to reset are defined by the inputSelector selector. The widget will store a clone of the fields\n     * on create, and on trigger of fieldsetReset event it resets the defined fields. The event is triggered by the\n     * reset control widget.\n     *\n     * For inputs of type file, the whole dom element is replaced as changing the value is a security violation\n     * For inputs of type checkbox or radio, the checked attribute is added or removed as appropriate\n     * For all others the jquery .val method is used to update to value to the original.\n     */\n    $.widget('mage.fieldsetControls', {\n        original: undefined,\n        options: {\n            inputSelector: '[data-reset=\"true\"]'\n        },\n\n        /**\n         * @private\n         */\n        _create: function () {\n            this.original = this.element.find(this.options.inputSelector).clone(true);\n            this._bind();\n        },\n\n        /**\n         * @private\n         */\n        _bind: function () {\n            this._on({\n                'fieldsetReset': '_onReset'\n            });\n        },\n\n        /**\n         * @param {jQuery.Event} e\n         * @private\n         */\n        _onReset: function (e) {\n            var items;\n\n            e.stopPropagation();\n            // find all the ones we have to remove\n            items = this.element.find(this.options.inputSelector);\n            // loop over replacing each one.\n            items.each($.proxy(function (index, item) {\n                if ($(item).attr('type') == 'file') { //eslint-disable-line eqeqeq\n                    // Replace the current one we found with a clone of the original saved earlier\n                    $(item).replaceWith($(this.original[index]).clone(true));\n                } else if ($(item).attr('type') == 'checkbox' || $(item).attr('type') == 'radio') { //eslint-disable-line\n                    // Return to original state.\n                    if ($(this.original[index]).attr('checked') === undefined) {\n                        $(item).removeAttr('checked');\n                    } else {\n                        $(item).attr('checked', $(this.original[index]).attr('checked'));\n                    }\n                } else {\n                    // Replace the value with the original\n                    $(item).val($(this.original[index]).val());\n                }\n            }, this));\n        }\n    });\n\n    $.widget('mage.fieldsetResetControl', {\n        /**\n         * @private\n         */\n        _create: function () {\n            this._bind();\n        },\n\n        /**\n         * @private\n         */\n        _bind: function () {\n            this._on({\n                click: '_onClick'\n            });\n        },\n\n        /**\n         * @param {jQuery.Event} e\n         * @private\n         */\n        _onClick: function (e) {\n            e.stopPropagation();\n            $(this.element).trigger('fieldsetReset');\n        }\n    });\n\n    return {\n        fieldsetControls: $.mage.fieldsetControls,\n        fieldsetResetControl: $.mage.fieldsetResetControl\n    };\n});\n","mage/storage.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['jquery', 'mage/url'], function ($, urlBuilder) {\n    'use strict';\n\n    return {\n        /**\n         * Perform asynchronous GET request to server.\n         * @param {String} url\n         * @param {Boolean} global\n         * @param {String} contentType\n         * @param {Object} headers\n         * @returns {Deferred}\n         */\n        get: function (url, global, contentType, headers) {\n            headers = headers || {};\n            global = global === undefined ? true : global;\n            contentType = contentType || 'application/json';\n\n            return $.ajax({\n                url: urlBuilder.build(url),\n                type: 'GET',\n                global: global,\n                contentType: contentType,\n                headers: headers\n            });\n        },\n\n        /**\n         * Perform asynchronous POST request to server.\n         * @param {String} url\n         * @param {String} data\n         * @param {Boolean} global\n         * @param {String} contentType\n         * @param {Object} headers\n         * @returns {Deferred}\n         */\n        post: function (url, data, global, contentType, headers) {\n            headers = headers || {};\n            global = global === undefined ? true : global;\n            contentType = contentType || 'application/json';\n\n            return $.ajax({\n                url: urlBuilder.build(url),\n                type: 'POST',\n                data: data,\n                global: global,\n                contentType: contentType,\n                headers: headers\n            });\n        },\n\n        /**\n         * Perform asynchronous PUT request to server.\n         * @param {String} url\n         * @param {String} data\n         * @param {Boolean} global\n         * @param {String} contentType\n         * @param {Object} headers\n         * @returns {Deferred}\n         */\n        put: function (url, data, global, contentType, headers) {\n            var ajaxSettings = {};\n\n            headers = headers || {};\n            global = global === undefined ? true : global;\n            contentType = contentType || 'application/json';\n            ajaxSettings.url = urlBuilder.build(url);\n            ajaxSettings.type = 'PUT';\n            ajaxSettings.data = data;\n            ajaxSettings.global = global;\n            ajaxSettings.contentType = contentType;\n            ajaxSettings.headers = headers;\n\n            return $.ajax(ajaxSettings);\n        },\n\n        /**\n         * Perform asynchronous DELETE request to server.\n         * @param {String} url\n         * @param {Boolean} global\n         * @param {String} contentType\n         * @param {Object} headers\n         * @returns {Deferred}\n         */\n        delete: function (url, global, contentType, headers) {\n            headers = headers || {};\n            global = global === undefined ? true : global;\n            contentType = contentType || 'application/json';\n\n            return $.ajax({\n                url: urlBuilder.build(url),\n                type: 'DELETE',\n                global: global,\n                contentType: contentType,\n                headers: headers\n            });\n        }\n    };\n});\n","mage/item-table.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated since version 2.2.0\n */\ndefine([\n    'jquery',\n    'mage/template',\n    'jquery-ui-modules/widget'\n], function ($, mageTemplate) {\n    'use strict';\n\n    $.widget('mage.itemTable', {\n        options: {\n            addBlock: '[data-template=\"add-block\"]',\n            addBlockData: {},\n            addEvent: 'click',\n            addSelector: '[data-role=\"add\"]',\n            itemsSelector: '[data-container=\"items\"]',\n            keepLastRow: true\n        },\n\n        /**\n         * This method adds a new instance of the block to the items.\n         * @private\n         */\n        _add: function () {\n            var hideShowDelete,\n                deletableItems,\n                addedBlock;\n\n            // adding a new row, so increment the count to give each row a unique index\n            this.rowIndex++;\n\n            // make sure the block data has the rowIndex\n            this.options.addBlockData.rowIndex = this.rowIndex;\n\n            // render the form\n            addedBlock = $(this.addBlockTmpl({\n                data: this.options.addBlockData\n            }));\n\n            // add the row to the item block\n            this.element.find(this.options.itemsSelector).append(addedBlock);\n\n            // initialize all mage content\n            addedBlock.trigger('contentUpdated');\n\n            // determine all existing items in the collection\n            deletableItems = this._getDeletableItems();\n\n            // for the most part, show the delete mechanism, except in the case where there is only one it should not\n            // be deleted\n            hideShowDelete = 'showDelete';\n\n            if (this.options.keepLastRow && deletableItems.length === 1) {\n                hideShowDelete = 'hideDelete';\n            }\n\n            // loop through each control and perform that action on the deletable item\n            $.each(deletableItems, function (index) {\n                $(deletableItems[index]).trigger(hideShowDelete);\n            });\n        },\n\n        /**\n         * This method binds elements found in this widget.\n         * @private\n         */\n        _bind: function () {\n            var handlers = {};\n\n            // since the first handler is dynamic, generate the object using array notation\n            handlers[this.options.addEvent + ' ' + this.options.addSelector] = '_add';\n            handlers.deleteItem = '_onDeleteItem';\n\n            this._on(handlers);\n        },\n\n        /**\n         * This method constructs a new widget.\n         * @private\n         */\n        _create: function () {\n            this._bind();\n\n            this.addBlockTmpl = mageTemplate(this.options.addBlock);\n\n            // nothing in the table, so indicate that\n            this.rowIndex = -1;\n\n            // make sure the block data is an object\n            if (this.options.addBlockData == null || typeof this.options.addBlockData !== 'object') {\n                // reset the block data to an empty object\n                this.options.addBlockData = {};\n            }\n\n            // add the first row to the table\n            this._add();\n        },\n\n        /**\n         * This method returns the list of widgets associated with deletable items from the container (direct children\n         * only).\n         * @private\n         */\n        _getDeletableItems: function () {\n            return this.element.find(this.options.itemsSelector + '> .deletableItem');\n        },\n\n        /**\n         * This method removes the item associated with the message.\n         * @private\n         */\n        _onDeleteItem: function (e) {\n            var deletableItems;\n\n            // parent elements don't need to see this event\n            e.stopPropagation();\n\n            // remove the deletable item\n            $(e.target).remove();\n\n            if (this.options.keepLastRow) {\n                // determine if there is only one element remaining, in which case, disable the delete mechanism on it\n                deletableItems = this._getDeletableItems();\n\n                if (deletableItems.length === 1) {\n                    $(deletableItems[0]).trigger('hideDelete');\n                }\n            }\n        }\n    });\n\n    return $.mage.itemTable;\n});\n","mage/accordion.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/tabs'\n], function ($, tabs) {\n    'use strict';\n\n    $.widget('mage.accordion', tabs, {\n        options: {\n            active: [0],\n            multipleCollapsible: false,\n            openOnFocus: false\n        },\n\n        /**\n         * @private\n         */\n        _callCollapsible: function () {\n            var self = this,\n                disabled = false,\n                active = false;\n\n            if (typeof this.options.active === 'string') {\n                this.options.active = this.options.active.split(' ').map(function (item) {\n                    return parseInt(item, 10);\n                });\n            }\n\n            $.each(this.collapsibles, function (i) {\n                disabled = active = false;\n\n                if ($.inArray(i, self.options.disabled) !== -1) {\n                    disabled = true;\n                }\n\n                if ($.inArray(i, self.options.active) !== -1) {\n                    active = true;\n                }\n                self._instantiateCollapsible(this, i, active, disabled);\n            });\n        },\n\n        /**\n         * Overwrites default functionality to provide the option to activate/deactivate multiple sections simultaneous\n         * @param {*} action\n         * @param {*} index\n         * @private\n         */\n        _toggleActivate: function (action, index) {\n            var self = this;\n\n            if (Array.isArray(index && this.options.multipleCollapsible)) {\n                $.each(index, function () {\n                    self.collapsibles.eq(this).collapsible(action);\n                });\n            } else if (index === undefined && this.options.multipleCollapsible) {\n                this.collapsibles.collapsible(action);\n            } else {\n                this._super(action, index);\n            }\n        },\n\n        /**\n         * If the Accordion allows multiple section to be active at the same time, if deep linking is used\n         * sections that don't contain the id from anchor shouldn't be closed, otherwise the accordion uses the\n         * tabs behavior\n         * @private\n         */\n        _handleDeepLinking: function () {\n            if (!this.options.multipleCollapsible) {\n                this._super();\n            }\n        },\n\n        /**\n         * Prevent default behavior that closes the other sections when one gets activated if the Accordion allows\n         * multiple sections simultaneous\n         * @private\n         */\n        _closeOthers: function () {\n            var self = this;\n\n            if (!this.options.multipleCollapsible) {\n                $.each(this.collapsibles, function () {\n                    $(this).on('beforeOpen', function () {\n                        self.collapsibles.not(this).collapsible('deactivate');\n                    });\n                });\n            }\n            $.each(this.collapsibles, function () {\n                $(this).on('beforeOpen', function () {\n                    var section = $(this);\n\n                    section.addClass('allow').prevAll().addClass('allow');\n                    section.nextAll().removeClass('allow');\n                });\n            });\n        }\n    });\n\n    return $.mage.accordion;\n});\n","mage/collapsible.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'jquery-ui-modules/core',\n    'jquery/jquery-storageapi',\n    'mage/mage'\n], function ($) {\n    'use strict';\n\n    var hideProps = {},\n        showProps = {};\n\n    hideProps.height = 'hide';\n    showProps.height = 'show';\n\n    $.widget('mage.collapsible', {\n        options: {\n            active: false,\n            disabled: false,\n            collapsible: true,\n            header: '[data-role=title]',\n            content: '[data-role=content]',\n            trigger: '[data-role=trigger]',\n            closedState: null,\n            openedState: null,\n            disabledState: null,\n            ajaxUrlElement: '[data-ajax=true]',\n            ajaxContent: false,\n            loadingClass: null,\n            saveState: false,\n            animate: false,\n            icons: {\n                activeHeader: null,\n                header: null\n            },\n            collateral: {\n                element: null,\n                openedState: null\n            }\n        },\n\n        /**\n         * @private\n         */\n        _create: function () {\n            this.storage = $.localStorage;\n            this.icons = false;\n\n            if (typeof this.options.icons === 'string') {\n                this.options.icons = JSON.parse(this.options.icons);\n            }\n\n            this._processPanels();\n            this._processState();\n            this._refresh();\n\n            if (this.options.icons.header && this.options.icons.activeHeader) {\n                this._createIcons();\n                this.icons = true;\n            }\n\n            this.element.on('dimensionsChanged', function (e) {\n                if (e.target && e.target.classList.contains('active')) {\n                    this._scrollToTopIfNotVisible();\n                }\n            }.bind(this));\n\n            this._bind('click');\n            this._trigger('created');\n        },\n\n        /**\n         * @private\n         */\n        _refresh: function () {\n            this.trigger.attr('tabIndex', 0);\n\n            if (this.options.active && !this.options.disabled) {\n                if (this.options.openedState) {\n                    this.element.addClass(this.options.openedState);\n                }\n\n                if (this.options.collateral.element && this.options.collateral.openedState) {\n                    $(this.options.collateral.element).addClass(this.options.collateral.openedState);\n                }\n\n                if (this.options.ajaxContent) {\n                    this._loadContent();\n                }\n                // ARIA (updates aria attributes)\n                this.header.attr({\n                    'aria-selected': false\n                });\n            } else if (this.options.disabled) {\n                this.disable();\n            } else {\n                this.content.hide();\n\n                if (this.options.closedState) {\n                    this.element.addClass(this.options.closedState);\n                }\n            }\n        },\n\n        /**\n         * Processing the state:\n         *     If deep linking is used and the anchor is the id of the content or the content contains this id,\n         *     and the collapsible element is a nested one having collapsible parents, in order to see the content,\n         *     all the parents must be expanded.\n         * @private\n         */\n        _processState: function () {\n            var anchor = window.location.hash,\n                isValid = $.mage.isValidSelector(anchor),\n                urlPath = window.location.pathname.replace(/\\./g, ''),\n                state;\n\n            this.stateKey = encodeURIComponent(urlPath + this.element.attr('id'));\n\n            if (isValid &&\n                ($(this.content.find(anchor)).length > 0 || this.content.attr('id') === anchor.replace('#', ''))\n            ) {\n                this.element.parents('[data-collapsible=true]').collapsible('forceActivate');\n\n                if (!this.options.disabled) {\n                    this.options.active = true;\n\n                    if (this.options.saveState) { //eslint-disable-line max-depth\n                        this.storage.set(this.stateKey, true);\n                    }\n                }\n            } else if (this.options.saveState && !this.options.disabled) {\n                state = this.storage.get(this.stateKey);\n\n                if (typeof state === 'undefined' || state === null) {\n                    this.storage.set(this.stateKey, this.options.active);\n                } else if (state === true) {\n                    this.options.active = true;\n                } else if (state === false) {\n                    this.options.active = false;\n                }\n            }\n        },\n\n        /**\n         * @private\n         */\n        _createIcons: function () {\n            var icons = this.options.icons;\n\n            if (icons) {\n                $('<span>')\n                    .addClass(icons.header)\n                    .attr('data-role', 'icons')\n                    .prependTo(this.header);\n\n                if (this.options.active && !this.options.disabled) {\n                    this.header.children('[data-role=icons]')\n                        .removeClass(icons.header)\n                        .addClass(icons.activeHeader);\n                }\n            }\n        },\n\n        /**\n         * @private\n         */\n        _destroyIcons: function () {\n            this.header\n                .children('[data-role=icons]')\n                .remove();\n        },\n\n        /**\n         * @private\n         */\n        _destroy: function () {\n            var options = this.options;\n\n            this.element.removeAttr('data-collapsible');\n\n            this.trigger.removeAttr('tabIndex');\n\n            if (options.openedState) {\n                this.element.removeClass(options.openedState);\n            }\n\n            if (this.options.collateral.element && this.options.collateral.openedState) {\n                $(this.options.collateral.element).removeClass(this.options.collateral.openedState);\n            }\n\n            if (options.closedState) {\n                this.element.removeClass(options.closedState);\n            }\n\n            if (options.disabledState) {\n                this.element.removeClass(options.disabledState);\n            }\n\n            if (this.icons) {\n                this._destroyIcons();\n            }\n        },\n\n        /**\n         * @private\n         */\n        _processPanels: function () {\n            var headers, triggers;\n\n            this.element.attr('data-collapsible', 'true');\n\n            if (typeof this.options.header === 'object') {\n                this.header = this.options.header;\n            } else {\n                headers = this.element.find(this.options.header);\n\n                if (headers.length > 0) {\n                    this.header = headers.eq(0);\n                } else {\n                    this.header = this.element;\n                }\n            }\n\n            if (typeof this.options.content === 'object') {\n                this.content = this.options.content;\n            } else {\n                this.content = this.header.next(this.options.content).eq(0);\n            }\n\n            // ARIA (init aria attributes)\n            if (this.header.attr('id')) {\n                this.content.attr('aria-labelledby', this.header.attr('id'));\n            }\n\n            if (this.content.attr('id')) {\n                this.header.attr('aria-controls', this.content.attr('id'));\n            }\n\n            this.header\n                .attr({\n                    'role': 'tab',\n                    'aria-selected': this.options.active,\n                    'aria-expanded': this.options.active\n                });\n\n            // For collapsible widget only (not tabs or accordion)\n            if (this.header.parent().attr('role') !== 'presentation') {\n                this.header\n                    .parent()\n                    .attr('role', 'tablist');\n            }\n\n            this.content.attr({\n                'role': 'tabpanel',\n                'aria-hidden': !this.options.active\n            });\n\n            if (typeof this.options.trigger === 'object') {\n                this.trigger = this.options.trigger;\n            } else {\n                triggers = this.header.find(this.options.trigger);\n\n                if (triggers.length > 0) {\n                    this.trigger = triggers.eq(0);\n                } else {\n                    this.trigger = this.header;\n                }\n            }\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _keydown: function (event) {\n            var keyCode;\n\n            if (event.altKey || event.ctrlKey) {\n                return;\n            }\n\n            keyCode = $.ui.keyCode;\n\n            switch (event.keyCode) {\n                case keyCode.SPACE:\n                case keyCode.ENTER:\n                    this._eventHandler(event);\n                    break;\n            }\n\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _bind: function (event) {\n            var self = this;\n\n            this.events = {\n                keydown: '_keydown'\n            };\n\n            if (event) {\n                $.each(event.split(' '), function (index, eventName) {\n                    self.events[eventName] = '_eventHandler';\n                });\n            }\n            this._off(this.trigger);\n\n            if (!this.options.disabled) {\n                this._on(this.trigger, this.events);\n            }\n        },\n\n        /**\n         * Disable.\n         */\n        disable: function () {\n            this.options.disabled = true;\n            this._off(this.trigger);\n            this.forceDeactivate();\n\n            if (this.options.disabledState) {\n                this.element.addClass(this.options.disabledState);\n            }\n            this.trigger.attr('tabIndex', -1);\n        },\n\n        /**\n         * Enable.\n         */\n        enable: function () {\n            this.options.disabled = false;\n            this._on(this.trigger, this.events);\n            this.forceActivate();\n\n            if (this.options.disabledState) {\n                this.element.removeClass(this.options.disabledState);\n            }\n            this.trigger.attr('tabIndex', 0);\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _eventHandler: function (event) {\n\n            if (this.options.active && this.options.collapsible) {\n                this.deactivate();\n            } else {\n                this.activate();\n\n            }\n            event.preventDefault();\n\n        },\n\n        /**\n         * @param {*} prop\n         * @private\n         */\n        _animate: function (prop) {\n            var duration,\n                easing,\n                animate = this.options.animate;\n\n            if (typeof animate === 'number') {\n                duration = animate;\n            }\n\n            if (typeof animate === 'string') {\n                animate = JSON.parse(animate);\n            }\n            duration = duration || animate.duration;\n            easing = animate.easing;\n            this.content.animate(prop, duration, easing);\n        },\n\n        /**\n         * Deactivate.\n         */\n        deactivate: function () {\n            if (this.options.animate) {\n                this._animate(hideProps);\n            } else {\n                this.content.hide();\n            }\n            this._close();\n        },\n\n        /**\n         * Force deactivate.\n         */\n        forceDeactivate: function () {\n            this.content.hide();\n            this._close();\n\n        },\n\n        /**\n         * @private\n         */\n        _close: function () {\n            this.options.active = false;\n\n            if (this.options.saveState) {\n                this.storage.set(this.stateKey, false);\n            }\n\n            if (this.options.openedState) {\n                this.element.removeClass(this.options.openedState);\n            }\n\n            if (this.options.collateral.element && this.options.collateral.openedState) {\n                $(this.options.collateral.element).removeClass(this.options.collateral.openedState);\n            }\n\n            if (this.options.closedState) {\n                this.element.addClass(this.options.closedState);\n            }\n\n            if (this.icons) {\n                this.header.children('[data-role=icons]')\n                    .removeClass(this.options.icons.activeHeader)\n                    .addClass(this.options.icons.header);\n            }\n\n            // ARIA (updates aria attributes)\n            this.header.attr({\n                'aria-selected': 'false',\n                'aria-expanded': 'false'\n            });\n            this.content.attr({\n                'aria-hidden': 'true'\n            });\n\n            this.element.trigger('dimensionsChanged', {\n                opened: false\n            });\n        },\n\n        /**\n         * Activate.\n         *\n         * @return void;\n         */\n        activate: function () {\n            if (this.options.disabled) {\n                return;\n            }\n\n            if (this.options.animate) {\n                this._animate(showProps);\n            } else {\n                this.content.show();\n            }\n            this._open();\n        },\n\n        /**\n         * Force activate.\n         */\n        forceActivate: function () {\n            if (!this.options.disabled) {\n                this.content.show();\n                this._open();\n            }\n        },\n\n        /**\n         * @private\n         */\n        _open: function () {\n            this.element.trigger('beforeOpen');\n            this.options.active = true;\n\n            if (this.options.ajaxContent) {\n                this._loadContent();\n            }\n\n            if (this.options.saveState) {\n                this.storage.set(this.stateKey, true);\n            }\n\n            if (this.options.openedState) {\n                this.element.addClass(this.options.openedState);\n            }\n\n            if (this.options.collateral.element && this.options.collateral.openedState) {\n                $(this.options.collateral.element).addClass(this.options.collateral.openedState);\n            }\n\n            if (this.options.closedState) {\n                this.element.removeClass(this.options.closedState);\n            }\n\n            if (this.icons) {\n                this.header.children('[data-role=icons]')\n                    .removeClass(this.options.icons.header)\n                    .addClass(this.options.icons.activeHeader);\n            }\n\n            // ARIA (updates aria attributes)\n            this.header.attr({\n                'aria-selected': 'true',\n                'aria-expanded': 'true'\n            });\n            this.content.attr({\n                'aria-hidden': 'false'\n            });\n\n            this.element.trigger('dimensionsChanged', {\n                opened: true\n            });\n        },\n\n        /**\n         * @private\n         */\n        _loadContent: function () {\n            var url = this.element.find(this.options.ajaxUrlElement).attr('href'),\n                that = this;\n\n            if (url) {\n                that.xhr = $.get({\n                    url: url,\n                    dataType: 'html'\n                }, function () {\n                });\n            }\n\n            if (that.xhr && that.xhr.statusText !== 'canceled') {\n                if (that.options.loadingClass) {\n                    that.element.addClass(that.options.loadingClass);\n                }\n                that.content.attr('aria-busy', 'true');\n                that.xhr.done(function (response) {\n                    setTimeout(function () {\n                        that.content.html(response);\n                    }, 1);\n                });\n                that.xhr.always(function (jqXHR, status) {\n                    setTimeout(function () {\n                        if (status === 'abort') {\n                            that.content.stop(false, true);\n                        }\n\n                        if (that.options.loadingClass) {\n                            that.element.removeClass(that.options.loadingClass);\n                        }\n                        that.content.removeAttr('aria-busy');\n\n                        if (jqXHR === that.xhr) {\n                            delete that.xhr;\n                        }\n                    }, 1);\n                });\n            }\n        },\n\n        /**\n         * @private\n         */\n        _scrollToTopIfNotVisible: function () {\n            if (this._isElementOutOfViewport()) {\n                this.header[0].scrollIntoView();\n            }\n        },\n\n        /**\n         * @private\n         * @return {Boolean}\n         */\n        _isElementOutOfViewport: function () {\n            var headerRect = this.header[0].getBoundingClientRect(),\n                contentRect = this.content.get().length ? this.content[0].getBoundingClientRect() : false,\n                headerOut,\n                contentOut;\n\n            headerOut = headerRect.bottom - headerRect.height < 0 ||\n                headerRect.right - headerRect.width < 0 ||\n                headerRect.left + headerRect.width > window.innerWidth ||\n                headerRect.top + headerRect.height > window.innerHeight;\n\n            contentOut = contentRect ? contentRect.bottom - contentRect.height < 0 ||\n                contentRect.right - contentRect.width < 0 ||\n                contentRect.left + contentRect.width > window.innerWidth ||\n                contentRect.top + contentRect.height > window.innerHeight : false;\n\n            return headerOut ? headerOut : contentOut;\n        }\n    });\n\n    return $.mage.collapsible;\n});\n","mage/validation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'moment',\n    'mageUtils',\n    'jquery-ui-modules/widget',\n    'jquery/validate',\n    'mage/translate'\n], function ($, moment, utils) {\n    'use strict';\n\n    var creditCartTypes, rules, showLabel, originValidateDelegate;\n\n    $.extend(true, $, {\n        // @TODO: Move methods 'isEmpty', 'isEmptyNoTrim', 'parseNumber', 'stripHtml' in file with utility functions\n        mage: {\n            /**\n             * Check if string is empty with trim\n             * @param {String} value\n             */\n            isEmpty: function (value) {\n                return value === '' || value === undefined ||\n                    value == null || value.length === 0 || /^\\s+$/.test(value);\n            },\n\n            /**\n             * Check if string is empty no trim\n             * @param {String} value\n             */\n            isEmptyNoTrim: function (value) {\n                return value === '' || value == null || value.length === 0;\n            },\n\n            /**\n             * Checks if {value} is between numbers {from} and {to}\n             * @param {String} value\n             * @param {String} from\n             * @param {String} to\n             * @returns {Boolean}\n             */\n            isBetween: function (value, from, to) {\n                return ($.mage.isEmpty(from) || value >= $.mage.parseNumber(from)) &&\n                    ($.mage.isEmpty(to) || value <= $.mage.parseNumber(to));\n            },\n\n            /**\n             * Parse price string\n             * @param {String} value\n             */\n            parseNumber: function (value) {\n                var isDot, isComa;\n\n                if (typeof value !== 'string') {\n                    return parseFloat(value);\n                }\n                isDot = value.indexOf('.');\n                isComa = value.indexOf(',');\n\n                if (isDot !== -1 && isComa !== -1) {\n                    if (isComa > isDot) {\n                        value = value.replace('.', '').replace(',', '.');\n                    } else {\n                        value = value.replace(',', '');\n                    }\n                } else if (isComa !== -1) {\n                    value = value.replace(',', '.');\n                }\n\n                return parseFloat(value);\n            },\n\n            /**\n             * Removes HTML tags and space characters, numbers and punctuation.\n             *\n             * @param {String} value - Value being stripped.\n             * @return {String}\n             */\n            stripHtml: function (value) {\n                return value.replace(/<.[^<>]*?>/g, ' ').replace(/&nbsp;|&#160;/gi, ' ')\n                    .replace(/[0-9.(),;:!?%#$'\"_+=\\/-]*/g, '');\n            }\n        }\n    });\n\n    /**\n     * @param {String} name\n     * @param {*} method\n     * @param {*} message\n     * @param {*} dontSkip\n     */\n    $.validator.addMethod = function (name, method, message, dontSkip) {\n        $.validator.methods[name] = method;\n        $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];\n\n        if (method.length < 3 || dontSkip) {\n            $.validator.addClassRules(name, $.validator.normalizeRule(name));\n        }\n    };\n\n    /**\n     * Javascript object with credit card types\n     * 0 - regexp for card number\n     * 1 - regexp for cvn\n     * 2 - check or not credit card number trough Luhn algorithm by\n     */\n    creditCartTypes = {\n        'SO': [\n            new RegExp('^(6334[5-9]([0-9]{11}|[0-9]{13,14}))|(6767([0-9]{12}|[0-9]{14,15}))$'),\n            new RegExp('^([0-9]{3}|[0-9]{4})?$'),\n            true\n        ],\n        'SM': [\n            new RegExp('(^(5[0678])[0-9]{11,18}$)|(^(6[^05])[0-9]{11,18}$)|' +\n                '(^(601)[^1][0-9]{9,16}$)|(^(6011)[0-9]{9,11}$)|(^(6011)[0-9]{13,16}$)|' +\n                '(^(65)[0-9]{11,13}$)|(^(65)[0-9]{15,18}$)|(^(49030)[2-9]([0-9]{10}$|[0-9]{12,13}$))|' +\n                '(^(49033)[5-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49110)[1-2]([0-9]{10}$|[0-9]{12,13}$))|' +\n                '(^(49117)[4-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49118)[0-2]([0-9]{10}$|[0-9]{12,13}$))|' +\n                '(^(4936)([0-9]{12}$|[0-9]{14,15}$))'), new RegExp('^([0-9]{3}|[0-9]{4})?$'),\n            true\n        ],\n        'VI': [new RegExp('^4[0-9]{12}([0-9]{3})?$'), new RegExp('^[0-9]{3}$'), true],\n        'MC': [\n            new RegExp('^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$'),\n            new RegExp('^[0-9]{3}$'),\n            true\n        ],\n        'AE': [new RegExp('^3[47][0-9]{13}$'), new RegExp('^[0-9]{4}$'), true],\n        'DI': [new RegExp('^(6011(0|[2-4]|74|7[7-9]|8[6-9]|9)|6(4[4-9]|5))\\\\d*$'), new RegExp('^[0-9]{3}$'), true],\n        'JCB': [new RegExp('^35(2[8-9]|[3-8])\\\\d*$'), new RegExp('^[0-9]{3}$'), true],\n        'DN': [new RegExp('^(3(0[0-5]|095|6|[8-9]))\\\\d*$'), new RegExp('^[0-9]{3}$'), true],\n        'UN': [\n            new RegExp('^(622(1(2[6-9]|[3-9])|[3-8]|9([[0-1]|2[0-5]))|62[4-6]|628([2-8]))\\\\d*?$'),\n            new RegExp('^[0-9]{3}$'),\n            true\n        ],\n        'MI': [new RegExp('^(5(0|[6-9])|63|67(?!59|6770|6774))\\\\d*$'), new RegExp('^[0-9]{3}$'), true],\n        'MD': [new RegExp('^6759(?!24|38|40|6[3-9]|70|76)|676770|676774\\\\d*$'), new RegExp('^[0-9]{3}$'), true]\n    };\n\n    /**\n     * validate credit card number using mod10\n     * @param {String} s\n     * @return {Boolean}\n     */\n    function validateCreditCard(s) {\n        // remove non-numerics\n        var v = '0123456789',\n            w = '',\n            i, j, k, m, c, a, x;\n\n        for (i = 0; i < s.length; i++) {\n            x = s.charAt(i);\n\n            if (v.indexOf(x, 0) !== -1) {\n                w += x;\n            }\n        }\n        // validate number\n        j = w.length / 2;\n        k = Math.floor(j);\n        m = Math.ceil(j) - k;\n        c = 0;\n\n        for (i = 0; i < k; i++) {\n            a = w.charAt(i * 2 + m) * 2;\n            c += a > 9 ? Math.floor(a / 10 + a % 10) : a;\n        }\n\n        for (i = 0; i < k + m; i++) {\n            c += w.charAt(i * 2 + 1 - m) * 1;\n        }\n\n        return c % 10 === 0;\n    }\n\n    /**\n     * validate all table required inputs at once, using single hidden input\n     * @param {String} value\n     * @param {HTMLElement} element\n     *\n     * @return {Boolean}\n     */\n    function tableSingleValidation(value, element) {\n        var empty = $(element).closest('table')\n            .find('input.required-option:visible')\n            .filter(function (i, el) {\n                if ($(el).is('disabled')) {\n                    return $.mage.isEmpty(el.value);\n                }\n            })\n            .length;\n\n        return empty === 0;\n    }\n\n    /**\n     *\n     * @param {float} qty\n     * @param {float} qtyIncrements\n     * @returns {float}\n     */\n    function resolveModulo(qty, qtyIncrements) {\n        var divideEpsilon = 10000,\n            epsilon,\n            remainder;\n\n        while (qtyIncrements < 1) {\n            qty *= 10;\n            qtyIncrements *= 10;\n        }\n\n        epsilon = qtyIncrements / divideEpsilon;\n        remainder = qty % qtyIncrements;\n\n        if (Math.abs(remainder - qtyIncrements) < epsilon ||\n            Math.abs(remainder) < epsilon) {\n            remainder = 0;\n        }\n\n        return remainder;\n    }\n\n    /**\n     * Collection of validation rules including rules from additional-methods.js\n     * @type {Object}\n     */\n    rules = {\n        'max-words': [\n            function (value, element, params) {\n                return this.optional(element) || $.mage.stripHtml(value).match(/\\b\\w+\\b/g).length <= params;\n            },\n            $.mage.__('Please enter {0} words or less.')\n        ],\n        'min-words': [\n            function (value, element, params) {\n                return this.optional(element) || $.mage.stripHtml(value).match(/\\b\\w+\\b/g).length >= params;\n            },\n            $.mage.__('Please enter at least {0} words.')\n        ],\n        'range-words': [\n            function (value, element, params) {\n                return this.optional(element) ||\n                    $.mage.stripHtml(value).match(/\\b\\w+\\b/g).length >= params[0] &&\n                    value.match(/bw+b/g).length < params[1];\n            },\n            $.mage.__('Please enter between {0} and {1} words.')\n        ],\n        'letters-with-basic-punc': [\n            function (value, element) {\n                return this.optional(element) || /^[a-z\\-.,()'\\\"\\s]+$/i.test(value);\n            },\n            $.mage.__('Letters or punctuation only please')\n        ],\n        'alphanumeric': [\n            function (value, element) {\n                return this.optional(element) || /^\\w+$/i.test(value);\n            },\n            $.mage.__('Letters, numbers, spaces or underscores only please')\n        ],\n        'letters-only': [\n            function (value, element) {\n                return this.optional(element) || /^[a-z]+$/i.test(value);\n            },\n            $.mage.__('Letters only please')\n        ],\n        'no-whitespace': [\n            function (value, element) {\n                return this.optional(element) || /^\\S+$/i.test(value);\n            },\n            $.mage.__('No white space please')\n        ],\n        'no-marginal-whitespace': [\n            function (value, element) {\n                return this.optional(element) || !/^\\s+|\\s+$/i.test(value);\n            },\n            $.mage.__('No marginal white space please')\n        ],\n        'zip-range': [\n            function (value, element) {\n                return this.optional(element) || /^90[2-5]-\\d{2}-\\d{4}$/.test(value);\n            },\n            $.mage.__('Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx')\n        ],\n        'integer': [\n            function (value, element) {\n                return this.optional(element) || /^-?\\d+$/.test(value);\n            },\n            $.mage.__('A positive or negative non-decimal number please')\n        ],\n        'vinUS': [\n            function (v) {\n                var i, n, d, f, cd, cdv, LL, VL, FL, rs;\n\n                /* eslint-disable max-depth */\n                if (v.length !== 17) {\n                    return false;\n                }\n\n                LL = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L',\n                    'M', 'N', 'P', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];\n                VL = [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9];\n                FL = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];\n                rs = 0;\n\n                for (i = 0; i < 17; i++) {\n                    f = FL[i];\n                    d = v.slice(i, i + 1);\n\n                    if (i === 8) {\n                        cdv = d;\n                    }\n\n                    if (!isNaN(d)) {\n                        d *= f;\n                    } else {\n                        for (n = 0; n < LL.length; n++) {\n                            if (d.toUpperCase() === LL[n]) {\n                                d = VL[n];\n                                d *= f;\n\n                                if (isNaN(cdv) && n === 8) {\n                                    cdv = LL[n];\n                                }\n                                break;\n                            }\n                        }\n                    }\n                    rs += d;\n                }\n\n                /* eslint-enable max-depth */\n                cd = rs % 11;\n\n                if (cd === 10) {\n                    cd = 'X';\n                }\n\n                if (cd === cdv) {\n                    return true;\n                }\n\n                return false;\n            },\n            $.mage.__('The specified vehicle identification number (VIN) is invalid.')\n        ],\n        'dateITA': [\n            function (value, element) {\n                var check = false,\n                    re = /^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$/,\n                    adata, gg, mm, aaaa, xdata;\n\n                if (re.test(value)) {\n                    adata = value.split('/');\n                    gg = parseInt(adata[0], 10);\n                    mm = parseInt(adata[1], 10);\n                    aaaa = parseInt(adata[2], 10);\n                    xdata = new Date(aaaa, mm - 1, gg);\n\n                    if (xdata.getFullYear() === aaaa &&\n                        xdata.getMonth() === mm - 1 &&\n                        xdata.getDate() === gg\n                    ) {\n                        check = true;\n                    } else {\n                        check = false;\n                    }\n                } else {\n                    check = false;\n                }\n\n                return this.optional(element) || check;\n            },\n            $.mage.__('Please enter a correct date')\n        ],\n        'dateNL': [\n            function (value, element) {\n                return this.optional(element) || /^\\d\\d?[\\.\\/-]\\d\\d?[\\.\\/-]\\d\\d\\d?\\d?$/.test(value);\n            },\n            'Vul hier een geldige datum in.'\n        ],\n        'time': [\n            function (value, element) {\n                return this.optional(element) || /^([01]\\d|2[0-3])(:[0-5]\\d){0,2}$/.test(value);\n            },\n            $.mage.__('Please enter a valid time, between 00:00 and 23:59')\n        ],\n        'time12h': [\n            function (value, element) {\n                return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\\d){0,2}(\\s[AP]M))$/i.test(value);\n            },\n            $.mage.__('Please enter a valid time, between 00:00 am and 12:00 pm')\n        ],\n        'phoneUS': [\n            function (phoneNumber, element) {\n                phoneNumber = phoneNumber.replace(/\\s+/g, '');\n\n                return this.optional(element) || phoneNumber.length > 9 &&\n                    phoneNumber.match(/^(1-?)?(\\([2-9]\\d{2}\\)|[2-9]\\d{2})-?[2-9]\\d{2}-?\\d{4}$/);\n            },\n            $.mage.__('Please specify a valid phone number')\n        ],\n        'phoneUK': [\n            function (phoneNumber, element) {\n                return this.optional(element) || phoneNumber.length > 9 &&\n                    phoneNumber.match(/^(\\(?(0|\\+44)[1-9]{1}\\d{1,4}?\\)?\\s?\\d{3,4}\\s?\\d{3,4})$/);\n            },\n            $.mage.__('Please specify a valid phone number')\n        ],\n        'mobileUK': [\n            function (phoneNumber, element) {\n                return this.optional(element) || phoneNumber.length > 9 &&\n                    phoneNumber.match(/^((0|\\+44)7\\d{3}\\s?\\d{6})$/);\n            },\n            $.mage.__('Please specify a valid mobile number')\n        ],\n        'stripped-min-length': [\n            function (value, element, param) {\n                return value.length >= param;\n            },\n            $.mage.__('Please enter at least {0} characters')\n        ],\n\n        /* detect chars that would require more than 3 bytes */\n        'validate-no-utf8mb4-characters': [\n            function (value) {\n                var validator = this,\n                    message = $.mage.__('Please remove invalid characters: {0}.'),\n                    matches = value.match(/(?:[\\uD800-\\uDBFF][\\uDC00-\\uDFFF])/g),\n                    result = matches === null;\n\n                if (!result) {\n                    validator.charErrorMessage = message.replace('{0}', matches.join());\n                }\n\n                return result;\n            }, function () {\n                return this.charErrorMessage;\n            }\n        ],\n\n        /* eslint-disable max-len */\n        'email2': [\n            function (value, element) {\n                return this.optional(element) ||\n                    /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$/i.test(value);\n            },\n            $.validator.messages.email\n        ],\n        'url2': [\n            function (value, element) {\n                return this.optional(element) || /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i.test(value);\n            },\n            $.validator.messages.url\n        ],\n\n        /* eslint-enable max-len */\n        'credit-card-types': [\n            function (value, element, param) {\n                var validTypes;\n\n                if (/[^0-9-]+/.test(value)) {\n                    return false;\n                }\n                value = value.replace(/\\D/g, '');\n\n                validTypes = 0x0000;\n\n                if (param.mastercard) {\n                    validTypes |= 0x0001;\n                }\n\n                if (param.visa) {\n                    validTypes |= 0x0002;\n                }\n\n                if (param.amex) {\n                    validTypes |= 0x0004;\n                }\n\n                if (param.dinersclub) {\n                    validTypes |= 0x0008;\n                }\n\n                if (param.enroute) {\n                    validTypes |= 0x0010;\n                }\n\n                if (param.discover) {\n                    validTypes |= 0x0020;\n                }\n\n                if (param.jcb) {\n                    validTypes |= 0x0040;\n                }\n\n                if (param.unknown) {\n                    validTypes |= 0x0080;\n                }\n\n                if (param.all) {\n                    validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;\n                }\n\n                if (validTypes & 0x0001 && /^(51|52|53|54|55)/.test(value)) { //mastercard\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0004 && /^(34|37)/.test(value)) { //amex\n                    return value.length === 15;\n                }\n\n                if (validTypes & 0x0008 && /^(300|301|302|303|304|305|36|38)/.test(value)) { //dinersclub\n                    return value.length === 14;\n                }\n\n                if (validTypes & 0x0010 && /^(2014|2149)/.test(value)) { //enroute\n                    return value.length === 15;\n                }\n\n                if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb\n                    return value.length === 15;\n                }\n\n                if (validTypes & 0x0080) { //unknown\n                    return true;\n                }\n\n                return false;\n            },\n            $.mage.__('Please enter a valid credit card number.')\n        ],\n\n        /* eslint-disable max-len */\n        'ipv4': [\n            function (value, element) {\n                return this.optional(element) ||\n                    /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(value);\n            },\n            $.mage.__('Please enter a valid IP v4 address.')\n        ],\n        'ipv6': [\n            function (value, element) {\n                return this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);\n            },\n            $.mage.__('Please enter a valid IP v6 address.')\n        ],\n\n        /* eslint-enable max-len */\n        'pattern': [\n            function (value, element, param) {\n                return this.optional(element) || new RegExp(param).test(value);\n            },\n            $.mage.__('Invalid format.')\n        ],\n        'allow-container-className': [\n            function (element) {\n                if (element.type === 'radio' || element.type === 'checkbox') {\n                    return $(element).hasClass('change-container-classname');\n                }\n            },\n            ''\n        ],\n        'validate-no-html-tags': [\n            function (value) {\n                return !/<(\\/)?\\w+/.test(value);\n            },\n            $.mage.__('HTML tags are not allowed.')\n        ],\n        'validate-select': [\n            function (value) {\n                return value !== 'none' && value != null && value.length !== 0;\n            },\n            $.mage.__('Please select an option.')\n        ],\n        'validate-no-empty': [\n            function (value) {\n                return !$.mage.isEmpty(value);\n            },\n            $.mage.__('Empty Value.')\n        ],\n        'validate-alphanum-with-spaces': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z0-9 ]+$/.test(v);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.')\n        ],\n        'validate-data': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^[A-Za-z]+[A-Za-z0-9_]+$/.test(v);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.') //eslint-disable-line max-len\n        ],\n        'validate-street': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^[ \\w]{3,}([A-Za-z]\\.)?([ \\w]*\\#\\d+)?(\\r\\n| )[ \\w]{3,}/.test(v);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9), spaces and \"#\" in this field.')\n        ],\n        'validate-phoneStrict': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(v);\n            },\n            $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n        ],\n        'validate-phoneLax': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) ||\n                    /^((\\d[\\-. ]?)?((\\(\\d{3}\\))|\\d{3}))?[\\-. ]?\\d{3}[\\-. ]?\\d{4}$/.test(v);\n            },\n            $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n        ],\n        'validate-fax': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(v);\n            },\n            $.mage.__('Please enter a valid fax number (Ex: 123-456-7890).')\n        ],\n        'validate-email': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*@([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*\\.(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]){2,})$/i.test(v); //eslint-disable-line max-len\n            },\n            $.mage.__('Please enter a valid email address (Ex: johndoe@domain.com).')\n        ],\n        'validate-emailSender': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^[\\S ]+$/.test(v);\n            },\n            $.mage.__('Please enter a valid email address (Ex: johndoe@domain.com).')\n        ],\n        'validate-password': [\n            function (v) {\n                var pass;\n\n                if (v == null) {\n                    return false;\n                }\n                //strip leading and trailing spaces\n                pass = v.trim();\n\n                if (!pass.length) {\n                    return true;\n                }\n\n                return !(pass.length > 0 && pass.length < 6);\n            },\n            $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n        ],\n        'validate-admin-password': [\n            function (v) {\n                var pass;\n\n                if (v == null) {\n                    return false;\n                }\n                pass = v.trim();\n                // strip leading and trailing spaces\n                if (pass.length === 0) {\n                    return true;\n                }\n\n                if (!/[a-z]/i.test(v) || !/[0-9]/.test(v)) {\n                    return false;\n                }\n\n                if (pass.length < 7) {\n                    return false;\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter 7 or more characters, using both numeric and alphabetic.')\n        ],\n        'validate-customer-password': [\n            function (v, elm) {\n                var validator = this,\n                    counter = 0,\n                    passwordMinLength = $(elm).data('password-min-length'),\n                    passwordMinCharacterSets = $(elm).data('password-min-character-sets'),\n                    pass = v.trim(),\n                    result = pass.length >= passwordMinLength;\n\n                if (result === false) {\n                    validator.passwordErrorMessage = $.mage.__('Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.').replace('%1', passwordMinLength); //eslint-disable-line max-len\n\n                    return result;\n                }\n\n                if (pass.match(/\\d+/)) {\n                    counter++;\n                }\n\n                if (pass.match(/[a-z]+/)) {\n                    counter++;\n                }\n\n                if (pass.match(/[A-Z]+/)) {\n                    counter++;\n                }\n\n                if (pass.match(/[^a-zA-Z0-9]+/)) {\n                    counter++;\n                }\n\n                if (counter < passwordMinCharacterSets) {\n                    result = false;\n                    validator.passwordErrorMessage = $.mage.__('Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.').replace('%1', passwordMinCharacterSets); //eslint-disable-line max-len\n                }\n\n                return result;\n            }, function () {\n                return this.passwordErrorMessage;\n            }\n        ],\n        'validate-url': [\n            function (v) {\n                if ($.mage.isEmptyNoTrim(v)) {\n                    return true;\n                }\n                v = (v || '').replace(/^\\s+/, '').replace(/\\s+$/, '');\n\n                return (/^(http|https|ftp):\\/\\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\\d+))?(\\/[A-Z0-9~](([A-Z0-9_~-]|\\.)*[A-Z0-9~]|))*\\/?(.*)?$/i).test(v); //eslint-disable-line max-len\n\n            },\n            $.mage.__('Please enter a valid URL. Protocol is required (http://, https:// or ftp://).')\n        ],\n        'validate-clean-url': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^(http|https|ftp):\\/\\/(([A-Z0-9][A-Z0-9_-]*)(\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(v) || /^(www)((\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(v); //eslint-disable-line max-len\n\n            },\n            $.mage.__('Please enter a valid URL. For example http://www.example.com or www.example.com.')\n        ],\n        'validate-xml-identifier': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^[A-Z][A-Z0-9_\\/-]*$/i.test(v);\n\n            },\n            $.mage.__('Please enter a valid XML-identifier (Ex: something_1, block5, id-4).')\n        ],\n        'validate-ssn': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^\\d{3}-?\\d{2}-?\\d{4}$/.test(v);\n\n            },\n            $.mage.__('Please enter a valid social security number (Ex: 123-45-6789).')\n        ],\n        'validate-zip-us': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /(^\\d{5}$)|(^\\d{5}-\\d{4}$)/.test(v);\n\n            },\n            $.mage.__('Please enter a valid zip code (Ex: 90602 or 90602-1234).')\n        ],\n        'validate-date-au': [\n            function (v) {\n                var regex, d;\n\n                if ($.mage.isEmptyNoTrim(v)) {\n                    return true;\n                }\n                regex = /^(\\d{2})\\/(\\d{2})\\/(\\d{4})$/;\n\n                if ($.mage.isEmpty(v) || !regex.test(v)) {\n                    return false;\n                }\n                d = new Date(v.replace(regex, '$2/$1/$3'));\n\n                return parseInt(RegExp.$2, 10) === 1 + d.getMonth() &&\n                    parseInt(RegExp.$1, 10) === d.getDate() &&\n                    parseInt(RegExp.$3, 10) === d.getFullYear();\n\n            },\n            $.mage.__('Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.')\n        ],\n        'validate-currency-dollar': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^\\$?\\-?([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}\\d*(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$/.test(v); //eslint-disable-line max-len\n\n            },\n            $.mage.__('Please enter a valid $ amount. For example $100.00.')\n        ],\n        'validate-not-negative-number': [\n            function (v) {\n                if ($.mage.isEmptyNoTrim(v)) {\n                    return true;\n                }\n                v = $.mage.parseNumber(v);\n\n                return !isNaN(v) && v >= 0;\n\n            },\n            $.mage.__('Please enter a number 0 or greater in this field.')\n        ],\n        // validate-not-negative-number should be replaced in all places with this one and then removed\n        'validate-zero-or-greater': [\n            function (v) {\n                if ($.mage.isEmptyNoTrim(v)) {\n                    return true;\n                }\n                v = $.mage.parseNumber(v);\n\n                return !isNaN(v) && v >= 0;\n\n            },\n            $.mage.__('Please enter a number 0 or greater in this field.')\n        ],\n        'validate-greater-than-zero': [\n            function (v) {\n                if ($.mage.isEmptyNoTrim(v)) {\n                    return true;\n                }\n                v = $.mage.parseNumber(v);\n\n                return !isNaN(v) && v > 0;\n            },\n            $.mage.__('Please enter a number greater than 0 in this field.')\n        ],\n        'validate-css-length': [\n            function (v) {\n                if (v !== '') {\n                    return (/^[0-9]*\\.*[0-9]+(px|pc|pt|ex|em|mm|cm|in|%)?$/).test(v);\n                }\n\n                return true;\n            },\n            $.mage.__('Please input a valid CSS-length (Ex: 100px, 77pt, 20em, .5ex or 50%).')\n        ],\n        // Additional methods\n        'validate-number': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || !isNaN($.mage.parseNumber(v)) && /^\\s*-?\\d*(\\.\\d*)?\\s*$/.test(v);\n            },\n            $.mage.__('Please enter a valid number in this field.')\n        ],\n        'required-number': [\n            function (v) {\n                return !!v.length;\n            },\n            $.mage.__('Please enter a valid number in this field.')\n        ],\n        'validate-number-range': [\n            function (v, elm, param) {\n                var numValue, dataAttrRange, classNameRange, result, range, m, classes, ii;\n\n                if ($.mage.isEmptyNoTrim(v)) {\n                    return true;\n                }\n\n                numValue = $.mage.parseNumber(v);\n\n                if (isNaN(numValue)) {\n                    return false;\n                }\n\n                dataAttrRange = /^(-?[\\d.,]+)?-(-?[\\d.,]+)?$/;\n                classNameRange = /^number-range-(-?[\\d.,]+)?-(-?[\\d.,]+)?$/;\n                result = true;\n                range = param;\n\n                if (typeof range === 'string') {\n                    m = dataAttrRange.exec(range);\n\n                    if (m) {\n                        result = result && $.mage.isBetween(numValue, m[1], m[2]);\n                    } else {\n                        result = false;\n                    }\n                } else if (elm && elm.className) {\n                    classes = elm.className.split(' ');\n                    ii = classes.length;\n\n                    while (ii--) {\n                        range = classes[ii];\n                        m = classNameRange.exec(range);\n\n                        if (m) { //eslint-disable-line max-depth\n                            result = result && $.mage.isBetween(numValue, m[1], m[2]);\n                            break;\n                        }\n                    }\n                }\n\n                return result;\n            },\n            $.mage.__('The value is not within the specified range.'),\n            true\n        ],\n        'validate-digits': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || !/[^\\d]/.test(v);\n            },\n            $.mage.__('Please enter a valid number in this field.')\n        ],\n        'validate-forbidden-extensions': [\n            function (v, elem) {\n                var forbiddenExtensions = $(elem).attr('data-validation-params'),\n                    forbiddenExtensionsArray = forbiddenExtensions.split(','),\n                    extensionsArray = v.split(','),\n                    result = true;\n\n                this.validateExtensionsMessage = $.mage.__('Forbidden extensions has been used. Avoid usage of ') +\n                    forbiddenExtensions;\n\n                $.each(extensionsArray, function (key, extension) {\n                    if (forbiddenExtensionsArray.indexOf(extension) !== -1) {\n                        result = false;\n                    }\n                });\n\n                return result;\n            }, function () {\n                return this.validateExtensionsMessage;\n            }\n        ],\n        'validate-digits-range': [\n            function (v, elm, param) {\n                var numValue, dataAttrRange, classNameRange, result, range, m, classes, ii;\n\n                if ($.mage.isEmptyNoTrim(v)) {\n                    return true;\n                }\n\n                numValue = $.mage.parseNumber(v);\n\n                if (isNaN(numValue)) {\n                    return false;\n                }\n\n                dataAttrRange = /^(-?\\d+)?-(-?\\d+)?$/;\n                classNameRange = /^digits-range-(-?\\d+)?-(-?\\d+)?$/;\n                result = true;\n                range = param;\n\n                if (typeof range === 'string') {\n                    m = dataAttrRange.exec(range);\n\n                    if (m) {\n                        result = result && $.mage.isBetween(numValue, m[1], m[2]);\n                    } else {\n                        result = false;\n                    }\n                } else if (elm && elm.className) {\n                    classes = elm.className.split(' ');\n                    ii = classes.length;\n\n                    while (ii--) {\n                        range = classes[ii];\n                        m = classNameRange.exec(range);\n\n                        if (m) { //eslint-disable-line max-depth\n                            result = result && $.mage.isBetween(numValue, m[1], m[2]);\n                            break;\n                        }\n                    }\n                }\n\n                return result;\n            },\n            $.mage.__('The value is not within the specified range.'),\n            true\n        ],\n        'validate-range': [\n            function (v, elm) {\n                var minValue, maxValue, ranges, reRange, result, values,\n                    i, name, validRange, minValidRange, maxValidRange;\n\n                if ($.mage.isEmptyNoTrim(v)) {\n                    return true;\n                } else if ($.validator.methods['validate-digits'] && $.validator.methods['validate-digits'](v)) {\n                    minValue = maxValue = $.mage.parseNumber(v);\n                } else {\n                    ranges = /^(-?\\d+)?-(-?\\d+)?$/.exec(v);\n\n                    if (ranges) {\n                        minValue = $.mage.parseNumber(ranges[1]);\n                        maxValue = $.mage.parseNumber(ranges[2]);\n\n                        if (minValue > maxValue) { //eslint-disable-line max-depth\n                            return false;\n                        }\n                    } else {\n                        return false;\n                    }\n                }\n                reRange = /^range-(-?\\d+)?-(-?\\d+)?$/;\n                result = true;\n                values = $(elm).prop('class').split(' ');\n\n                for (i = values.length - 1; i >= 0; i--) {\n                    name = values[i];\n                    validRange = reRange.exec(name);\n\n                    if (validRange) {\n                        minValidRange = $.mage.parseNumber(validRange[1]);\n                        maxValidRange = $.mage.parseNumber(validRange[2]);\n                        result = result &&\n                            (isNaN(minValidRange) || minValue >= minValidRange) &&\n                            (isNaN(maxValidRange) || maxValue <= maxValidRange);\n                    }\n                }\n\n                return result;\n            },\n            $.mage.__('The value is not within the specified range.')\n        ],\n        'validate-alpha': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z]+$/.test(v);\n            },\n            $.mage.__('Please use letters only (a-z or A-Z) in this field.')\n        ],\n        'validate-code': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z]+[a-zA-Z0-9_]+$/.test(v);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.') //eslint-disable-line max-len\n        ],\n        'validate-alphanum': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z0-9]+$/.test(v);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.') //eslint-disable-line max-len\n        ],\n        'validate-not-number-first': [\n            function (value) {\n                return $.mage.isEmptyNoTrim(value) || /^[^0-9-\\.].*$/.test(value.trim());\n            },\n            $.mage.__('First character must be letter.')\n        ],\n        'validate-date': [\n            function (value, params, additionalParams) {\n                var test = moment(value, utils.convertToMomentFormat(additionalParams.dateFormat));\n\n                return $.mage.isEmptyNoTrim(value) || test.isValid();\n            },\n            $.mage.__('Please enter a valid date.')\n\n        ],\n        'validate-date-range': [\n            function (v, elm) {\n                var m = /\\bdate-range-(\\w+)-(\\w+)\\b/.exec(elm.className),\n                    currentYear, normalizedTime, dependentElements;\n\n                if (!m || m[2] === 'to' || $.mage.isEmptyNoTrim(v)) {\n                    return true;\n                }\n\n                currentYear = new Date().getFullYear() + '';\n\n                /**\n                 * @param {String} vd\n                 * @return {Number}\n                 */\n                normalizedTime = function (vd) {\n                    vd = vd.split(/[.\\/]/);\n\n                    if (vd[2] && vd[2].length < 4) {\n                        vd[2] = currentYear.substr(0, vd[2].length) + vd[2];\n                    }\n\n                    return new Date(vd.join('/')).getTime();\n                };\n\n                dependentElements = $(elm.form).find('.validate-date-range.date-range-' + m[1] + '-to');\n\n                return !dependentElements.length || $.mage.isEmptyNoTrim(dependentElements[0].value) ||\n                    normalizedTime(v) <= normalizedTime(dependentElements[0].value);\n            },\n            $.mage.__('Make sure the To Date is later than or the same as the From Date.')\n        ],\n        'validate-cpassword': [\n            function () {\n                var conf = $('#confirmation').length > 0 ? $('#confirmation') : $($('.validate-cpassword')[0]),\n                    pass = false,\n                    passwordElements, i, passwordElement;\n\n                if ($('#password')) {\n                    pass = $('#password');\n                }\n                passwordElements = $('.validate-password');\n\n                for (i = 0; i < passwordElements.length; i++) {\n                    passwordElement = $(passwordElements[i]);\n\n                    if (passwordElement.closest('form').attr('id') === conf.closest('form').attr('id')) {\n                        pass = passwordElement;\n                    }\n                }\n\n                if ($('.validate-admin-password').length) {\n                    pass = $($('.validate-admin-password')[0]);\n                }\n\n                return pass.val() === conf.val();\n            },\n            $.mage.__('Please make sure your passwords match.')\n        ],\n        'validate-identifier': [\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^[a-z0-9][a-z0-9_\\/-]+(\\.[a-z0-9_-]+)?$/.test(v);\n            },\n            $.mage.__('Please enter a valid URL Key (Ex: \"example-page\", \"example-page.html\" or \"anotherlevel/example-page\").') //eslint-disable-line max-len\n        ],\n        'validate-zip-international': [\n\n            /*function(v) {\n             // @TODO: Cleanup\n             return Validation.get('IsEmpty').test(v) ||\n             /(^[A-z0-9]{2,10}([\\s]{0,1}|[\\-]{0,1})[A-z0-9]{2,10}$)/.test(v);\n             }*/\n            function () {\n                return true;\n            },\n            $.mage.__('Please enter a valid zip code.')\n        ],\n        'validate-one-required': [\n            function (v, elm) {\n                var p = $(elm).parent(),\n                    options = p.find('input');\n\n                return options.map(function (el) {\n                    return $(el).val();\n                }).length > 0;\n            },\n            $.mage.__('Please select one of the options above.')\n        ],\n        'validate-state': [\n            function (v) {\n                return v !== 0;\n            },\n            $.mage.__('Please select State/Province.')\n        ],\n        'required-file': [\n            function (v, elm) {\n                var result = !$.mage.isEmptyNoTrim(v),\n                    ovId;\n\n                if (!result) {\n                    ovId = $('#' + $(elm).attr('id') + '_value');\n\n                    if (ovId.length > 0) {\n                        result = !$.mage.isEmptyNoTrim(ovId.val());\n                    }\n                }\n\n                return result;\n            },\n            $.mage.__('Please select a file.')\n        ],\n        'validate-ajax-error': [\n            function (v, element) {\n                element = $(element);\n                element.on('change.ajaxError', function () {\n                    element.removeClass('validate-ajax-error');\n                    element.off('change.ajaxError');\n                });\n\n                return !element.hasClass('validate-ajax-error');\n            },\n            ''\n        ],\n        'validate-optional-datetime': [\n            function (v, elm, param) {\n                var dateTimeParts = $('.datetime-picker[id^=\"options_' + param + '\"]'),\n                    hasWithValue = false,\n                    hasWithNoValue = false,\n                    pattern = /day_part$/i,\n                    i;\n\n                for (i = 0; i < dateTimeParts.length; i++) {\n                    if (!pattern.test($(dateTimeParts[i]).attr('id'))) {\n                        if ($(dateTimeParts[i]).val() === 's') { //eslint-disable-line max-depth\n                            hasWithValue = true;\n                        } else {\n                            hasWithNoValue = true;\n                        }\n                    }\n                }\n\n                return hasWithValue ^ hasWithNoValue;\n            },\n            $.mage.__('The field isn\\'t complete.')\n        ],\n        'validate-required-datetime': [\n            function (v, elm, param) {\n                var dateTimeParts = $('.datetime-picker[id^=\"options_' + param + '\"]'),\n                    i;\n\n                for (i = 0; i < dateTimeParts.length; i++) {\n                    if (dateTimeParts[i].value === '') {\n                        return false;\n                    }\n                }\n\n                return true;\n            },\n            $.mage.__('This is a required field.')\n        ],\n        'validate-one-required-by-name': [\n            function (v, elm, selector) {\n                var name = elm.name.replace(/([\\\\\"])/g, '\\\\$1'),\n                    container = this.currentForm;\n\n                selector = selector === true ? 'input[name=\"' + name + '\"]:checked' : selector;\n\n                return !!container.querySelectorAll(selector).length;\n            },\n            $.mage.__('Please select one of the options.')\n        ],\n        'less-than-equals-to': [\n            function (value, element, params) {\n                if ($.isNumeric($(params).val()) && $.isNumeric(value)) {\n                    this.lteToVal = $(params).val();\n\n                    return parseFloat(value) <= parseFloat($(params).val());\n                }\n\n                return true;\n            },\n            function () {\n                var message = $.mage.__('Please enter a value less than or equal to %s.');\n\n                return message.replace('%s', this.lteToVal);\n            }\n        ],\n        'greater-than-equals-to': [\n            function (value, element, params) {\n                if ($.isNumeric($(params).val()) && $.isNumeric(value)) {\n                    this.gteToVal = $(params).val();\n\n                    return parseFloat(value) >= parseFloat($(params).val());\n                }\n\n                return true;\n            },\n            function () {\n                var message = $.mage.__('Please enter a value greater than or equal to %s.');\n\n                return message.replace('%s', this.gteToVal);\n            }\n        ],\n        'validate-emails': [\n            function (value) {\n                var validRegexp, emails, i;\n\n                if ($.mage.isEmpty(value)) {\n                    return true;\n                }\n                validRegexp = /^([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*@([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*\\.(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]){2,})$/i; //eslint-disable-line max-len\n                emails = value.split(/[\\s\\n\\,]+/g);\n\n                for (i = 0; i < emails.length; i++) {\n                    if (!validRegexp.test(emails[i].trim())) {\n                        return false;\n                    }\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter valid email addresses, separated by commas. For example, johndoe@domain.com, johnsmith@domain.com.') //eslint-disable-line max-len\n        ],\n\n        'validate-cc-type-select': [\n\n            /**\n             * Validate credit card type matches credit card number\n             * @param {*} value - select credit card type\n             * @param {*} element - element contains the select box for credit card types\n             * @param {*} params - selector for credit card number\n             * @return {Boolean}\n             */\n            function (value, element, params) {\n                if (value && params && creditCartTypes[value]) {\n                    return creditCartTypes[value][0].test($(params).val().replace(/\\s+/g, ''));\n                }\n\n                return false;\n            },\n            $.mage.__('Card type does not match credit card number.')\n        ],\n        'validate-cc-number': [\n\n            /**\n             * Validate credit card number based on mod 10.\n             *\n             * @param {*} value - credit card number\n             * @return {Boolean}\n             */\n            function (value) {\n                if (value) {\n                    return validateCreditCard(value);\n                }\n\n                return false;\n            },\n            $.mage.__('Please enter a valid credit card number.')\n        ],\n        'validate-cc-type': [\n\n            /**\n             * Validate credit card number is for the correct credit card type.\n             *\n             * @param {String} value - credit card number\n             * @param {*} element - element contains credit card number\n             * @param {*} params - selector for credit card type\n             * @return {Boolean}\n             */\n            function (value, element, params) {\n                var ccType;\n\n                if (value && params) {\n                    ccType = $(params).val();\n                    value = value.replace(/\\s/g, '').replace(/\\-/g, '');\n\n                    if (creditCartTypes[ccType] && creditCartTypes[ccType][0]) {\n                        return creditCartTypes[ccType][0].test(value);\n                    } else if (creditCartTypes[ccType] && !creditCartTypes[ccType][0]) {\n                        return true;\n                    }\n                }\n\n                return false;\n            },\n            $.mage.__('Credit card number does not match credit card type.')\n        ],\n        'validate-cc-exp': [\n\n            /**\n             * Validate credit card expiration date, make sure it's within the year and not before current month.\n             *\n             * @param {*} value - month\n             * @param {*} element - element contains month\n             * @param {*} params - year selector\n             * @return {Boolean}\n             */\n            function (value, element, params) {\n                var isValid = false,\n                    month, year, currentTime, currentMonth, currentYear;\n\n                if (value && params) {\n                    month = value;\n                    year = $(params).val();\n                    currentTime = new Date();\n                    currentMonth = currentTime.getMonth() + 1;\n                    currentYear = currentTime.getFullYear();\n\n                    isValid = !year || year > currentYear || year == currentYear && month >= currentMonth; //eslint-disable-line\n                }\n\n                return isValid;\n            },\n            $.mage.__('Incorrect credit card expiration date.')\n        ],\n        'validate-cc-cvn': [\n\n            /**\n             * Validate credit card cvn based on credit card type.\n             *\n             * @param {*} value - credit card cvn\n             * @param {*} element - element contains credit card cvn\n             * @param {*} params - credit card type selector\n             * @return {*}\n             */\n            function (value, element, params) {\n                var ccType;\n\n                if (value && params) {\n                    ccType = $(params).val();\n\n                    if (creditCartTypes[ccType] && creditCartTypes[ccType][0]) {\n                        return creditCartTypes[ccType][1].test(value);\n                    }\n                }\n\n                return false;\n            },\n            $.mage.__('Please enter a valid credit card verification number.')\n        ],\n        'validate-cc-ukss': [\n\n            /**\n             * Validate Switch/Solo/Maestro issue number and start date is filled.\n             *\n             * @param {*} value - input field value\n             * @return {*}\n             */\n            function (value) {\n                return value;\n            },\n            $.mage.__('Please enter issue number or start date for switch/solo card type.')\n        ],\n        'validate-length': [\n            function (v, elm) {\n                var reMax = new RegExp(/^maximum-length-[0-9]+$/),\n                    reMin = new RegExp(/^minimum-length-[0-9]+$/),\n                    validator = this,\n                    result = true,\n                    length = 0;\n\n                $.each(elm.className.split(' '), function (index, name) {\n                    if (name.match(reMax) && result) {\n                        length = name.split('-')[2];\n                        result = v.length <= length;\n                        validator.validateMessage =\n                            $.mage.__('Please enter less or equal than %1 symbols.').replace('%1', length);\n                    }\n\n                    if (name.match(reMin) && result && !$.mage.isEmpty(v)) {\n                        length = name.split('-')[2];\n                        result = v.length >= length;\n                        validator.validateMessage =\n                            $.mage.__('Please enter more or equal than %1 symbols.').replace('%1', length);\n                    }\n                });\n\n                return result;\n            }, function () {\n                return this.validateMessage;\n            }\n        ],\n        'required-entry': [\n            function (value) {\n                return !$.mage.isEmpty(value);\n            }, $.mage.__('This is a required field.')\n        ],\n        'not-negative-amount': [\n            function (v) {\n                if (v.length) {\n                    return (/^\\s*\\d+([,.]\\d+)*\\s*%?\\s*$/).test(v);\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter positive number in this field.')\n        ],\n        'validate-per-page-value-list': [\n            function (v) {\n                var isValid = true,\n                    values = v.split(','),\n                    i;\n\n                if ($.mage.isEmpty(v)) {\n                    return isValid;\n                }\n\n                for (i = 0; i < values.length; i++) {\n                    if (!/^[0-9]+$/.test(values[i])) {\n                        isValid = false;\n                    }\n                }\n\n                return isValid;\n            },\n            $.mage.__('Please enter a valid value, ex: 10,20,30')\n        ],\n        'validate-per-page-value': [\n            function (v, elm) {\n                var values;\n\n                if ($.mage.isEmpty(v)) {\n                    return false;\n                }\n                values = $('#' + elm.id + '_values').val().split(',');\n\n                return values.indexOf(v) !== -1;\n            },\n            $.mage.__('Please enter a valid value from list')\n        ],\n        'validate-new-password': [\n            function (v) {\n                if ($.validator.methods['validate-password'] && !$.validator.methods['validate-password'](v)) {\n                    return false;\n                }\n\n                if ($.mage.isEmpty(v) && v !== '') {\n                    return false;\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n        ],\n        'required-if-not-specified': [\n            function (value, element, params) {\n                var valid = false,\n                    alternate = $(params),\n                    alternateValue;\n\n                if (alternate.length > 0) {\n                    valid = this.check(alternate);\n                    // if valid, it may be blank, so check for that\n                    if (valid) {\n                        alternateValue = alternate.val();\n\n                        if (typeof alternateValue == 'undefined' || alternateValue.length === 0) { //eslint-disable-line\n                            valid = false;\n                        }\n                    }\n                }\n\n                if (!valid) {\n                    valid = !this.optional(element);\n                }\n\n                return valid;\n            },\n            $.mage.__('This is a required field.')\n        ],\n        'required-if-all-sku-empty-and-file-not-loaded': [\n            function (value, element, params) {\n                var valid = false,\n                    alternate = $(params.specifiedId),\n                    alternateValue;\n\n                if (alternate.length > 0) {\n                    valid = this.check(alternate);\n                    // if valid, it may be blank, so check for that\n                    if (valid) {\n                        alternateValue = alternate.val();\n\n                        if (typeof alternateValue == 'undefined' || alternateValue.length === 0) { //eslint-disable-line\n                            valid = false;\n                        }\n                    }\n                }\n\n                if (!valid) {\n                    valid = !this.optional(element);\n                }\n\n                $('input[' + params.dataSku + '=true]').each(function () {\n                    if ($(this).val() !== '') {\n                        valid = true;\n                    }\n                });\n\n                return valid;\n            },\n            $.mage.__('Please enter valid SKU key.')\n        ],\n        'required-if-specified': [\n            function (value, element, params) {\n                var valid = true,\n                    dependent = $(params),\n                    dependentValue;\n\n                if (dependent.length > 0) {\n                    valid = this.check(dependent);\n                    // if valid, it may be blank, so check for that\n                    if (valid) {\n                        dependentValue = dependent.val();\n                        valid = typeof dependentValue != 'undefined' && dependentValue.length > 0;\n                    }\n                }\n\n                if (valid) {\n                    valid = !this.optional(element);\n                } else {\n                    valid = true; // dependent was not valid, so don't even check\n                }\n\n                return valid;\n            },\n            $.mage.__('This is a required field.')\n        ],\n        'required-number-if-specified': [\n            function (value, element, params) {\n                var valid = true,\n                    dependent = $(params),\n                    depeValue;\n\n                if (dependent.length) {\n                    valid = this.check(dependent);\n\n                    if (valid) {\n                        depeValue = dependent[0].value;\n                        valid = !!(depeValue && depeValue.length);\n                    }\n                }\n\n                return valid ? !!value.length : true;\n            },\n            $.mage.__('Please enter a valid number.')\n        ],\n        'datetime-validation': [\n            function (value, element) {\n                var isValid = true;\n\n                if ($(element).val().length === 0) {\n                    isValid = false;\n                    $(element).addClass('mage-error');\n                }\n\n                return isValid;\n            },\n            $.mage.__('This is required field')\n        ],\n        'required-text-swatch-entry': [\n            tableSingleValidation,\n            $.mage.__('Admin is a required field in each row.')\n        ],\n        'required-visual-swatch-entry': [\n            tableSingleValidation,\n            $.mage.__('Admin is a required field in each row.')\n        ],\n        'required-dropdown-attribute-entry': [\n            tableSingleValidation,\n            $.mage.__('Admin is a required field in each row.')\n        ],\n        'validate-item-quantity': [\n            function (value, element, params) {\n                var validator = this,\n                    result = false,\n                    // obtain values for validation\n                    qty = $.mage.parseNumber(value),\n                    isMinAllowedValid = typeof params.minAllowed === 'undefined' ||\n                        qty >= $.mage.parseNumber(params.minAllowed),\n                    isMaxAllowedValid = typeof params.maxAllowed === 'undefined' ||\n                        qty <= $.mage.parseNumber(params.maxAllowed),\n                    isQtyIncrementsValid = typeof params.qtyIncrements === 'undefined' ||\n                        resolveModulo(qty, $.mage.parseNumber(params.qtyIncrements)) === 0.0;\n\n                result = qty > 0;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('Please enter a quantity greater than 0.');//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                result = isMinAllowedValid;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('The fewest you may purchase is %1.').replace('%1', params.minAllowed);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                result = isMaxAllowedValid;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('The maximum you may purchase is %1.').replace('%1', params.maxAllowed);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                result = isQtyIncrementsValid;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('You can buy this product only in quantities of %1 at a time.').replace('%1', params.qtyIncrements);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                return result;\n            }, function () {\n                return this.itemQtyErrorMessage;\n            }\n        ],\n        'password-not-equal-to-user-name': [\n            function (value, element, params) {\n                if (typeof params === 'string') {\n                    return value.toLowerCase() !== params.toLowerCase();\n                }\n\n                return true;\n            },\n            $.mage.__('The password can\\'t be the same as the email address. Create a new password and try again.')\n        ]\n    };\n\n    $.each(rules, function (i, rule) {\n        rule.unshift(i);\n        $.validator.addMethod.apply($.validator, rule);\n    });\n    $.validator.addClassRules({\n        'required-option': {\n            required: true\n        },\n        'required-options-count': {\n            required: true\n        },\n        'validate-both-passwords': {\n            'validate-cpassword': true\n        }\n    });\n    $.validator.messages = $.extend($.validator.messages, {\n        required: $.mage.__('This is a required field.'),\n        remote: $.mage.__('Please fix this field.'),\n        email: $.mage.__('Please enter a valid email address.'),\n        url: $.mage.__('Please enter a valid URL.'),\n        date: $.mage.__('Please enter a valid date.'),\n        dateISO: $.mage.__('Please enter a valid date (ISO).'),\n        number: $.mage.__('Please enter a valid number.'),\n        digits: $.mage.__('Please enter only digits.'),\n        creditcard: $.mage.__('Please enter a valid credit card number.'),\n        equalTo: $.mage.__('Please enter the same value again.'),\n        maxlength: $.validator.format($.mage.__('Please enter no more than {0} characters.')),\n        minlength: $.validator.format($.mage.__('Please enter at least {0} characters.')),\n        rangelength: $.validator.format($.mage.__('Please enter a value between {0} and {1} characters long.')),\n        range: $.validator.format($.mage.__('Please enter a value between {0} and {1}.')),\n        max: $.validator.format($.mage.__('Please enter a value less than or equal to {0}.')),\n        min: $.validator.format($.mage.__('Please enter a value greater than or equal to {0}.'))\n    });\n\n    if ($.metadata) {\n        // Setting the type as html5 to enable data-validate attribute\n        $.metadata.setType('html5');\n    }\n\n    showLabel = $.validator.prototype.showLabel;\n    $.extend(true, $.validator.prototype, {\n        /**\n         * @param {*} element\n         * @param {*} message\n         */\n        showLabel: function (element, message) {\n            var label, elem;\n\n            showLabel.call(this, element, message);\n\n            // ARIA (adding aria-invalid & aria-describedby)\n            label = this.errorsFor(element);\n            elem = $(element);\n\n            if (!label.attr('id')) {\n                label.attr('id', this.idOrName(element) + '-error');\n            }\n            elem.attr('aria-invalid', 'true')\n                .attr('aria-describedby', label.attr('id'));\n        }\n    });\n\n    /**\n     * Validate form field without instantiating validate plug-in.\n     *\n     * @param {Element|String} element - DOM element or selector\n     * @return {Boolean} validation result\n     */\n    $.validator.validateElement = function (element) {\n        var form, validator, valid, classes;\n\n        element = $(element);\n        form = element.get(0).form;\n        validator = form ? $(form).data('validator') : null;\n\n        if (validator) {\n            return validator.element(element.get(0));\n        }\n        valid = true;\n        classes = element.prop('class').split(' ');\n        $.each(classes, $.proxy(function (i, className) {\n            if (this.methods[className] && !this.methods[className](element.val(), element.get(0))) {\n                valid = false;\n\n                return valid;\n            }\n        }, this));\n\n        return valid;\n    };\n\n    originValidateDelegate = $.fn.validateDelegate;\n\n    /**\n     * @return {*}\n     */\n    $.fn.validateDelegate = function () {\n        if (!this[0].form) {\n            return this;\n        }\n\n        return originValidateDelegate.apply(this, arguments);\n    };\n\n    /**\n     * Validate single element.\n     *\n     * @param {Element} element\n     * @param {Object} config\n     * @returns {*}\n     */\n    $.validator.validateSingleElement = function (element, config) {\n        var errors = {},\n            valid = true,\n            validateConfig = {\n                errorElement: 'label',\n                ignore: '.ignore-validate',\n                hideError: false\n            },\n            form, validator, classes, elementValue;\n\n        $.extend(validateConfig, config);\n        element = $(element).not(validateConfig.ignore);\n\n        if (!element.length) {\n            return true;\n        }\n\n        form = element.get(0).form;\n        validator = form ? $(form).data('validator') : null;\n\n        if (validator) {\n            return validator.element(element.get(0));\n        }\n\n        classes = element.prop('class').split(' ');\n        validator = element.parent().data('validator') ||\n            $.mage.validation(validateConfig, element.parent()).validate;\n\n        element.removeClass(validator.settings.errorClass);\n        validator.toHide = validator.toShow;\n        validator.hideErrors();\n        validator.toShow = validator.toHide = $([]);\n\n        $.each(classes, $.proxy(function (i, className) {\n            elementValue = element.val();\n\n            if (element.is(':checkbox') || element.is(':radio')) {\n                elementValue = element.is(':checked') || null;\n            }\n\n            if (this.methods[className] && !this.methods[className](elementValue, element.get(0))) {\n                valid = false;\n                errors[element.get(0).name] = this.messages[className];\n                validator.invalid[element.get(0).name] = true;\n\n                if (!validateConfig.hideError) {\n                    validator.showErrors(errors);\n                }\n\n                return valid;\n            }\n        }, this));\n\n        return valid;\n    };\n\n    $.widget('mage.validation', {\n        options: {\n            meta: 'validate',\n            onfocusout: false,\n            onkeyup: false,\n            onclick: false,\n            ignoreTitle: true,\n            errorClass: 'mage-error',\n            errorElement: 'div',\n\n            /**\n             * @param {*} error\n             * @param {*} element\n             */\n            errorPlacement: function (error, element) {\n                var errorPlacement = element,\n                    fieldWrapper;\n\n                // logic for date-picker error placement\n                if (element.hasClass('_has-datepicker')) {\n                    errorPlacement = element.siblings('button');\n                }\n                // logic for field wrapper\n                fieldWrapper = element.closest('.addon');\n\n                if (fieldWrapper.length) {\n                    errorPlacement = fieldWrapper.after(error);\n                }\n                //logic for checkboxes/radio\n                if (element.is(':checkbox') || element.is(':radio')) {\n                    errorPlacement = element.parents('.control').children().last();\n\n                    //fallback if group does not have .control parent\n                    if (!errorPlacement.length) {\n                        errorPlacement = element.siblings('label').last();\n                    }\n                }\n                //logic for control with tooltip\n                if (element.siblings('.tooltip').length) {\n                    errorPlacement = element.siblings('.tooltip');\n                }\n                //logic for select with tooltip in after element\n                if (element.next().find('.tooltip').length) {\n                    errorPlacement = element.next();\n                }\n                errorPlacement.after(error);\n            }\n        },\n\n        /**\n         * Check if form pass validation rules without submit.\n         *\n         * @return boolean\n         */\n        isValid: function () {\n            return this.element.valid();\n        },\n\n        /**\n         * Remove validation error messages\n         */\n        clearError: function () {\n            if (arguments.length) {\n                $.each(arguments, $.proxy(function (index, item) {\n                    this.validate.prepareElement(item);\n                    this.validate.hideErrors();\n                }, this));\n            } else {\n                this.validate.resetForm();\n            }\n        },\n\n        /**\n         * Validation creation.\n         *\n         * @protected\n         */\n        _create: function () {\n            this.validate = this.element.validate(this.options);\n\n            // ARIA (adding aria-required attribute)\n            this.element\n                .find('.field.required')\n                .find('.control')\n                .find('input, select, textarea')\n                .attr('aria-required', 'true');\n\n            this._listenFormValidate();\n        },\n\n        /**\n         * Validation listening.\n         *\n         * @protected\n         */\n        _listenFormValidate: function () {\n            $('form').on('invalid-form.validate', this.listenFormValidateHandler);\n        },\n\n        /**\n         * Handle form validation. Focus on first invalid form field.\n         *\n         * @param {jQuery.Event} event\n         * @param {Object} validation\n         */\n        listenFormValidateHandler: function (event, validation) {\n            var firstActive = $(validation.errorList[0].element || []),\n                lastActive = $(validation.findLastActive() ||\n                    validation.errorList.length && validation.errorList[0].element || []),\n                windowHeight = $(window).height(),\n                parent, successList;\n\n            if (lastActive.is(':hidden')) {\n                parent = lastActive.parent();\n                $('html, body').animate({\n                    scrollTop: parent.offset().top - windowHeight / 2\n                });\n            }\n\n            // ARIA (removing aria attributes if success)\n            successList = validation.successList;\n\n            if (successList.length) {\n                $.each(successList, function () {\n                    $(this)\n                        .removeAttr('aria-describedby')\n                        .removeAttr('aria-invalid');\n                });\n            }\n\n            if (firstActive.length) {\n                $('html, body').stop().animate({\n                    scrollTop: firstActive.parent().offset().top - windowHeight / 2\n                });\n                firstActive.focus();\n            }\n        }\n    });\n\n    return $.mage.validation;\n});\n","mage/smart-keyboard-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    /**\n     * @return {Object}\n     * @constructor\n     */\n    function KeyboardHandler() {\n        var body = $('body'),\n            focusState = false,\n            tabFocusClass = '_keyfocus',\n            productsGrid = '[data-container=\"product-grid\"]',\n            catalogProductsGrid = $(productsGrid),\n            CODE_TAB = 9;\n\n        /**\n         * Handle logic, when onTabKeyPress fired at first.\n         * Then it changes state.\n         */\n        function onFocusInHandler() {\n            focusState = true;\n            body.addClass(tabFocusClass)\n                .off('focusin.keyboardHandler', onFocusInHandler);\n        }\n\n        /**\n         * Handle logic to remove state after onTabKeyPress to normal.\n         */\n        function onClickHandler() {\n            focusState = false;\n            body.removeClass(tabFocusClass)\n                .off('click', onClickHandler);\n        }\n\n        /**\n         * Tab key onKeypress handler. Apply main logic:\n         *  - call differ actions onTabKeyPress and onClick\n         */\n        function smartKeyboardFocus() {\n            $(document).on('keydown keypress', function (event) {\n                if (event.which === CODE_TAB && !focusState) {\n                    body\n                        .on('focusin.keyboardHandler', onFocusInHandler)\n                        .on('click', onClickHandler);\n                }\n            });\n\n            // ARIA support for catalog grid products\n            if (catalogProductsGrid.length) {\n                body.on('focusin.gridProducts', productsGrid, function () {\n                    if (body.hasClass(tabFocusClass)) {\n                        $(this).addClass('active');\n                    }\n                });\n                body.on('focusout.gridProducts', productsGrid, function () {\n                    $(this).removeClass('active');\n                });\n            }\n        }\n\n        /**\n         * Attach smart focus on specific element.\n         * @param {jQuery} element\n         */\n        function handleFocus(element) {\n            element.on('focusin.emulateTabFocus', function () {\n                focusState = true;\n                body.addClass(tabFocusClass);\n                element.off();\n            });\n\n            element.on('focusout.emulateTabFocus', function () {\n                focusState = false;\n                body.removeClass(tabFocusClass);\n                element.off();\n            });\n        }\n\n        return {\n            apply: smartKeyboardFocus,\n            focus: handleFocus\n        };\n    }\n\n    return new KeyboardHandler;\n});\n","mage/polyfill.js":"(function (root, doc) {\n    'use strict';\n\n    var Storage;\n\n    try {\n        if (!root.localStorage || !root.sessionStorage) {\n            throw new Error();\n        }\n\n        localStorage.setItem('storage_test', 1);\n        localStorage.removeItem('storage_test');\n    } catch (e) {\n        /**\n         * Returns a storage object to shim local or sessionStorage\n         * @param {String} type - either 'local' or 'session'\n         */\n        Storage = function (type) {\n            var data;\n\n            /**\n             * Creates a cookie\n             * @param {String} name\n             * @param {String} value\n             * @param {Integer} days\n             */\n            function createCookie(name, value, days) {\n                var date, expires;\n\n                if (days) {\n                    date = new Date();\n                    date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n                    expires = '; expires=' + date.toGMTString();\n                } else {\n                    expires = '';\n                }\n                doc.cookie = name + '=' + value + expires + '; path=/';\n            }\n\n            /**\n             * Reads value of a cookie\n             * @param {String} name\n             */\n            function readCookie(name) {\n                var nameEQ = name + '=',\n                    ca = doc.cookie.split(';'),\n                    i = 0,\n                    c;\n\n                for (i = 0; i < ca.length; i++) {\n                    c = ca[i];\n\n                    while (c.charAt(0) === ' ') {\n                        c = c.substring(1, c.length);\n                    }\n\n                    if (c.indexOf(nameEQ) === 0) {\n                        return c.substring(nameEQ.length, c.length);\n                    }\n                }\n\n                return null;\n            }\n\n            /**\n             * Returns cookie name based upon the storage type.\n             * If this is session storage, the function returns a unique cookie per tab\n             */\n            function getCookieName() {\n\n                if (type !== 'session') {\n                    return 'localstorage';\n                }\n\n                if (!root.name) {\n                    root.name = new Date().getTime();\n                }\n\n                return 'sessionStorage' + root.name;\n            }\n\n            /**\n             * Sets storage cookie to a data object\n             * @param {Object} dataObject\n             */\n            function setData(dataObject) {\n                data = encodeURIComponent(JSON.stringify(dataObject));\n                createCookie(getCookieName(), data, 365);\n            }\n\n            /**\n             * Clears value of cookie data\n             */\n            function clearData() {\n                createCookie(getCookieName(), '', 365);\n            }\n\n            /**\n             * @returns value of cookie data\n             */\n            function getData() {\n                var dataResponse = readCookie(getCookieName());\n\n                return dataResponse ? JSON.parse(decodeURIComponent(dataResponse)) : {};\n            }\n\n            data = getData();\n\n            return {\n                length: 0,\n\n                /**\n                 * Clears data from storage\n                 */\n                clear: function () {\n                    data = {};\n                    this.length = 0;\n                    clearData();\n                },\n\n                /**\n                 * Gets an item from storage\n                 * @param {String} key\n                 */\n                getItem: function (key) {\n                    return data[key] === undefined ? null : data[key];\n                },\n\n                /**\n                 * Gets an item by index from storage\n                 * @param {Integer} i\n                 */\n                key: function (i) {\n                    var ctr = 0,\n                        k;\n\n                    for (k in data) {\n\n                        if (data.hasOwnProperty(k)) {\n\n                            // eslint-disable-next-line max-depth\n                            if (ctr.toString() === i.toString()) {\n                                return k;\n                            }\n                            ctr++;\n                        }\n                    }\n\n                    return null;\n                },\n\n                /**\n                 * Removes an item from storage\n                 * @param {String} key\n                 */\n                removeItem: function (key) {\n                    delete data[key];\n                    this.length--;\n                    setData(data);\n                },\n\n                /**\n                 * Sets an item from storage\n                 * @param {String} key\n                 * @param {String} value\n                 */\n                setItem: function (key, value) {\n                    data[key] = value.toString();\n                    this.length++;\n                    setData(data);\n                }\n            };\n        };\n\n        root.localStorage.prototype = root.localStorage = new Storage('local');\n        root.sessionStorage.prototype = root.sessionStorage = new Storage('session');\n    }\n})(window, document);\n","mage/translate-inline.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/template',\n    'mage/utils/misc',\n    'mage/translate',\n    'jquery-ui-modules/dialog'\n], function ($, mageTemplate, miscUtils) {\n    'use strict';\n\n    $.widget('mage.translateInline', $.ui.dialog, {\n        options: {\n            translateForm: {\n                template: '#translate-form-template',\n                data: {\n                    id: 'translate-inline-form',\n                    message: 'Please refresh the page to see your changes after submitting this form. ' +\n                        'Note: browser cache refresh may be required'\n                }\n            },\n            autoOpen: false,\n            translateArea: null,\n            modal: true,\n            dialogClass: 'popup-window window-translate-inline',\n            width: '75%',\n            title: $.mage.__('Translate'),\n            height: 470,\n            position: {\n                my: 'left top',\n                at: 'center top',\n                of: 'body'\n            },\n            buttons: [{\n                text: $.mage.__('Submit'),\n                'class': 'action-primary',\n\n                /**\n                 * Click\n                 */\n                click: function () {\n                    $(this).translateInline('submit');\n                }\n            },\n            {\n                text: $.mage.__('Close'),\n                'class': 'action-close',\n\n                /**\n                 * Click.\n                 */\n                click: function () {\n                    $(this).translateInline('close');\n                }\n            }],\n\n            /**\n             * Open.\n             */\n            open: function () {\n                var $uiDialog = $(this).closest('.ui-dialog'),\n                    topMargin = $uiDialog.children('.ui-dialog-titlebar').outerHeight() + 45;\n\n                $uiDialog\n                    .addClass('ui-dialog-active')\n                    .css('margin-top', topMargin);\n            },\n\n            /**\n             * Close.\n             */\n            close: function () {\n                $(this).closest('.ui-dialog').removeClass('ui-dialog-active');\n            }\n        },\n\n        /**\n         * Translate Inline creation\n         * @protected\n         */\n        _create: function () {\n            var $translateArea = $(this.options.translateArea);\n\n            if (!$translateArea.length) {\n                $translateArea = $('body');\n            }\n            $translateArea.on('edit.editTrigger', $.proxy(this._onEdit, this));\n\n            this.tmpl = mageTemplate(this.options.translateForm.template);\n\n            this._super();\n        },\n\n        /**\n         * @param {*} templateData\n         * @return {*|jQuery|HTMLElement}\n         * @private\n         */\n        _prepareContent: function (templateData) {\n            var data = $.extend({\n                items: templateData,\n                escape: miscUtils.escape\n            }, this.options.translateForm.data);\n\n            this.data = data;\n\n            return $(this.tmpl({\n                data: data\n            }));\n        },\n\n        /**\n         * Render translation form and open dialog\n         * @param {Object} e - object\n         * @protected\n         */\n        _onEdit: function (e) {\n            this.target = e.target;\n            this.element.html(this._prepareContent($(e.target).data('translate')));\n            this.open(e);\n        },\n\n        /**\n         * Submit.\n         */\n        submit: function () {\n            if (this.formIsSubmitted) {\n                return;\n            }\n            this._formSubmit();\n        },\n\n        /**\n         * Send ajax request on form submit\n         * @protected\n         */\n        _formSubmit: function () {\n            var parameters = $.param({\n                    area: this.options.area\n                }) + '&' + $('#' + this.options.translateForm.data.id).serialize();\n\n            this.formIsSubmitted = true;\n\n            $.ajax({\n                url: this.options.ajaxUrl,\n                type: 'POST',\n                data: parameters,\n                loaderContext: this.element,\n                showLoader: true\n            }).always($.proxy(this._formSubmitComplete, this));\n        },\n\n        /**\n         * @param {Object} response\n         * @private\n         */\n        _formSubmitComplete: function (response) {\n            var responseJSON = response.responseJSON || response;\n\n            this.close();\n            this.formIsSubmitted = false;\n            $.mage.translate.add(responseJSON);\n            this._updatePlaceholder(responseJSON[this.data.items[0].original]);\n        },\n\n        /**\n         * @param {*} newValue\n         * @private\n         */\n        _updatePlaceholder: function (newValue) {\n            var $target = $(this.target),\n                translateObject = $target.data('translate')[0];\n\n            translateObject.shown = newValue;\n            translateObject.translated = newValue;\n            $.mage.translate.add(this.data.items[0].original, newValue);\n\n            $target.html(newValue);\n        },\n\n        /**\n         * Destroy translateInline\n         */\n        destroy: function () {\n            this.element.off('.editTrigger');\n            this._super();\n        }\n    });\n\n    return $.mage.translateInline;\n});\n","mage/menu.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'matchMedia',\n    'jquery-ui-modules/menu',\n    'mage/translate'\n], function ($, mediaCheck) {\n    'use strict';\n\n    /**\n     * Menu Widget - this widget is a wrapper for the jQuery UI Menu\n     */\n    $.widget('mage.menu', $.ui.menu, {\n        options: {\n            responsive: false,\n            expanded: false,\n            showDelay: 42,\n            hideDelay: 300,\n            delay: 0,\n            mediaBreakpoint: '(max-width: 768px)'\n        },\n\n        /**\n         * @private\n         */\n        _create: function () {\n            var self = this;\n\n            this.delay = this.options.delay;\n\n            this._super();\n            $(window).on('resize', function () {\n                self.element.find('.submenu-reverse').removeClass('submenu-reverse');\n            });\n        },\n\n        /**\n         * @private\n         */\n        _init: function () {\n            this._super();\n\n            if (this.options.expanded === true) {\n                this.isExpanded();\n            }\n\n            if (this.options.responsive === true) {\n                mediaCheck({\n                    media: this.options.mediaBreakpoint,\n                    entry: $.proxy(function () {\n                        this._toggleMobileMode();\n                    }, this),\n                    exit: $.proxy(function () {\n                        this._toggleDesktopMode();\n                    }, this)\n                });\n            }\n\n            this._assignControls()._listen();\n            this._setActiveMenu();\n        },\n\n        /**\n         * @return {Object}\n         * @private\n         */\n        _assignControls: function () {\n            this.controls = {\n                toggleBtn: $('[data-action=\"toggle-nav\"]')\n            };\n\n            return this;\n        },\n\n        /**\n         * @private\n         */\n        _listen: function () {\n            var controls = this.controls,\n                toggle = this.toggle;\n\n            controls.toggleBtn.off('click');\n            controls.toggleBtn.on('click', toggle.bind(this));\n        },\n\n        /**\n         * Toggle.\n         */\n        toggle: function () {\n            var html = $('html');\n\n            if (html.hasClass('nav-open')) {\n                html.removeClass('nav-open');\n                setTimeout(function () {\n                    html.removeClass('nav-before-open');\n                }, this.options.hideDelay);\n            } else {\n                html.addClass('nav-before-open');\n                setTimeout(function () {\n                    html.addClass('nav-open');\n                }, this.options.showDelay);\n            }\n        },\n\n        /**\n         * Tries to figure out the active category for current page and add appropriate classes:\n         *  - 'active' class for active category\n         *  - 'has-active' class for all parents of active category\n         *\n         *  First, checks whether current URL is URL of category page,\n         *  otherwise tries to retrieve category URL in case of current URL is product view page URL\n         *  which has category tree path in it.\n         *\n         * @return void\n         * @private\n         */\n        _setActiveMenu: function () {\n            var currentUrl = window.location.href.split('?')[0];\n\n            if (!this._setActiveMenuForCategory(currentUrl)) {\n                this._setActiveMenuForProduct(currentUrl);\n            }\n        },\n\n        /**\n         * Looks for category with provided URL and adds 'active' CSS class to it if it was not set before.\n         * If menu item has parent categories, sets 'has-active' class to all af them.\n         *\n         * @param {String} url - possible category URL\n         * @returns {Boolean} - true if active category was founded by provided URL, otherwise return false\n         * @private\n         */\n        _setActiveMenuForCategory: function (url) {\n            var activeCategoryLink = this.element.find('a[href=\"' + url + '\"]'),\n                classes,\n                classNav;\n\n            if (!activeCategoryLink || !activeCategoryLink.hasClass('ui-menu-item-wrapper')) {\n\n                //category was not found by provided URL\n                return false;\n            } else if (!activeCategoryLink.parent().hasClass('active')) {\n                activeCategoryLink.parent().addClass('active');\n                classes = activeCategoryLink.parent().attr('class');\n                classNav = classes.match(/(nav\\-)[0-9]+(\\-[0-9]+)+/gi);\n\n                if (classNav) {\n                    this._setActiveParent(classNav[0]);\n                }\n            }\n\n            return true;\n        },\n\n        /**\n         * Sets 'has-active' CSS class to all parent categories which have part of provided class in childClassName\n         *\n         * @example\n         *  childClassName - 'nav-1-2-3'\n         *  CSS class 'has-active' will be added to categories have 'nav-1-2' and 'nav-1' classes\n         *\n         * @param {String} childClassName - Class name of active category <li> element\n         * @return void\n         * @private\n         */\n        _setActiveParent: function (childClassName) {\n            var parentElement,\n                parentClass = childClassName.substr(0, childClassName.lastIndexOf('-'));\n\n            if (parentClass.lastIndexOf('-') !== -1) {\n                parentElement = this.element.find('.' + parentClass);\n\n                if (parentElement) {\n                    parentElement.addClass('has-active');\n                }\n                this._setActiveParent(parentClass);\n            }\n        },\n\n        /**\n         * Tries to retrieve category URL from current URL and mark this category as active\n         * @see _setActiveMenuForCategory(url)\n         *\n         * @example\n         *  currentUrl - http://magento.com/category1/category12/product.html,\n         *  category URLs has extensions .phtml - http://magento.com/category1.phtml\n         *  method sets active category which has URL http://magento.com/category1/category12.phtml\n         *\n         * @param {String} currentUrl - current page URL without parameters\n         * @return void\n         * @private\n         */\n        _setActiveMenuForProduct: function (currentUrl) {\n            var categoryUrlExtension,\n                lastUrlSection,\n                possibleCategoryUrl,\n                //retrieve first category URL to know what extension is used for category URLs\n                firstCategoryUrl = this.element.find('> li a').attr('href');\n\n            if (firstCategoryUrl) {\n                lastUrlSection = firstCategoryUrl.substr(firstCategoryUrl.lastIndexOf('/'));\n                categoryUrlExtension = lastUrlSection.lastIndexOf('.') !== -1 ?\n                    lastUrlSection.substr(lastUrlSection.lastIndexOf('.')) : '';\n\n                possibleCategoryUrl = currentUrl.substr(0, currentUrl.lastIndexOf('/')) + categoryUrlExtension;\n                this._setActiveMenuForCategory(possibleCategoryUrl);\n            }\n        },\n\n        /**\n         * Add class for expanded option.\n         */\n        isExpanded: function () {\n            var subMenus = this.element.find(this.options.menus),\n                expandedMenus = subMenus.find(this.options.menus);\n\n            expandedMenus.addClass('expanded');\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _activate: function (event) {\n            window.location.href = this.active.find('> a').attr('href');\n            this.collapseAll(event);\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _keydown: function (event) {\n            var match, prev, character, skip, regex,\n                preventDefault = true;\n\n            /* eslint-disable max-depth */\n            /**\n             * @param {String} value\n             */\n            function escape(value) {\n                return value.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, '\\\\$&');\n            }\n\n            if (this.active.closest(this.options.menus).attr('aria-expanded') != 'true') { //eslint-disable-line eqeqeq\n\n                switch (event.keyCode) {\n                    case $.ui.keyCode.PAGE_UP:\n                        this.previousPage(event);\n                        break;\n\n                    case $.ui.keyCode.PAGE_DOWN:\n                        this.nextPage(event);\n                        break;\n\n                    case $.ui.keyCode.HOME:\n                        this._move('first', 'first', event);\n                        break;\n\n                    case $.ui.keyCode.END:\n                        this._move('last', 'last', event);\n                        break;\n\n                    case $.ui.keyCode.UP:\n                        this.previous(event);\n                        break;\n\n                    case $.ui.keyCode.DOWN:\n                        if (this.active && !this.active.is('.ui-state-disabled')) {\n                            this.expand(event);\n                        }\n                        break;\n\n                    case $.ui.keyCode.LEFT:\n                        this.previous(event);\n                        break;\n\n                    case $.ui.keyCode.RIGHT:\n                        this.next(event);\n                        break;\n\n                    case $.ui.keyCode.ENTER:\n                    case $.ui.keyCode.SPACE:\n                        this._activate(event);\n                        break;\n\n                    case $.ui.keyCode.ESCAPE:\n                        this.collapse(event);\n                        break;\n                    default:\n                        preventDefault = false;\n                        prev = this.previousFilter || '';\n                        character = String.fromCharCode(event.keyCode);\n                        skip = false;\n\n                        clearTimeout(this.filterTimer);\n\n                        if (character === prev) {\n                            skip = true;\n                        } else {\n                            character = prev + character;\n                        }\n\n                        regex = new RegExp('^' + escape(character), 'i');\n                        match = this.activeMenu.children('.ui-menu-item').filter(function () {\n                            return regex.test($(this).children('a').text());\n                        });\n                        match = skip && match.index(this.active.next()) !== -1 ?\n                            this.active.nextAll('.ui-menu-item') :\n                            match;\n\n                        // If no matches on the current filter, reset to the last character pressed\n                        // to move down the menu to the first item that starts with that character\n                        if (!match.length) {\n                            character = String.fromCharCode(event.keyCode);\n                            regex = new RegExp('^' + escape(character), 'i');\n                            match = this.activeMenu.children('.ui-menu-item').filter(function () {\n                                return regex.test($(this).children('a').text());\n                            });\n                        }\n\n                        if (match.length) {\n                            this.focus(event, match);\n\n                            if (match.length > 1) {\n                                this.previousFilter = character;\n                                this.filterTimer = this._delay(function () {\n                                    delete this.previousFilter;\n                                }, 1000);\n                            } else {\n                                delete this.previousFilter;\n                            }\n                        } else {\n                            delete this.previousFilter;\n                        }\n                }\n            } else {\n                switch (event.keyCode) {\n                    case $.ui.keyCode.DOWN:\n                        this.next(event);\n                        break;\n\n                    case $.ui.keyCode.UP:\n                        this.previous(event);\n                        break;\n\n                    case $.ui.keyCode.RIGHT:\n                        if (this.active && !this.active.is('.ui-state-disabled')) {\n                            this.expand(event);\n                        }\n                        break;\n\n                    case $.ui.keyCode.ENTER:\n                    case $.ui.keyCode.SPACE:\n                        this._activate(event);\n                        break;\n\n                    case $.ui.keyCode.LEFT:\n                    case $.ui.keyCode.ESCAPE:\n                        this.collapse(event);\n                        break;\n                    default:\n                        preventDefault = false;\n                        prev = this.previousFilter || '';\n                        character = String.fromCharCode(event.keyCode);\n                        skip = false;\n\n                        clearTimeout(this.filterTimer);\n\n                        if (character === prev) {\n                            skip = true;\n                        } else {\n                            character = prev + character;\n                        }\n\n                        regex = new RegExp('^' + escape(character), 'i');\n                        match = this.activeMenu.children('.ui-menu-item').filter(function () {\n                            return regex.test($(this).children('a').text());\n                        });\n                        match = skip && match.index(this.active.next()) !== -1 ?\n                            this.active.nextAll('.ui-menu-item') :\n                            match;\n\n                        // If no matches on the current filter, reset to the last character pressed\n                        // to move down the menu to the first item that starts with that character\n                        if (!match.length) {\n                            character = String.fromCharCode(event.keyCode);\n                            regex = new RegExp('^' + escape(character), 'i');\n                            match = this.activeMenu.children('.ui-menu-item').filter(function () {\n                                return regex.test($(this).children('a').text());\n                            });\n                        }\n\n                        if (match.length) {\n                            this.focus(event, match);\n\n                            if (match.length > 1) {\n                                this.previousFilter = character;\n                                this.filterTimer = this._delay(function () {\n                                    delete this.previousFilter;\n                                }, 1000);\n                            } else {\n                                delete this.previousFilter;\n                            }\n                        } else {\n                            delete this.previousFilter;\n                        }\n                }\n            }\n\n            /* eslint-enable max-depth */\n            if (preventDefault) {\n                event.preventDefault();\n            }\n        },\n\n        /**\n         * @private\n         */\n        _toggleMobileMode: function () {\n            var subMenus;\n\n            $(this.element).off('mouseenter mouseleave');\n            this._on({\n\n                /**\n                 * @param {jQuery.Event} event\n                 */\n                'click .ui-menu-item:has(a)': function (event) {\n                    var target;\n\n                    event.preventDefault();\n                    target = $(event.target).closest('.ui-menu-item');\n                    target.get(0).scrollIntoView();\n\n                    // Open submenu on click\n                    if (target.has('.ui-menu').length) {\n                        this.expand(event);\n                    } else if (!this.element.is(':focus') &&\n                        $(this.document[0].activeElement).closest('.ui-menu').length\n                    ) {\n                        // Redirect focus to the menu\n                        this.element.trigger('focus', [true]);\n\n                        // If the active item is on the top level, let it stay active.\n                        // Otherwise, blur the active item since it is no longer visible.\n                        if (this.active && this.active.parents('.ui-menu').length === 1) { //eslint-disable-line\n                            clearTimeout(this.timer);\n                        }\n                    }\n\n                    if (!target.hasClass('level-top') || !target.has('.ui-menu').length) {\n                        window.location.href = target.find('> a').attr('href');\n                    }\n                },\n\n                /**\n                 * @param {jQuery.Event} event\n                 */\n                'click .ui-menu-item:has(.ui-state-active)': function (event) {\n                    this.collapseAll(event, true);\n                }\n            });\n\n            subMenus = this.element.find('.level-top');\n            $.each(subMenus, $.proxy(function (index, item) {\n                var category = $(item).find('> a span').not('.ui-menu-icon').text(),\n                    categoryUrl = $(item).find('> a').attr('href'),\n                    menu = $(item).find('> .ui-menu');\n\n                this.categoryLink = $('<a>')\n                    .attr('href', categoryUrl)\n                    .text($.mage.__('All %1').replace('%1', category));\n\n                this.categoryParent = $('<li>')\n                    .addClass('ui-menu-item all-category')\n                    .html(this.categoryLink);\n\n                if (menu.find('.all-category').length === 0) {\n                    menu.prepend(this.categoryParent);\n                }\n\n            }, this));\n        },\n\n        /**\n         * @private\n         */\n        _toggleDesktopMode: function () {\n            var categoryParent, html;\n\n            $(this.element).off('click mousedown mouseenter mouseleave');\n            this._on({\n\n                /**\n                 * Prevent focus from sticking to links inside menu after clicking\n                 * them (focus should always stay on UL during navigation).\n                 */\n                'mousedown .ui-menu-item > a': function (event) {\n                    event.preventDefault();\n                },\n\n                /**\n                 * Prevent focus from sticking to links inside menu after clicking\n                 * them (focus should always stay on UL during navigation).\n                 */\n                'click .ui-state-disabled > a': function (event) {\n                    event.preventDefault();\n                },\n\n                /**\n                 * @param {jQuer.Event} event\n                 */\n                'click .ui-menu-item:has(a)': function (event) {\n                    var target = $(event.target).closest('.ui-menu-item');\n\n                    if (!this.mouseHandled && target.not('.ui-state-disabled').length) {\n                        this.select(event);\n\n                        // Only set the mouseHandled flag if the event will bubble, see #9469.\n                        if (!event.isPropagationStopped()) {\n                            this.mouseHandled = true;\n                        }\n\n                        // Open submenu on click\n                        if (target.has('.ui-menu').length) {\n                            this.expand(event);\n                        } else if (!this.element.is(':focus') &&\n                            $(this.document[0].activeElement).closest('.ui-menu').length\n                        ) {\n                            // Redirect focus to the menu\n                            this.element.trigger('focus', [true]);\n\n                            // If the active item is on the top level, let it stay active.\n                            // Otherwise, blur the active item since it is no longer visible.\n                            if (this.active && this.active.parents('.ui-menu').length === 1) { //eslint-disable-line\n                                clearTimeout(this.timer);\n                            }\n                        }\n                    }\n                },\n\n                /**\n                 * @param {jQuery.Event} event\n                 */\n                'mouseenter .ui-menu-item': function (event) {\n                    var target = $(event.currentTarget),\n                        submenu = this.options.menus,\n                        ulElement,\n                        ulElementWidth,\n                        width,\n                        targetPageX,\n                        rightBound;\n\n                    if (target.has(submenu)) {\n                        ulElement = target.find(submenu);\n                        ulElementWidth = ulElement.outerWidth(true);\n                        width = target.outerWidth() * 2;\n                        targetPageX = target.offset().left;\n                        rightBound = $(window).width();\n\n                        if (ulElementWidth + width + targetPageX > rightBound) {\n                            ulElement.addClass('submenu-reverse');\n                        }\n\n                        if (targetPageX - ulElementWidth < 0) {\n                            ulElement.removeClass('submenu-reverse');\n                        }\n                    }\n\n                    // Remove ui-state-active class from siblings of the newly focused menu item\n                    // to avoid a jump caused by adjacent elements both having a class with a border\n                    target.siblings().children('.ui-state-active').removeClass('ui-state-active');\n                    this.focus(event, target);\n                },\n\n                /**\n                 * @param {jQuery.Event} event\n                 */\n                'mouseleave': function (event) {\n                    this.collapseAll(event, true);\n                },\n\n                /**\n                 * Mouse leave.\n                 */\n                'mouseleave .ui-menu': 'collapseAll'\n            });\n\n            categoryParent = this.element.find('.all-category');\n            html = $('html');\n\n            categoryParent.remove();\n\n            if (html.hasClass('nav-open')) {\n                html.removeClass('nav-open');\n                setTimeout(function () {\n                    html.removeClass('nav-before-open');\n                }, this.options.hideDelay);\n            }\n        },\n\n        /**\n         * @param {*} handler\n         * @param {Number} delay\n         * @return {Number}\n         * @private\n         */\n        _delay: function (handler, delay) {\n            var instance = this,\n\n                /**\n                 * @return {*}\n                 */\n                handlerProxy = function () {\n                    return (typeof handler === 'string' ? instance[handler] : handler).apply(instance, arguments);\n                };\n\n            return setTimeout(handlerProxy, delay || 0);\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         */\n        expand: function (event) {\n            var newItem = this.active &&\n                this.active\n                    .children('.ui-menu')\n                    .children('.ui-menu-item')\n                    .first();\n\n            if (newItem && newItem.length) {\n                if (newItem.closest('.ui-menu').is(':visible') &&\n                    newItem.closest('.ui-menu').has('.all-categories')\n                ) {\n                    return;\n                }\n\n                // remove the active state class from the siblings\n                this.active.siblings().children('.ui-state-active').removeClass('ui-state-active');\n\n                this._open(newItem.parent());\n\n                // Delay so Firefox will not hide activedescendant change in expanding submenu from AT\n                this._delay(function () {\n                    this.focus(event, newItem);\n                });\n            }\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         */\n        select: function (event) {\n            var ui;\n\n            this.active = this.active || $(event.target).closest('.ui-menu-item');\n\n            if (this.active.is('.all-category')) {\n                this.active = $(event.target).closest('.ui-menu-item');\n            }\n            ui = {\n                item: this.active\n            };\n\n            if (!this.active.has('.ui-menu').length) {\n                this.collapseAll(event, true);\n            }\n            this._trigger('select', event, ui);\n        }\n    });\n\n    $.widget('mage.navigation', $.mage.menu, {\n        options: {\n            responsiveAction: 'wrap', //option for responsive handling\n            maxItems: null, //option to set max number of menu items\n            container: '#menu', //container to check against navigation length\n            moreText: $.mage.__('more'),\n            breakpoint: 768\n        },\n\n        /**\n         * @private\n         */\n        _init: function () {\n            var that, responsive;\n\n            this._super();\n\n            that = this;\n            responsive = this.options.responsiveAction;\n\n            this.element\n                .addClass('ui-menu-responsive')\n                .attr('responsive', 'main');\n\n            this.setupMoreMenu();\n            this.setMaxItems();\n\n            //check responsive option\n            if (responsive == 'onResize') { //eslint-disable-line eqeqeq\n                $(window).on('resize', function () {\n                    if ($(window).width() > that.options.breakpoint) {\n                        that._responsive();\n                        $('[responsive=more]').show();\n                    } else {\n                        that.element.children().show();\n                        $('[responsive=more]').hide();\n                    }\n                });\n            } else if (responsive == 'onReload') { //eslint-disable-line eqeqeq\n                this._responsive();\n            }\n        },\n\n        /**\n         * Setup more menu.\n         */\n        setupMoreMenu: function () {\n            var moreListItems = this.element.children().clone(),\n                moreLink = $('<a>' + this.options.moreText + '</a>');\n\n            moreListItems.hide();\n\n            moreLink.attr('href', '#');\n\n            this.moreItemsList = $('<ul>')\n                .append(moreListItems);\n\n            this.moreListContainer = $('<li>')\n                .append(moreLink)\n                .append(this.moreItemsList);\n\n            this.responsiveMenu = $('<ul>')\n                .addClass('ui-menu-more')\n                .attr('responsive', 'more')\n                .append(this.moreListContainer)\n                .menu({\n                    position: {\n                        my: 'right top',\n                        at: 'right bottom'\n                    }\n                })\n                .insertAfter(this.element);\n        },\n\n        /**\n         * @private\n         */\n        _responsive: function () {\n            var container = $(this.options.container),\n                containerSize = container.width(),\n                width = 0,\n                items = this.element.children('li'),\n                more = $('.ui-menu-more > li > ul > li a');\n\n            items = items.map(function () {\n                var item = {};\n\n                item.item = $(this);\n                item.itemSize = $(this).outerWidth();\n\n                return item;\n            });\n\n            $.each(items, function (index) {\n                var itemText = items[index].item\n                    .find('a:first')\n                    .text();\n\n                width += parseInt(items[index].itemSize, null); //eslint-disable-line radix\n\n                if (width < containerSize) {\n                    items[index].item.show();\n\n                    more.each(function () {\n                        var text = $(this).text();\n\n                        if (text === itemText) {\n                            $(this).parent().hide();\n                        }\n                    });\n                } else if (width > containerSize) {\n                    items[index].item.hide();\n\n                    more.each(function () {\n                        var text = $(this).text();\n\n                        if (text === itemText) {\n                            $(this).parent().show();\n                        }\n                    });\n                }\n            });\n        },\n\n        /**\n         * Set max items.\n         */\n        setMaxItems: function () {\n            var items = this.element.children('li'),\n                itemsCount = items.length,\n                maxItems = this.options.maxItems,\n                overflow = itemsCount - maxItems,\n                overflowItems = items.slice(overflow);\n\n            overflowItems.hide();\n\n            overflowItems.each(function () {\n                var itemText = $(this).find('a:first').text();\n\n                $(this).hide();\n\n                $('.ui-menu-more > li > ul > li a').each(function () {\n                    var text = $(this).text();\n\n                    if (text === itemText) {\n                        $(this).parent().show();\n                    }\n                });\n            });\n        }\n    });\n\n    return {\n        menu: $.mage.menu,\n        navigation: $.mage.navigation\n    };\n});\n","mage/common.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'domReady!'\n], function ($) {\n    'use strict';\n\n    /* Form with auto submit feature */\n    $('form[data-auto-submit=\"true\"]').trigger('submit');\n\n    //Add form keys.\n    $(document).on(\n        'submit',\n        'form',\n        function (e) {\n            var formKeyElement,\n                existingFormKeyElement,\n                isKeyPresentInForm,\n                isActionExternal,\n                baseUrl = window.BASE_URL,\n                form = $(e.target),\n                formKey = $('input[name=\"form_key\"]').val(),\n                formMethod = form.prop('method'),\n                formAction = form.prop('action');\n\n            isActionExternal = formAction.indexOf(baseUrl) !== 0;\n\n            existingFormKeyElement = form.find('input[name=\"form_key\"]');\n            isKeyPresentInForm = existingFormKeyElement.length;\n\n            /* Verifies that existing auto-added form key is a direct form child element,\n               protection from a case when one form contains another form. */\n            if (isKeyPresentInForm && existingFormKeyElement.attr('auto-added-form-key') === '1') {\n                isKeyPresentInForm = form.find('> input[name=\"form_key\"]').length;\n            }\n\n            if (formKey && !isKeyPresentInForm && !isActionExternal && formMethod !== 'get') {\n                formKeyElement = document.createElement('input');\n                formKeyElement.setAttribute('type', 'hidden');\n                formKeyElement.setAttribute('name', 'form_key');\n                formKeyElement.setAttribute('value', formKey);\n                formKeyElement.setAttribute('auto-added-form-key', '1');\n                form.get(0).appendChild(formKeyElement);\n            }\n        }\n    );\n});\n","mage/edit-trigger.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated since version 2.2.0\n */\ndefine([\n    'jquery',\n    'mage/template',\n    'jquery-ui-modules/widget'\n], function ($, mageTemplate) {\n    'use strict';\n\n    var editTriggerPrototype;\n\n    $.widget('mage.editTrigger', {\n        options: {\n            img: '',\n            alt: '[TR]',\n            template: '#translate-inline-icon',\n            zIndex: 2000,\n            editSelector: '[data-translate]',\n            delay: 2000,\n            offsetTop: -3,\n            singleElement: true\n        },\n\n        /**\n         * editTriger creation\n         * @protected\n         */\n        _create: function () {\n            this.tmpl = mageTemplate(this.options.template);\n            this._initTrigger();\n            this._bind();\n        },\n\n        /**\n         * @return {Object}\n         * @private\n         */\n        _getCss: function () {\n            return {\n                position: 'absolute',\n                cursor: 'pointer',\n                display: 'none',\n                'z-index': this.options.zIndex\n            };\n        },\n\n        /**\n         * @param {*} appendTo\n         * @return {*|jQuery}\n         * @private\n         */\n        _createTrigger: function (appendTo) {\n            var tmpl = this.tmpl({\n                data: this.options\n            });\n\n            return $(tmpl)\n                .css(this._getCss())\n                .data('role', 'edit-trigger-element')\n                .appendTo(appendTo);\n        },\n\n        /**\n         * @private\n         */\n        _initTrigger: function () {\n            this.trigger = this._createTrigger($('body'));\n        },\n\n        /**\n         * Bind on mousemove event\n         * @protected\n         */\n        _bind: function () {\n            this.trigger.on('click.' + this.widgetName, $.proxy(this._onClick, this));\n            this.element.on('mousemove.' + this.widgetName, $.proxy(this._onMouseMove, this));\n        },\n\n        /**\n         * Show editTriger\n         */\n        show: function () {\n            if (this.trigger.is(':hidden')) {\n                this.trigger.show();\n            }\n        },\n\n        /**\n         * Hide editTriger\n         */\n        hide: function () {\n            this.currentTarget = null;\n\n            if (this.trigger && this.trigger.is(':visible')) {\n                this.trigger.hide();\n            }\n        },\n\n        /**\n         * Set editTriger position\n         * @protected\n         */\n        _setPosition: function (el) {\n            var offset = el.offset();\n\n            this.trigger.css({\n                top: offset.top + el.outerHeight() + this.options.offsetTop,\n                left: offset.left\n            });\n        },\n\n        /**\n         * Show/hide trigger on mouse move.\n         *\n         * @param {jQuery.Event} e\n         * @protected\n         */\n        _onMouseMove: function (e) {\n            var target = $(e.target),\n                inner = target.find(this.options.editSelector);\n\n            if ($(e.target).is('button') && inner.length) {\n                target = inner;\n            } else if (!target.is(this.trigger) && !target.is(this.options.editSelector)) {\n                target = target.parents(this.options.editSelector).first();\n            }\n\n            if (target.length) {\n                if (!target.is(this.trigger)) {\n                    this._setPosition(target);\n                    this.currentTarget = target;\n                }\n                this.show();\n            } else {\n                this.hide();\n            }\n        },\n\n        /**\n         * Trigger event \"edit\" on element for translate.\n         *\n         * @param {jQuery.Event} e\n         * @protected\n         */\n        _onClick: function (e) {\n            e.preventDefault();\n            e.stopImmediatePropagation();\n            $(this.currentTarget).trigger('edit.' + this.widgetName);\n            this.hide(true);\n        },\n\n        /**\n         * Destroy editTriger\n         */\n        destroy: function () {\n            this.trigger.remove();\n            this.element.off('.' + this.widgetName);\n\n            return $.Widget.prototype.destroy.call(this);\n        }\n    });\n\n    /**\n     * Extention for widget editTrigger - hide trigger with delay\n     */\n    editTriggerPrototype = $.mage.editTrigger.prototype;\n\n    $.widget('mage.editTrigger', $.extend({}, editTriggerPrototype, {\n        /**\n         * Added clear timeout on trigger show\n         */\n        show: function () {\n            editTriggerPrototype.show.apply(this, arguments);\n\n            if (this.options.delay) {\n                this._clearTimer();\n            }\n        },\n\n        /**\n         * Added setTimeout on trigger hide\n         */\n        hide: function (immediate) {\n            if (!immediate && this.options.delay) {\n                if (!this.timer) {\n                    this.timer = setTimeout($.proxy(function () {\n                        editTriggerPrototype.hide.apply(this, arguments);\n                        this._clearTimer();\n                    }, this), this.options.delay);\n                }\n            } else {\n                editTriggerPrototype.hide.apply(this, arguments);\n            }\n        },\n\n        /**\n         * Clear timer\n         * @protected\n         */\n        _clearTimer: function () {\n            if (this.timer) {\n                clearTimeout(this.timer);\n                this.timer = null;\n            }\n        }\n    }));\n\n    return $.mage.editTrigger;\n});\n","mage/terms.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated since version 2.2.0\n */\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    /**\n     * @param {*} args\n     */\n    $.fn.terms = function (args) {\n\n        // default\n        var defaults = {\n                start: 0,\n                wrapper: '',\n                showAnchor: '',\n                effects: 'slide'\n            },\n            options = $.extend(defaults, args);\n\n        this.each(function () {\n            var obj = $(this),\n                wrapper = options.wrapper !== '' ? '> ' + options.wrapper : '',\n                switches = $(wrapper + '> [data-section=\"title\"] > [data-toggle=\"switch\"]', obj),\n                terms = $(wrapper + '> [data-section=\"content\"]', obj),\n                t = switches.length,\n                marginTop = $(switches[0]).closest('[data-section=\"title\"]').css('position') == 'absolute' ? 0 : null, //eslint-disable-line\n                title,\n                current,\n\n                /**\n                 * @param {*} item\n                 */\n                showItem = function (item) {\n                    if (item != current && !$(switches[item]).closest('[data-section=\"title\"]').hasClass('disabled')) { //eslint-disable-line\n                        $(switches).closest('[data-section=\"title\"]').removeClass('active');\n\n                        if (options.wrapper !== '') {\n                            $(switches).parent().parent().removeClass('active');\n                        }\n                        $(terms).removeClass('active');\n                        $(switches[item]).closest('[data-section=\"title\"]').addClass('active');\n\n                        if (options.wrapper !== '') {\n                            $(switches[current]).parent().parent().addClass('active');\n                        }\n                        $(terms[item]).addClass('active');\n                        current = item;\n                    } else if (\n                        // Check if this is accordion width as criteria for now\n                        (obj.attr('data-sections') == 'accordion' || $(switches[item]).closest('[data-section=\"title\"]').css('width') == obj.css('width')) && //eslint-disable-line\n                        item == current && !$(switches[item]).closest('[data-section=\"title\"]').hasClass('disabled') //eslint-disable-line\n                    ) {\n                        $(switches).closest('[data-section=\"title\"]').removeClass('active');\n\n                        if (options.wrapper !== '') {\n                            $(switches).parent().parent().removeClass('active');\n                        }\n                        $(terms).removeClass('active');\n                        current = -1;\n                    }\n                },\n\n                /**\n                 * Init.\n                 */\n                init = function () {\n                    var linksList, i, classes, dataSection, itemHref, itemClass, fromUrl;\n\n                    if (t > 0) {\n                        if ($(switches[0]).closest('[data-section=\"title\"]').css('display') == 'table-cell') { //eslint-disable-line\n                            obj.addClass('adjusted');\n\n                            if (obj[0].tagName == 'DL') { //eslint-disable-line eqeqeq, max-depth\n                                linksList = $('<dd>');\n                            } else {\n                                linksList = $('<div>');\n                            }\n                            linksList.addClass('sections-nav');\n                            obj.prepend(linksList);\n\n                            for (i = 0; i < t; i++) { //eslint-disable-line max-depth\n                                title = $(switches[i]).html();\n                                classes = $(switches[i]).closest('[data-section=\"title\"]').attr('class');\n                                dataSection = $(switches[i]).closest('[data-section=\"title\"]').attr('data-section');\n                                itemHref = $(switches[i]).attr('href');\n                                itemClass = $(switches[i]).attr('class');\n                                $(switches[i]).parent('[data-section=\"title\"]').hide();\n                                switches[i] = $('<a/>', {\n                                    href: itemHref,\n                                    'class': itemClass,\n                                    html: title\n                                }).appendTo(linksList);\n                                $(switches[i]).wrap(\n                                    '<strong class=\"' + classes + '\" data-section=\"' + dataSection + '\" />'\n                                );\n                            }\n                        }\n                        $(switches).each(function (ind, el) {\n                            $(el).on('click', function (event) {\n                                event.preventDefault();\n                                showItem(ind);\n                            });\n\n                            if (marginTop !== null) {\n                                $(el).closest('[data-section=\"title\"]').css({\n                                    'top': marginTop + 'px'\n                                });\n                                marginTop += $(el).closest('[data-section=\"title\"]').outerHeight(true);\n                                obj.css({\n                                    'min-height': marginTop + 'px'\n                                });\n                            }\n                        });\n\n                        fromUrl = false;\n\n                        if (window.location.hash.length > 0) {\n                            $(terms).each(function (ind, el) {\n                                if ('#info-' + $(el).attr('id') == window.location.hash) { //eslint-disable-line eqeqeq\n                                    showItem(ind);\n                                    $('html, body').animate({\n                                        scrollTop: $(switches[ind]).offset().top\n                                    }, 700);\n                                    fromUrl = true;\n                                }\n                            });\n                        }\n\n                        if (fromUrl === false) {\n                            if (options.start % 1 === 0) { //eslint-disable-line max-depth\n                                current = options.start + 1;\n                                showItem(options.start);\n                            } else {\n                                $(terms).each(function (ind, el) {\n                                    if ($(el).attr('id') == options.start) { //eslint-disable-line eqeqeq\n                                        current = ind + 1;\n                                        showItem(ind);\n                                        $('html, body').animate({\n                                            scrollTop: $(switches[ind]).offset().top\n                                        }, 700);\n                                    }\n                                });\n                            }\n                        }\n                    }\n                };\n\n            init();\n        });\n    };\n\n    return function (data, el) {\n        $(el).terms(data);\n    };\n});\n","mage/translate.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/mage',\n    'mageTranslationDictionary',\n    'underscore'\n], function ($, mage, dictionary, _) {\n    'use strict';\n\n    $.extend(true, $, {\n        mage: {\n            translate: (function () {\n                /**\n                 * Key-value translations storage\n                 * @type {Object}\n                 * @private\n                 */\n                var _data = dictionary;\n\n                return {\n                    /**\n                     * Add new translation (two string parameters) or several translations (object)\n                     */\n                    add: function () {\n                        if (arguments.length > 1) {\n                            _data[arguments[0]] = arguments[1];\n                        } else if (typeof arguments[0] === 'object') {\n                            $.extend(_data, arguments[0]);\n                        }\n                    },\n\n                    /**\n                     * Make a translation with parsing (to handle case when _data represents tuple)\n                     * @param {String} text\n                     * @return {String}\n                     */\n                    translate: function (text) {\n                        return typeof _data[text] !== 'undefined' ? _data[text] : text;\n                    }\n                };\n            }())\n        }\n    });\n    $.mage.__ = $.proxy($.mage.translate.translate, $.mage.translate);\n\n    // Provide i18n wrapper to be used in underscore templates for translation\n    _.extend(_, {\n        /**\n         * Make a translation using $.mage.__\n         *\n         * @param {String} text\n         * @return {String}\n         */\n        i18n: function (text) {\n            return $.mage.__(text);\n        }\n    });\n\n    return $.mage.__;\n});\n","mage/template.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore'\n], function (_) {\n    'use strict';\n\n    /**\n     * Checks if provided string is a valid DOM selector.\n     *\n     * @param {String} selector - Selector to be checked.\n     * @returns {Boolean}\n     */\n    function isSelector(selector) {\n        try {\n            document.querySelector(selector);\n\n            return true;\n        } catch (e) {\n            return false;\n        }\n    }\n\n    /**\n     * Unescapes characters used in underscore templates.\n     *\n     * @param {String} str - String to be processed.\n     * @returns {String}\n     */\n    function unescape(str) {\n        return str.replace(/&lt;%|%3C%/g, '<%').replace(/%&gt;|%%3E/g, '%>');\n    }\n\n    /**\n     * If 'tmpl' is a valid selector, returns target node's innerHTML if found.\n     * Else, returns empty string and emits console warning.\n     * If 'tmpl' is not a selector, returns 'tmpl' as is.\n     *\n     * @param {String} tmpl\n     * @returns {String}\n     */\n    function getTmplString(tmpl) {\n        if (isSelector(tmpl)) {\n            tmpl = document.querySelector(tmpl);\n\n            if (tmpl) {\n                tmpl = tmpl.innerHTML.trim();\n            } else {\n                console.warn('No template was found by selector: ' + tmpl);\n\n                tmpl = '';\n            }\n        }\n\n        return unescape(tmpl);\n    }\n\n    /**\n     * Compiles or renders template provided either\n     * by selector or by the template string.\n     *\n     * @param {String} tmpl - Template string or selector.\n     * @param {(Object|Array|Function)} [data] - Data object with which to render template.\n     * @returns {String|Function}\n     */\n    return function (tmpl, data) {\n        var render;\n\n        tmpl   = getTmplString(tmpl);\n        render = _.template(tmpl);\n\n        return !_.isUndefined(data) ?\n            render(data) :\n            render;\n    };\n});\n","mage/multiselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'jquery',\n    'text!mage/multiselect.html',\n    'Magento_Ui/js/modal/alert',\n    'jquery-ui-modules/widget',\n    'jquery/editableMultiselect/js/jquery.multiselect'\n], function (_, $, searchTemplate, alert) {\n    'use strict';\n\n    $.widget('mage.multiselect2', {\n        options: {\n            mselectContainer: 'section.mselect-list',\n            mselectItemsWrapperClass: 'mselect-items-wrapper',\n            mselectCheckedClass: 'mselect-checked',\n            containerClass: 'paginated',\n            searchInputClass: 'admin__action-multiselect-search',\n            selectedItemsCountClass: 'admin__action-multiselect-items-selected',\n            currentPage: 1,\n            lastAppendValue: 0,\n            updateDelay: 1000,\n            optionsLoaded: false\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            $.fn.multiselect.call(this.element, this.options);\n        },\n\n        /** @inheritdoc */\n        _init: function () {\n            this.domElement = this.element.get(0);\n\n            this.$container = $(this.options.mselectContainer);\n            this.$wrapper = this.$container.find('.' + this.options.mselectItemsWrapperClass);\n            this.$item = this.$wrapper.find('div').first();\n            this.selectedValues = [];\n            this.values = {};\n\n            this.$container.addClass(this.options.containerClass).prepend(searchTemplate);\n            this.$input = this.$container.find('.' + this.options.searchInputClass);\n            this.$selectedCounter = this.$container.find('.' + this.options.selectedItemsCountClass);\n            this.filter = '';\n\n            if (this.domElement.options.length) {\n                this._setLastAppendOption(this.domElement.options[this.domElement.options.length - 1].value);\n            }\n\n            this._initElement();\n            this._events();\n        },\n\n        /**\n         * Leave only saved/selected options in select element.\n         *\n         * @private\n         */\n        _initElement: function () {\n            this.element.empty();\n            _.each(this.options.selectedValues, function (value) {\n                this._createSelectedOption({\n                    value: value,\n                    label: value\n                });\n            }, this);\n        },\n\n        /**\n         * Attach required events.\n         *\n         * @private\n         */\n        _events: function () {\n            var onKeyUp = _.debounce(this.onKeyUp, this.options.updateDelay);\n\n            _.bindAll(this, 'onScroll', 'onCheck', 'onOptionsChange');\n\n            this.$wrapper.on('scroll', this.onScroll);\n            this.$wrapper.on('change.mselectCheck', '[type=checkbox]', this.onCheck);\n            this.$input.on('keyup', _.bind(onKeyUp, this));\n            this.element.on('change.hiddenSelect', this.onOptionsChange);\n        },\n\n        /**\n         * Behaves multiselect scroll.\n         */\n        onScroll: function () {\n            var height = this.$wrapper.height(),\n                scrollHeight = this.$wrapper.prop('scrollHeight'),\n                scrollTop = Math.ceil(this.$wrapper.prop('scrollTop'));\n\n            if (!this.options.optionsLoaded && scrollHeight - height <= scrollTop) {\n                this.loadOptions();\n            }\n        },\n\n        /**\n         * Behaves keyup event on input search\n         */\n        onKeyUp: function () {\n            if (this.getSearchCriteria() === this.filter) {\n                return false;\n            }\n\n            this.setFilter();\n            this.clearMultiselectOptions();\n            this.setCurrentPage(0);\n            this.loadOptions();\n        },\n\n        /**\n         * Callback for select change event\n         */\n        onOptionsChange: function () {\n            this.selectedValues = _.map(this.domElement.options, function (option) {\n                this.values[option.value] = true;\n\n                return option.value;\n            }, this);\n\n            this._updateSelectedCounter();\n        },\n\n        /**\n         * Overrides native check behaviour.\n         *\n         * @param {Event} event\n         */\n        onCheck: function (event) {\n            var checkbox = event.target,\n                option = {\n                    value: checkbox.value,\n                    label: $(checkbox).parent('label').text()\n                };\n\n            checkbox.checked ? this._createSelectedOption(option) : this._removeSelectedOption(option);\n            event.stopPropagation();\n        },\n\n        /**\n         * Show error message.\n         *\n         * @param {String} message\n         */\n        onError: function (message) {\n            alert({\n                content: message\n            });\n        },\n\n        /**\n         * Updates current filter state.\n         */\n        setFilter: function () {\n            this.filter = this.getSearchCriteria() || '';\n        },\n\n        /**\n         * Reads search input value.\n         *\n         * @return {String}\n         */\n        getSearchCriteria: function () {\n            return this.$input.val().trim();\n        },\n\n        /**\n         * Load options data.\n         */\n        loadOptions: function () {\n            var nextPage = this.getCurrentPage() + 1;\n\n            this.$wrapper.trigger('processStart');\n            this.$input.prop('disabled', true);\n\n            $.get(this.options.nextPageUrl, {\n                p: nextPage,\n                s: this.filter\n            })\n            .done(function (response) {\n                if (response.success) {\n                    this.appendOptions(response.result);\n                    this.setCurrentPage(nextPage);\n                } else {\n                    this.onError(response.errorMessage);\n                }\n            }.bind(this))\n            .always(function () {\n                this.$wrapper.trigger('processStop');\n                this.$input.prop('disabled', false);\n\n                if (this.filter) {\n                    this.$input.focus();\n                }\n            }.bind(this));\n        },\n\n        /**\n         * Append loaded options\n         *\n         * @param {Array} options\n         */\n        appendOptions: function (options) {\n            var divOptions = [];\n\n            if (!options.length) {\n                return false;\n            }\n\n            if (this.isOptionsLoaded(options)) {\n                return;\n            }\n\n            options.forEach(function (option) {\n                if (!this.values[option.value]) {\n                    this.values[option.value] = true;\n                    option.selected = this._isOptionSelected(option);\n                    divOptions.push(this._createMultiSelectOption(option));\n                    this._setLastAppendOption(option.value);\n                }\n            }, this);\n\n            this.$wrapper.append(divOptions);\n        },\n\n        /**\n         * Clear multiselect options\n         */\n        clearMultiselectOptions: function () {\n            this._setLastAppendOption(0);\n            this.values = {};\n            this.$wrapper.empty();\n        },\n\n        /**\n         * Checks if all options are already loaded\n         *\n         * @return {Boolean}\n         */\n        isOptionsLoaded: function (options) {\n            this.options.optionsLoaded = this.options.lastAppendValue === options[options.length - 1].value;\n\n            return this.options.optionsLoaded;\n        },\n\n        /**\n         * Setter for current page.\n         *\n         * @param {Number} page\n         */\n        setCurrentPage: function (page) {\n            this.options.currentPage = page;\n        },\n\n        /**\n         * Getter for current page.\n         *\n         * @return {Number}\n         */\n        getCurrentPage: function () {\n            return this.options.currentPage;\n        },\n\n        /**\n         * Creates new selected option for select element\n         *\n         * @param {Object} option - option object\n         * @param {String} option.value - option value\n         * @param {String} option.label - option label\n         * @private\n         */\n        _createSelectedOption: function (option) {\n            var selectOption = new Option(option.label, option.value, false, true);\n\n            this.element.append(selectOption);\n            this.selectedValues.push(option.value);\n            this._updateSelectedCounter();\n\n            return selectOption;\n        },\n\n        /**\n         * Remove passed option from select element\n         *\n         * @param {Object} option - option object\n         * @param {String} option.value - option value\n         * @param {String} option.label - option label\n         * @return {Object} option\n         * @private\n         */\n        _removeSelectedOption: function (option) {\n            var unselectedOption = _.findWhere(this.domElement.options, {\n                value: option.value\n            });\n\n            if (!_.isUndefined(unselectedOption)) {\n                this.domElement.remove(unselectedOption.index);\n                this.selectedValues.splice(_.indexOf(this.selectedValues, option.value), 1);\n                this._updateSelectedCounter();\n            }\n\n            return unselectedOption;\n        },\n\n        /**\n         * Creates new DIV option for multiselect widget\n         *\n         * @param {Object} option - option object\n         * @param {String} option.value - option value\n         * @param {String} option.label - option label\n         * @param {Boolean} option.selected - is option selected\n         * @private\n         */\n        _createMultiSelectOption: function (option) {\n            var item = this.$item.clone(),\n                checkbox = item.find('input'),\n                isSelected = !!option.selected;\n\n            checkbox.val(option.value)\n                .prop('checked', isSelected)\n                .toggleClass(this.options.mselectCheckedClass, isSelected);\n\n            item.find('label > span').text(option.label);\n\n            return item;\n        },\n\n        /**\n         * Checks if passed option should be selected\n         *\n         * @param {Object} option - option object\n         * @param {String} option.value - option value\n         * @param {String} option.label - option label\n         * @param {Boolean} option.selected - is option selected\n         * @return {Boolean}\n         * @private\n         */\n        _isOptionSelected: function (option) {\n            return !!~this.selectedValues.indexOf(option.value);\n        },\n\n        /**\n         * Saves last added option value.\n         *\n         * @param {Number} value\n         * @private\n         */\n        _setLastAppendOption: function (value) {\n            this.options.lastAppendValue = value;\n        },\n\n        /**\n         * Updates counter of selected items.\n         *\n         * @private\n         */\n        _updateSelectedCounter: function () {\n            this.$selectedCounter.text(this.selectedValues.length);\n        }\n    });\n\n    return $.mage.multiselect2;\n});\n","mage/dataPost.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/template',\n    'Magento_Ui/js/modal/confirm',\n    'jquery-ui-modules/widget'\n], function ($, mageTemplate, uiConfirm) {\n    'use strict';\n\n    $.widget('mage.dataPost', {\n        options: {\n            formTemplate: '<form action=\"<%- data.action %>\" method=\"post\">' +\n            '<% _.each(data.data, function(value, index) { %>' +\n            '<input name=\"<%- index %>\" value=\"<%- value %>\">' +\n            '<% }) %></form>',\n            postTrigger: ['a[data-post]', 'button[data-post]', 'span[data-post]'],\n            formKeyInputSelector: 'input[name=\"form_key\"]'\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            this._bind();\n        },\n\n        /** @inheritdoc */\n        _bind: function () {\n            var events = {};\n\n            $.each(this.options.postTrigger, function (index, value) {\n                events['click ' + value] = '_postDataAction';\n            });\n\n            this._on(events);\n        },\n\n        /**\n         * Handler for click.\n         *\n         * @param {Object} e\n         * @private\n         */\n        _postDataAction: function (e) {\n            var params = $(e.currentTarget).data('post');\n\n            e.preventDefault();\n            this.postData(params);\n        },\n\n        /**\n         * Data post action.\n         *\n         * @param {Object} params\n         */\n        postData: function (params) {\n            var formKey = $(this.options.formKeyInputSelector).val(),\n                $form, input;\n\n            if (formKey) {\n                params.data['form_key'] = formKey;\n            }\n\n            $form = $(mageTemplate(this.options.formTemplate, {\n                data: params\n            }));\n\n            if (params.files) {\n                $form[0].enctype = 'multipart/form-data';\n                $.each(params.files, function (key, files) {\n                    if (files instanceof FileList) {\n                        input = document.createElement('input');\n                        input.type = 'file';\n                        input.name = key;\n                        input.files = files;\n                        $form[0].appendChild(input);\n                    }\n                });\n            }\n\n            if (params.data.confirmation) {\n                uiConfirm({\n                    content: params.data.confirmationMessage,\n                    actions: {\n                        /** @inheritdoc */\n                        confirm: function () {\n                            $form.appendTo('body').hide().trigger('submit');\n                        }\n                    }\n                });\n            } else {\n                $form.appendTo('body').hide().trigger('submit');\n            }\n        }\n    });\n\n    $(document).dataPost();\n\n    return $.mage.dataPost;\n});\n","mage/tooltip.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated since version 2.2.0\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/tooltip'\n], function ($) {\n    'use strict';\n\n    //Widget Wrapper\n    $.widget('mage.tooltip', $.ui.tooltip, {});\n\n    return $.mage.tooltip;\n});\n","mage/url.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable strict */\ndefine([], function () {\n    var baseUrl = '';\n\n    return {\n        /**\n         * @param {String} url\n         */\n        setBaseUrl: function (url) {\n            baseUrl = url;\n        },\n\n        /**\n         * @param {String} path\n         * @return {*}\n         */\n        build: function (path) {\n            if (path.indexOf(baseUrl) !== -1) {\n                return path;\n            }\n\n            return baseUrl + path;\n        }\n    };\n});\n","mage/sticky.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.sticky', {\n        options: {\n            /**\n             * Element selector, who's height will be used to restrict the\n             * maximum offsetTop position of the stuck element.\n             * Default uses document body.\n             * @type {String}\n             */\n            container: '',\n\n            /**\n             * Spacing in pixels above the stuck element\n             * @type {Number|Function} Number or Function that will return a Number\n             */\n            spacingTop: 0,\n\n            /**\n             * Allows postponing sticking, until element will go out of the\n             * screen for the number of pixels.\n             * @type {Number|Function} Number or Function that will return a Number\n             */\n            stickAfter: 0,\n\n            /**\n             * CSS class for active sticky state\n             * @type {String}\n             */\n            stickyClass: '_sticky'\n        },\n\n        /**\n         * Retrieve option value\n         * @param  {String} option\n         * @return {*}\n         * @private\n         */\n        _getOptionValue: function (option) {\n            var value = this.options[option] || 0;\n\n            if (typeof value === 'function') {\n                value = this.options[option]();\n            }\n\n            return value;\n        },\n\n        /**\n         * Bind handlers to scroll event\n         * @private\n         */\n        _create: function () {\n            $(window).on({\n                'scroll': $.proxy(this._stick, this),\n                'resize': $.proxy(this.reset, this)\n            });\n\n            this.element.on('dimensionsChanged', $.proxy(this.reset, this));\n\n            this.reset();\n\n            // Application of the workaround for IE11 and Edge\n            this.normalizeIE11AndEdgeScroll();\n        },\n\n        /**\n         * float Block on windowScroll\n         * @private\n         */\n        _stick: function () {\n            var offset,\n                isStatic,\n                stuck,\n                stickAfter;\n\n            isStatic = this.element.css('position') === 'static';\n\n            if (!isStatic && this.element.is(':visible')) {\n                offset = $(document).scrollTop() -\n                    this.parentOffset +\n                    this._getOptionValue('spacingTop');\n\n                offset = Math.max(0, Math.min(offset, this.maxOffset));\n\n                stuck = this.element.hasClass(this.options.stickyClass);\n                stickAfter = this._getOptionValue('stickAfter');\n\n                if (offset && !stuck && offset < stickAfter) {\n                    offset = 0;\n                }\n\n                this.element\n                    .toggleClass(this.options.stickyClass, offset > 0)\n                    .css('top', offset);\n            }\n        },\n\n        /**\n         * Defines maximum offset value of the element.\n         * @private\n         */\n        _calculateDimens: function () {\n            var $parent         = this.element.parent(),\n                topMargin       = parseInt(this.element.css('margin-top'), 10),\n                parentHeight    = $parent.height() - topMargin,\n                height          = this.element.innerHeight(),\n                maxScroll       = document.body.offsetHeight - window.innerHeight;\n\n            if (this.options.container.length > 0) {\n                maxScroll = $(this.options.container).height();\n            }\n\n            this.parentOffset   = $parent.offset().top + topMargin;\n            this.maxOffset      = maxScroll - this.parentOffset;\n\n            if (this.maxOffset + height >= parentHeight) {\n                this.maxOffset = parentHeight - height;\n            }\n\n            return this;\n        },\n\n        /**\n         * Facade method that places sticky element where it should be.\n         */\n        reset: function () {\n            this._calculateDimens()\n                ._stick();\n        },\n\n        /**\n         * Workaround for IE11 and Edge that solves the IE known rendering issue\n         * that prevents sticky element from jumpy movement on scrolling the page.\n         *\n         * Alternatively, undesired jumpy movement can be eliminated by changing the setting in IE:\n         * Settings > Internet options > Advanced tab > inside 'Browsing' item > set 'Use smooth scrolling' to False\n         */\n        normalizeIE11AndEdgeScroll: function () {\n            if (navigator.userAgent.match(/Trident.*rv[ :]*11\\.|Edge\\//)) {\n                document.body.addEventListener('mousewheel', function () {\n                    event.preventDefault();\n                    window.scrollTo(0, window.pageYOffset - event.wheelDelta);\n                });\n            }\n        }\n    });\n\n    return $.mage.sticky;\n});\n","mage/decorate.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable strict */\ndefine([\n    'jquery',\n    'mage/translate'\n], function ($) {\n    var methods = {\n        /**\n         * Decorate a list (e.g. a <ul> containing <li>) recursively if specified.\n         * @param {Boolean} isRecursive\n         */\n        list: function (isRecursive) {\n            return this.each(function () {\n                var list = $(this),\n                    items;\n\n                if (list.length > 0) {\n                    items = typeof isRecursive === 'undefined' || isRecursive ?\n                        list.find('li') :\n                        list.children();\n                    items.decorate('generic', ['odd', 'even', 'last']);\n                }\n            });\n        },\n\n        /**\n         * Annotate a set of DOM elements with decorator classes.\n         * @param {Array} decoratorParams\n         */\n        generic: function (decoratorParams) {\n            var elements = $(this),\n                allSupportedParams;\n\n            if (elements) {\n                allSupportedParams = {\n                    even: 'odd', // Flip jQuery odd/even so that index 0 is odd.\n                    odd: 'even',\n                    last: 'last',\n                    first: 'first'\n                };\n\n                decoratorParams = decoratorParams || allSupportedParams;\n\n                $.each(decoratorParams, function (index, param) {\n                    if (param === 'even' || param === 'odd') {\n                        elements.filter(':' + param).removeClass('odd even').addClass(allSupportedParams[param]);\n                    } else {\n                        elements.filter(':' + param).addClass(allSupportedParams[param]);\n                    }\n                });\n            }\n\n            return this;\n        },\n\n        /**\n         * Decorate DOM elements in an HTML table with specified classes.\n         * @param {Object} instanceOptions\n         */\n        table: function (instanceOptions) {\n            return this.each(function () {\n                var table = $(this),\n                    options;\n\n                if (table.length > 0) {\n                    options = {\n                        'tbody': false,\n                        'tbody tr': ['odd', 'even', 'first', 'last'],\n                        'thead tr': ['first', 'last'],\n                        'tfoot tr': ['first', 'last'],\n                        'tr td': ['last']\n                    };\n\n                    $.extend(options, instanceOptions || {});\n\n                    $.each(options, function (key, value) {\n                        if (options[key]) {\n                            if (key === 'tr td') {\n                                $.each(table.find('tr'), function () {\n                                    $(this).find('td').decorate('generic', options['tr td']);\n                                });\n                            } else {\n                                table.find(key).decorate('generic', value);\n                            }\n                        }\n                    });\n                }\n            });\n        },\n\n        /**\n         * Annotate data list elements with CSS classes.\n         */\n        dataList: function () {\n            return this.each(function () {\n                var list = $(this);\n\n                if (list) {\n                    list.find('dt').decorate('generic', ['odd', 'even', 'last']);\n                    list.find('dd').decorate('generic', ['odd', 'even', 'last']);\n                }\n            });\n        }\n    };\n\n    /**\n     * @param {String} method\n     * @return {*}\n     */\n    $.fn.decorate = function (method) {\n        var message;\n\n        if (methods[method]) {\n            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));\n        } else if (typeof method === 'object' || !method) {\n            return methods.init.apply(this, arguments);\n        }\n\n        message = $.mage.__('Method %s does not exist on jQuery.decorate');\n        // eslint-disable-next-line jquery-no-event-shorthand\n        $.error(message.replace('%s', method));\n    };\n});\n","mage/dropdowns.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    /**\n     * @param {Object} options\n     */\n    $.fn.dropdown = function (options) {\n        var defaults = {\n                parent: null,\n                autoclose: true,\n                btnArrow: '.arrow',\n                menu: '[data-target=\"dropdown\"]',\n                activeClass: 'active'\n            },\n            actionElem = $(this),\n            self = this;\n\n        options = $.extend(defaults, options);\n        actionElem = $(this);\n        self = this;\n\n        /**\n         * @param {HTMLElement} elem\n         */\n        this.openDropdown = function (elem) {\n            elem\n                .addClass(options.activeClass)\n                .attr('aria-expanded', true)\n                .parent()\n                    .addClass(options.activeClass);\n\n            elem.parent()\n                .find(options.menu)\n                .attr('aria-hidden', false);\n\n            $(options.btnArrow, elem).text('-');\n        };\n\n        /**\n         * @param {HTMLElement} elem\n         */\n        this.closeDropdown = function (elem) {\n            elem.removeClass(options.activeClass)\n                .attr('aria-expanded', false)\n                .parent()\n                    .removeClass(options.activeClass);\n\n            elem.parent()\n                .find(options.menu)\n                .attr('aria-hidden', true);\n\n            $(options.btnArrow, elem).text('+');\n        };\n\n        /**\n         * Reset all dropdowns.\n         *\n         * @param {Object} param\n         */\n        this.reset = function (param) {\n            var params = param || {},\n                dropdowns = params.elems || actionElem;\n\n            dropdowns.each(function (index, elem) {\n                self.closeDropdown($(elem));\n            });\n        };\n\n        /* document Event bindings */\n        if (options.autoclose === true) {\n            $(document).on('click.hideDropdown', this.reset);\n            $(document).on('keyup.hideDropdown', function (e) {\n                var ESC_CODE = '27';\n\n                if (e.keyCode == ESC_CODE) { //eslint-disable-line eqeqeq\n                    self.reset();\n                }\n            });\n        }\n\n        if (options.events) {\n            $.each(options.events, function (index, event) {\n                $(document).on(event.name, event.selector, event.action);\n            });\n        }\n\n        return this.each(function () {\n            var elem = $(this),\n                parent = $(options.parent).length > 0 ? $(options.parent) : elem.parent(),\n                menu = $(options.menu, parent) || $('.dropdown-menu', parent);\n\n            // ARIA (adding aria attributes)\n            if (menu.length) {\n                elem.attr('aria-haspopup', true);\n            }\n\n            if (!elem.hasClass(options.activeClass)) {\n                elem.attr('aria-expanded', false);\n                menu.attr('aria-hidden', true);\n            } else {\n                elem.attr('aria-expanded', true);\n                menu.attr('aria-hidden', false);\n            }\n\n            if (!elem.is('a, button')) {\n                elem.attr('role', 'button');\n                elem.attr('tabindex', 0);\n            }\n\n            if (elem.attr('data-trigger-keypress-button')) {\n                elem.on('keypress', function (e) {\n                    var keyCode = e.keyCode || e.which,\n                        ENTER_CODE = 13;\n\n                    if (keyCode === ENTER_CODE) {\n                        e.preventDefault();\n                        elem.trigger('click.toggleDropdown');\n                    }\n                });\n            }\n\n            elem.on('click.toggleDropdown', function () {\n                var el = actionElem;\n\n                if (options.autoclose === true) {\n                    actionElem = $();\n                    $(document).trigger('click.hideDropdown');\n                    actionElem = el;\n                }\n\n                self[el.hasClass(options.activeClass) ? 'closeDropdown' : 'openDropdown'](elem);\n\n                return false;\n            });\n        });\n    };\n\n    return function (data, el) {\n        $(el).dropdown(data);\n    };\n});\n","mage/dropdown.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/dialog',\n    'mage/translate'\n], function ($) {\n    'use strict';\n\n    var timer = null;\n\n    /**\n     * Dropdown Widget - this widget is a wrapper for the jQuery UI Dialog\n     */\n    $.widget('mage.dropdownDialog', $.ui.dialog, {\n        options: {\n            triggerEvent: 'click',\n            triggerClass: null,\n            parentClass: null,\n            triggerTarget: null,\n            defaultDialogClass: 'mage-dropdown-dialog',\n            dialogContentClass: null,\n            shadowHinter: null,\n            closeOnMouseLeave: true,\n            closeOnClickOutside: true,\n            minHeight: null,\n            minWidth: null,\n            width: null,\n            modal: false,\n            timeout: null,\n            autoOpen: false,\n            createTitleBar: false,\n            autoPosition: false,\n            autoSize: false,\n            draggable: false,\n            resizable: false,\n            bodyClass: '',\n            buttons: [\n                {\n                    'class': 'action close',\n                    'text': $.mage.__('Close'),\n\n                    /**\n                     * Click action.\n                     */\n                    'click': function () {\n                        $(this).dropdownDialog('close');\n                    }\n                }\n            ]\n        },\n\n        /**\n         * extend default functionality to bind the opener for dropdown\n         * @private\n         */\n        _create: function () {\n            var _self = this;\n\n            this._super();\n            this.uiDialog.addClass(this.options.defaultDialogClass);\n\n            if (_self.options.triggerTarget) {\n                $(_self.options.triggerTarget).on(_self.options.triggerEvent, function (event) {\n                    event.preventDefault();\n                    event.stopPropagation();\n\n                    if (!_self._isOpen) {\n                        $('.' + _self.options.defaultDialogClass + ' > .ui-dialog-content').dropdownDialog('close');\n                        _self.open();\n                    } else {\n                        _self.close(event);\n                    }\n                });\n            }\n\n            if (_self.options.shadowHinter) {\n                _self.hinter = $('<div class=\"' + _self.options.shadowHinter + '\"></div>');\n                _self.element.append(_self.hinter);\n            }\n        },\n\n        /**\n         * Extend default functionality to close the dropdown\n         * with custom delay on mouse out and also to close when clicking outside\n         */\n        open: function () {\n            var _self = this;\n\n            this._super();\n\n            if (_self.options.dialogContentClass) {\n                _self.element.addClass(_self.options.dialogContentClass);\n            }\n\n            if (_self.options.closeOnMouseLeave) {\n\n                this._mouseEnter(_self.uiDialog);\n                this._mouseLeave(_self.uiDialog);\n\n                if (_self.options.triggerTarget) {\n                    this._mouseLeave($(_self.options.triggerTarget));\n                }\n            }\n\n            if (_self.options.closeOnClickOutside) {\n                $('body').on('click.outsideDropdown', function (event) {\n                    if (_self._isOpen && !$(event.target).closest('.ui-dialog').length) {\n                        if (timer) {\n                            clearTimeout(timer);\n                        }\n                        _self.close(event);\n                    }\n                });\n            }\n            // adding the class on the opener and parent element for dropdown\n            if (_self.options.triggerClass) {\n                $(_self.options.triggerTarget).addClass(_self.options.triggerClass);\n            }\n\n            if (_self.options.parentClass) {\n                $(_self.options.appendTo).addClass(_self.options.parentClass);\n            }\n\n            if (_self.options.bodyClass) {\n                $('body').addClass(_self.options.bodyClass);\n            }\n\n            if (_self.options.shadowHinter) {\n                _self._setShadowHinterPosition();\n            }\n        },\n\n        /**\n         * extend default functionality to reset the timer and remove the active class for opener\n         */\n        close: function () {\n            this._super();\n\n            if (this.options.dialogContentClass) {\n                this.element.removeClass(this.options.dialogContentClass);\n            }\n\n            if (this.options.triggerClass) {\n                $(this.options.triggerTarget).removeClass(this.options.triggerClass);\n            }\n\n            if (this.options.parentClass) {\n                $(this.options.appendTo).removeClass(this.options.parentClass);\n            }\n\n            if (this.options.bodyClass) {\n                $('body').removeClass(this.options.bodyClass);\n            }\n\n            if (timer) {\n                clearTimeout(timer);\n            }\n\n            if (this.options.triggerTarget) {\n                $(this.options.triggerTarget).off('mouseleave');\n            }\n            this.uiDialog.off('mouseenter');\n            this.uiDialog.off('mouseleave');\n            $('body').off('click.outsideDropdown');\n        },\n\n        /**\n         * _setShadowHinterPosition\n         * @private\n         */\n        _setShadowHinterPosition: function () {\n            var _self = this,\n                offset;\n\n            offset = _self.options.position.of.offset().left -\n                _self.element.offset().left +\n                _self.options.position.of.outerWidth() / 2;\n            offset = isNaN(offset) ? 0 : Math.floor(offset);\n            _self.hinter.css('left', offset);\n        },\n\n        /**\n         * @private\n         */\n        _position: function () {\n            if (this.options.autoPosition) {\n                this._super();\n            }\n        },\n\n        /**\n         * @private\n         */\n        _createTitlebar: function () {\n            if (this.options.createTitleBar) {\n                this._super();\n            } else {\n                // the title bar close button is referenced\n                // in _focusTabbable function, so to prevent errors it must be declared\n                this.uiDialogTitlebarClose = $('<div></div>');\n            }\n        },\n\n        /**\n         * @private\n         */\n        _size: function () {\n            if (this.options.autoSize) {\n                this._super();\n            }\n        },\n\n        /**\n         * @param {Object} handler\n         * @private\n         */\n        _mouseLeave: function (handler) {\n            var _self = this;\n\n            handler.on('mouseleave', function (event) {\n                event.stopPropagation();\n\n                if (_self._isOpen) {\n                    if (timer) {\n                        clearTimeout(timer);\n                    }\n                    timer = setTimeout(function (e) {\n                        _self.close(e);\n                    }, _self.options.timeout);\n                }\n            });\n        },\n\n        /**\n         * @param {Object} handler\n         * @private\n         */\n        _mouseEnter: function (handler) {\n            handler.on('mouseenter', function (event) {\n                event.stopPropagation();\n\n                if (timer) {\n                    clearTimeout(timer);\n                }\n            });\n        },\n\n        /**\n         * @param {String} key\n         * @param {*} value\n         * @private\n         */\n        _setOption: function (key, value) {\n            this._super(key, value);\n\n            if (key === 'triggerTarget') {\n                this.options.triggerTarget = value;\n            }\n        }\n    });\n\n    return $.mage.dropdownDialog;\n});\n","mage/mage.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/apply/main'\n], function ($, mage) {\n    'use strict';\n\n    /**\n     * Main namespace for Magento extensions\n     * @type {Object}\n     */\n    $.mage = $.mage || {};\n\n    /**\n     * Plugin mage, initialize components on elements\n     * @param {String} name - Components' path.\n     * @param {Object} config - Components' config.\n     * @returns {JQuery} Chainable.\n     */\n    $.fn.mage = function (name, config) {\n        config = config || {};\n\n        this.each(function (index, el) {\n            mage.applyFor(el, config, name);\n        });\n\n        return this;\n    };\n\n    $.extend($.mage, {\n        /**\n         * Handle all components declared via data attribute\n         * @return {Object} $.mage\n         */\n        init: function () {\n            mage.apply();\n\n            return this;\n        },\n\n        /**\n         * Method handling redirects and page refresh\n         * @param {String} url - redirect URL\n         * @param {(undefined|String)} type - 'assign', 'reload', 'replace'\n         * @param {(undefined|Number)} timeout - timeout in milliseconds before processing the redirect or reload\n         * @param {(undefined|Boolean)} forced - true|false used for 'reload' only\n         */\n        redirect: function (url, type, timeout, forced) {\n            var _redirect;\n\n            forced  = !!forced;\n            timeout = timeout || 0;\n            type    = type || 'assign';\n\n            /**\n             * @private\n             */\n            _redirect = function () {\n                window.location[type](type === 'reload' ? forced : url);\n            };\n\n            timeout ? setTimeout(_redirect, timeout) : _redirect();\n        },\n\n        /**\n         * Checks if provided string is a valid selector.\n         * @param {String} selector - Selector to check.\n         * @returns {Boolean}\n         */\n        isValidSelector: function (selector) {\n            try {\n                document.querySelector(selector);\n\n                return true;\n            } catch (e) {\n                return false;\n            }\n        }\n    });\n\n    /**\n     * Init components inside of dynamically updated elements\n     */\n    $(document).on('contentUpdated', 'body', function () {\n        if (mage) {\n            mage.apply();\n        }\n    });\n\n    return $.mage;\n});\n","mage/validation/validation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/validation',\n    'mage/translate'\n], function ($) {\n    'use strict';\n\n    $.each({\n        'validate-grouped-qty': [\n            function (value, element, params) {\n                var result = false,\n                    total = 0;\n\n                $(params).find('input[data-validate*=\"validate-grouped-qty\"]').each(function (i, e) {\n                    var val = $(e).val(),\n                        valInt;\n\n                    if (val && val.length > 0) {\n                        result = true;\n                        valInt = parseFloat(val) || 0;\n\n                        if (valInt >= 0) {\n                            total += valInt;\n                        } else {\n                            result = false;\n\n                            return result;\n                        }\n                    }\n                });\n\n                return result && total > 0;\n            },\n            $.mage.__('Please specify the quantity of product(s).')\n        ],\n        'validate-one-checkbox-required-by-name': [\n            function (value, element, params) {\n                var checkedCount = 0,\n                    container;\n\n                if (element.type === 'checkbox') {\n                    $('[name=\"' + element.name + '\"]').each(\n                        function () {\n                            if ($(this).is(':checked')) {\n                                checkedCount += 1;\n\n                                return false;\n                            }\n                        }\n                    );\n                }\n                container = '#' + params;\n\n                if (checkedCount > 0) {\n                    $(container).removeClass('validation-failed');\n                    $(container).addClass('validation-passed');\n\n                    return true;\n                }\n                $(container).addClass('validation-failed');\n                $(container).removeClass('validation-passed');\n\n                return false;\n            },\n            $.mage.__('Please select one of the options.')\n        ],\n        'validate-date-between': [\n            function (value, element, params) {\n                var minDate = new Date(params[0]),\n                    maxDate = new Date(params[1]),\n                    inputDate = new Date(element.value),\n                    message;\n\n                minDate.setHours(0);\n                maxDate.setHours(0);\n\n                if (inputDate >= minDate && inputDate <= maxDate) {\n                    return true;\n                }\n                message = $.mage.__('Please enter a date between %min and %max.');\n                this.dateBetweenErrorMessage = message.replace('%min', minDate).replace('%max', maxDate);\n\n                return false;\n            },\n            function () {\n                return this.dateBetweenErrorMessage;\n            }\n        ],\n        'validate-dob': [\n            function (val, element, params) {\n                var dob = $(element).parents('.customer-dob'),\n                    dayVal, monthVal, yearVal, dobLength, day, month, year, curYear,\n                    validYearMessage, validateDayInMonth, validDateMessage, today, dateEntered;\n\n                $(dob).find('.' + this.settings.errorClass).removeClass(this.settings.errorClass);\n                dayVal = $(dob).find(params[0]).find('input:text').val();\n                monthVal = $(dob).find(params[1]).find('input:text').val();\n                yearVal = $(dob).find(params[2]).find('input:text').val();\n                dobLength = dayVal.length + monthVal.length + yearVal.length;\n\n                if (params[3] && dobLength === 0) {\n                    this.dobErrorMessage = $.mage.__('This is a required field.');\n\n                    return false;\n                }\n\n                if (!params[3] && dobLength === 0) {\n                    return true;\n                }\n                day = parseInt(dayVal, 10) || 0;\n                month = parseInt(monthVal, 10) || 0;\n                year = parseInt(yearVal, 10) || 0;\n                curYear = new Date().getFullYear();\n\n                if (!day || !month || !year) {\n                    this.dobErrorMessage = $.mage.__('Please enter a valid full date.');\n\n                    return false;\n                }\n\n                if (month < 1 || month > 12) {\n                    this.dobErrorMessage = $.mage.__('Please enter a valid month (1-12).');\n\n                    return false;\n                }\n\n                if (year < 1900 || year > curYear) {\n                    validYearMessage = $.mage.__('Please enter a valid year (1900-%1).');\n                    this.dobErrorMessage = validYearMessage.replace('%1', curYear.toString());\n\n                    return false;\n                }\n                validateDayInMonth = new Date(year, month, 0).getDate();\n\n                if (day < 1 || day > validateDayInMonth) {\n                    validDateMessage = $.mage.__('Please enter a valid day (1-%1).');\n                    this.dobErrorMessage = validDateMessage.replace('%1', validateDayInMonth.toString());\n\n                    return false;\n                }\n                today = new Date();\n                dateEntered = new Date();\n                dateEntered.setFullYear(year, month - 1, day);\n\n                if (dateEntered > today) {\n                    this.dobErrorMessage = $.mage.__('Please enter a date from the past.');\n\n                    return false;\n                }\n\n                day = day % 10 === day ? '0' + day : day;\n                month = month % 10 === month ? '0' + month : month;\n                $(element).val(month + '/' + day + '/' + year);\n\n                return true;\n            },\n            function () {\n                return this.dobErrorMessage;\n            }\n        ]\n    }, function (i, rule) {\n        rule.unshift(i);\n        $.validator.addMethod.apply($.validator, rule);\n    });\n});\n","mage/validation/url.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    return {\n\n        /**\n         * Redirects to the url if it is considered safe\n         *\n         * @param {String} path - url to be redirected to\n         */\n        redirect: function (path) {\n            path = this.sanitize(path);\n\n            if (this.validate(path)) {\n                window.location.href = path;\n            }\n        },\n\n        /**\n         * Validates url\n         *\n         * @param {Object} path - url to be validated\n         * @returns {Boolean}\n         */\n        validate: function (path) {\n            var hostname = window.location.hostname;\n\n            if (path.indexOf(hostname) === -1 ||\n                path.indexOf('javascript:') !== -1 ||\n                path.indexOf('vbscript:') !== -1) {\n                return false;\n            }\n\n            return true;\n        },\n\n        /**\n         * Sanitize url, replacing disallowed chars\n         *\n         * @param {String} path - url to be normalized\n         * @returns {String}\n         */\n        sanitize: function (path) {\n            return path.replace('[^-A-Za-z0-9+&@#/%?=~_|!:,.;\\(\\)]', '');\n        }\n    };\n});\n","mage/gallery/gallery.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'fotorama/fotorama',\n    'underscore',\n    'matchMedia',\n    'mage/template',\n    'text!mage/gallery/gallery.html',\n    'uiClass',\n    'mage/translate'\n], function ($, fotorama, _, mediaCheck, template, galleryTpl, Class, $t) {\n    'use strict';\n\n    /**\n     * Retrieves index if the main item.\n     * @param {Array.<Object>} data - Set of gallery items.\n     */\n    var getMainImageIndex = function (data) {\n            var mainIndex;\n\n            if (_.every(data, function (item) {\n                    return _.isObject(item);\n                })\n            ) {\n                mainIndex = _.findIndex(data, function (item) {\n                    return item.isMain;\n                });\n            }\n\n            return mainIndex > 0 ? mainIndex : 0;\n        },\n\n        /**\n         * Helper for parse translate property\n         *\n         * @param {Element} el - el that to parse\n         * @returns {Array} - array of properties.\n         */\n        getTranslate = function (el) {\n            var slideTransform = $(el).attr('style').split(';');\n\n            slideTransform = $.map(slideTransform, function (style) {\n                style = style.trim();\n\n                if (style.startsWith('transform: translate3d')) {\n                    return style.match(/transform: translate3d\\((.+)px,(.+)px,(.+)px\\)/);\n                }\n\n                return false;\n            });\n\n            return slideTransform.filter(Boolean);\n        },\n\n        /**\n         * @param {*} str\n         * @return {*}\n         * @private\n         */\n        _toNumber = function (str) {\n            var type = typeof str;\n\n            if (type === 'string') {\n                return parseInt(str); //eslint-disable-line radix\n            }\n\n            return str;\n        };\n\n    return Class.extend({\n\n        defaults: {\n            settings: {},\n            config: {},\n            startConfig: {}\n        },\n\n        /**\n         * Checks if device has touch interface.\n         * @return {Boolean} The result of searching touch events on device.\n         */\n        isTouchEnabled: (function () {\n            return 'ontouchstart' in document.documentElement;\n        })(),\n\n        /**\n         * Initializes gallery.\n         * @param {Object} config - Gallery configuration.\n         * @param {String} element - String selector of gallery DOM element.\n         */\n        initialize: function (config, element) {\n            var self = this;\n\n            this._super();\n\n            _.bindAll(this,\n                '_focusSwitcher'\n            );\n\n            /*turn off arrows for touch devices*/\n            if (this.isTouchEnabled) {\n                config.options.arrows = false;\n\n                if (config.fullscreen) {\n                    config.fullscreen.arrows = false;\n                }\n            }\n\n            config.options.width = _toNumber(config.options.width);\n            config.options.height = _toNumber(config.options.height);\n            config.options.thumbwidth = _toNumber(config.options.thumbwidth);\n            config.options.thumbheight = _toNumber(config.options.thumbheight);\n\n            config.options.swipe = true;\n            this.config = config;\n\n            this.settings = {\n                $element: $(element),\n                $pageWrapper: $('body>.page-wrapper'),\n                currentConfig: config,\n                defaultConfig: _.clone(config),\n                fullscreenConfig: _.clone(config.fullscreen),\n                breakpoints: config.breakpoints,\n                activeBreakpoint: {},\n                fotoramaApi: null,\n                isFullscreen: false,\n                api: null,\n                data: _.clone(config.data)\n            };\n            config.options.ratio = config.options.width / config.options.height;\n            config.options.height = null;\n\n            $.extend(true, this.startConfig, config);\n\n            this.initGallery();\n            this.initApi();\n            this.setupBreakpoints();\n            this.initFullscreenSettings();\n\n            this.settings.$element.on('click', '.fotorama__stage__frame', function () {\n                if (\n                    !$(this).parents('.fotorama__shadows--left, .fotorama__shadows--right').length &&\n                    !$(this).hasClass('fotorama-video-container')\n                ) {\n                    self.openFullScreen();\n                }\n            });\n\n            if (this.isTouchEnabled && this.settings.isFullscreen) {\n                this.settings.$element.on('tap', '.fotorama__stage__frame', function () {\n                    var translate = getTranslate($(this).parents('.fotorama__stage__shaft'));\n\n                    if (translate[1] === '0' && !$(this).hasClass('fotorama-video-container')) {\n                        self.openFullScreen();\n                        self.settings.$pageWrapper.hide();\n                    }\n                });\n            }\n        },\n\n        /**\n         * Open gallery fullscreen\n         */\n        openFullScreen: function () {\n            this.settings.api.fotorama.requestFullScreen();\n            this.settings.$fullscreenIcon.css({\n                opacity: 1,\n                visibility: 'visible',\n                display: 'block'\n            });\n        },\n\n        /**\n         * Gallery fullscreen settings.\n         */\n        initFullscreenSettings: function () {\n            var settings = this.settings,\n                self = this;\n\n            settings.$gallery = this.settings.$element.find('[data-gallery-role=\"gallery\"]');\n            settings.$fullscreenIcon = this.settings.$element.find('[data-gallery-role=\"fotorama__fullscreen-icon\"]');\n            settings.focusableStart = this.settings.$element.find('[data-gallery-role=\"fotorama__focusable-start\"]');\n            settings.focusableEnd = this.settings.$element.find('[data-gallery-role=\"fotorama__focusable-end\"]');\n            settings.closeIcon = this.settings.$element.find('[data-gallery-role=\"fotorama__fullscreen-icon\"]');\n            settings.fullscreenConfig.swipe = true;\n\n            settings.$gallery.on('fotorama:fullscreenenter', function () {\n                settings.closeIcon.show();\n                settings.focusableStart.attr('tabindex', '0');\n                settings.focusableEnd.attr('tabindex', '0');\n                settings.focusableStart.on('focusin', self._focusSwitcher);\n                settings.focusableEnd.on('focusin', self._focusSwitcher);\n                settings.api.updateOptions(settings.defaultConfig.options, true);\n                settings.api.updateOptions(settings.fullscreenConfig, true);\n\n                if (!_.isEqual(settings.activeBreakpoint, {}) && settings.breakpoints) {\n                    settings.api.updateOptions(settings.activeBreakpoint.options, true);\n                }\n                settings.isFullscreen = true;\n            });\n\n            settings.$gallery.on('fotorama:fullscreenexit', function () {\n                settings.closeIcon.hide();\n                settings.focusableStart.attr('tabindex', '-1');\n                settings.focusableEnd.attr('tabindex', '-1');\n                settings.api.updateOptions(settings.defaultConfig.options, true);\n                settings.focusableStart.off('focusin', this._focusSwitcher);\n                settings.focusableEnd.off('focusin', this._focusSwitcher);\n                settings.closeIcon.hide();\n\n                if (!_.isEqual(settings.activeBreakpoint, {}) && settings.breakpoints) {\n                    settings.api.updateOptions(settings.activeBreakpoint.options, true);\n                }\n                settings.isFullscreen = false;\n                settings.$element.data('gallery').updateOptions({\n                    swipe: true\n                });\n            });\n        },\n\n        /**\n         * Switcher focus.\n         */\n        _focusSwitcher: function (e) {\n            var target = $(e.target),\n                settings = this.settings;\n\n            if (target.is(settings.focusableStart)) {\n                this._setFocus('start');\n            } else if (target.is(settings.focusableEnd)) {\n                this._setFocus('end');\n            }\n        },\n\n        /**\n         * Set focus to element.\n         * @param {String} position - can be \"start\" and \"end\"\n         *      positions.\n         *      If position is \"end\" - sets focus to first\n         *      focusable element in modal window scope.\n         *      If position is \"start\" - sets focus to last\n         *      focusable element in modal window scope\n         */\n        _setFocus: function (position) {\n            var settings = this.settings,\n                focusableElements,\n                infelicity;\n\n            if (position === 'end') {\n                settings.$gallery.find(settings.closeIcon).trigger('focus');\n            } else if (position === 'start') {\n                infelicity = 3; //Constant for find last focusable element\n                focusableElements = settings.$gallery.find(':focusable');\n                focusableElements.eq(focusableElements.length - infelicity).trigger('focus');\n            }\n        },\n\n        /**\n         * Initializes gallery with configuration options.\n         */\n        initGallery: function () {\n            var breakpoints = {},\n                settings = this.settings,\n                config = this.config,\n                tpl = template(galleryTpl, {\n                    next: $t('Next'),\n                    previous: $t('Previous')\n                }),\n                mainImageIndex,\n                $element = settings.$element,\n                $fotoramaElement,\n                $fotoramaStage;\n\n            if (settings.breakpoints) {\n                _.each(_.values(settings.breakpoints), function (breakpoint) {\n                    var conditions;\n\n                    _.each(_.pairs(breakpoint.conditions), function (pair) {\n                        conditions = conditions ? conditions + ' and (' + pair[0] + ': ' + pair[1] + ')' :\n                        '(' + pair[0] + ': ' + pair[1] + ')';\n                    });\n                    breakpoints[conditions] = breakpoint.options;\n                });\n                settings.breakpoints = breakpoints;\n            }\n\n            _.extend(config, config.options,\n                {\n                    options: undefined,\n                    click: false,\n                    breakpoints: null\n                }\n            );\n            settings.currentConfig = config;\n\n            $element\n                .css('min-height', settings.$element.height())\n                .append(tpl);\n\n            $fotoramaElement = $element.find('[data-gallery-role=\"gallery\"]');\n\n            $fotoramaStage = $fotoramaElement.find('.fotorama__stage');\n            $fotoramaStage.css('position', 'absolute');\n\n            $fotoramaElement.fotorama(config);\n            $fotoramaElement.find('.fotorama__stage__frame.fotorama__active')\n                    .one('f:load', function () {\n                        // Remove placeholder when main gallery image loads.\n                        $element.find('.gallery-placeholder__image').remove();\n                        $element\n                            .removeClass('_block-content-loading')\n                            .css('min-height', '');\n\n                        $fotoramaStage.css('position', '');\n                    });\n            settings.$elementF = $fotoramaElement;\n            settings.fotoramaApi = $fotoramaElement.data('fotorama');\n\n            $.extend(true, config, this.startConfig);\n\n            mainImageIndex = getMainImageIndex(config.data);\n\n            if (mainImageIndex) {\n                this.settings.fotoramaApi.show({\n                    index: mainImageIndex,\n                    time: 0\n                });\n            }\n        },\n\n        /**\n         * Creates breakpoints for gallery.\n         */\n        setupBreakpoints: function () {\n            var pairs,\n                settings = this.settings,\n                config = this.config,\n                startConfig = this.startConfig,\n                isInitialized = {},\n                isTouchEnabled = this.isTouchEnabled;\n\n            if (_.isObject(settings.breakpoints)) {\n                pairs = _.pairs(settings.breakpoints);\n                _.each(pairs, function (pair) {\n                    var mediaQuery = pair[0];\n\n                    isInitialized[mediaQuery] = false;\n                    mediaCheck({\n                        media: mediaQuery,\n\n                        /**\n                         * Is triggered when breakpoint enties.\n                         */\n                        entry: function () {\n                            $.extend(true, config, _.clone(startConfig));\n\n                            settings.api.updateOptions(settings.defaultConfig.options, true);\n\n                            if (settings.isFullscreen) {\n                                settings.api.updateOptions(settings.fullscreenConfig, true);\n                            }\n\n                            if (isTouchEnabled) {\n                                settings.breakpoints[mediaQuery].options.arrows = false;\n\n                                if (settings.breakpoints[mediaQuery].options.fullscreen) {\n                                    settings.breakpoints[mediaQuery].options.fullscreen.arrows = false;\n                                }\n                            }\n\n                            settings.api.updateOptions(settings.breakpoints[mediaQuery].options, true);\n                            $.extend(true, config, settings.breakpoints[mediaQuery]);\n                            settings.activeBreakpoint = settings.breakpoints[mediaQuery];\n\n                            isInitialized[mediaQuery] = true;\n                        },\n\n                        /**\n                         * Is triggered when breakpoint exits.\n                         */\n                        exit: function () {\n                            if (isInitialized[mediaQuery]) {\n                                $.extend(true, config, _.clone(startConfig));\n                                settings.api.updateOptions(settings.defaultConfig.options, true);\n\n                                if (settings.isFullscreen) {\n                                    settings.api.updateOptions(settings.fullscreenConfig, true);\n                                }\n                                settings.activeBreakpoint = {};\n                            } else {\n                                isInitialized[mediaQuery] = true;\n                            }\n                        }\n                    });\n                });\n            }\n        },\n\n        /**\n         * Creates gallery's API.\n         */\n        initApi: function () {\n            var settings = this.settings,\n                config = this.config,\n                api = {\n\n                    /**\n                     * Contains fotorama's API methods.\n                     */\n                    fotorama: settings.fotoramaApi,\n\n                    /**\n                     * Displays the last image on preview.\n                     */\n                    last: function () {\n                        settings.fotoramaApi.show('>>');\n                    },\n\n                    /**\n                     * Displays the first image on preview.\n                     */\n                    first: function () {\n                        settings.fotoramaApi.show('<<');\n                    },\n\n                    /**\n                     * Displays previous element on preview.\n                     */\n                    prev: function () {\n                        settings.fotoramaApi.show('<');\n                    },\n\n                    /**\n                     * Displays next element on preview.\n                     */\n                    next: function () {\n                        settings.fotoramaApi.show('>');\n                    },\n\n                    /**\n                     * Displays image with appropriate count number on preview.\n                     * @param {Number} index - Number of image that should be displayed.\n                     */\n                    seek: function (index) {\n                        if (_.isNumber(index) && index !== 0) {\n\n                            if (index > 0) {\n                                index -= 1;\n                            }\n                            settings.fotoramaApi.show(index);\n                        }\n                    },\n\n                    /**\n                     * Updates gallery with new set of options.\n                     * @param {Object} configuration - Standart gallery configuration object.\n                     * @param {Boolean} isInternal - Is this function called via breakpoints.\n                     */\n                    updateOptions: function (configuration, isInternal) {\n\n                        var $selectable = $('a[href], area[href], input, select, ' +\n                                'textarea, button, iframe, object, embed, *[tabindex], *[contenteditable]')\n                                .not('[tabindex=-1], [disabled], :hidden'),\n                            $focus = $(':focus'),\n                            index;\n\n                        if (_.isObject(configuration)) {\n\n                            //Saves index of focus\n                            $selectable.each(function (number) {\n                                if ($(this).is($focus)) {\n                                    index = number;\n                                }\n                            });\n\n                            if (this.isTouchEnabled) {\n                                configuration.arrows = false;\n                            }\n                            configuration.click = false;\n                            configuration.breakpoints = null;\n\n                            if (!isInternal) {\n                                !_.isEqual(settings.activeBreakpoint, {} && settings.breakpoints) ?\n                                    $.extend(true, settings.activeBreakpoint.options, configuration) :\n\n                                    settings.isFullscreen ?\n                                        $.extend(true, settings.fullscreenConfig, configuration) :\n                                        $.extend(true, settings.defaultConfig.options, configuration);\n\n                            }\n                            $.extend(true, settings.currentConfig.options, configuration);\n                            settings.fotoramaApi.setOptions(settings.currentConfig.options);\n\n                            if (_.isNumber(index)) {\n                                $selectable.eq(index).trigger('focus');\n                            }\n                        }\n                    },\n\n                    /**\n                     * Updates gallery with specific set of items.\n                     * @param {Array.<Object>} data - Set of gallery items to update.\n                     */\n                    updateData: function (data) {\n                        var mainImageIndex;\n\n                        if (_.isArray(data)) {\n                            settings.fotoramaApi.load(data);\n                            mainImageIndex = getMainImageIndex(data);\n\n                            if (settings.fotoramaApi.activeIndex !== mainImageIndex) {\n                                settings.fotoramaApi.show({\n                                    index: mainImageIndex,\n                                    time: 0\n                                });\n                            }\n\n                            $.extend(false, settings, {\n                                data: data,\n                                defaultConfig: data\n                            });\n                            $.extend(false, config, {\n                                data: data\n                            });\n                        }\n                    },\n\n                    /**\n                     * Returns current images list\n                     *\n                     * @returns {Array}\n                     */\n                    returnCurrentImages: function () {\n                        var images = [];\n\n                        _.each(this.fotorama.data, function (item) {\n                            images.push(_.omit(item, '$navThumbFrame', '$navDotFrame', '$stageFrame', 'labelledby'));\n                        });\n\n                        return images;\n                    },\n\n                    /**\n                     * Updates gallery data partially by index\n                     * @param {Number} index - Index of image in data array to be updated.\n                     * @param {Object} item - Standart gallery image object.\n                     *\n                     */\n                    updateDataByIndex: function (index, item) {\n                        settings.fotoramaApi.spliceByIndex(index, item);\n                    }\n                };\n\n            settings.$element.data('gallery', api);\n            settings.api = settings.$element.data('gallery');\n            settings.$element.trigger('gallery:loaded');\n        }\n    });\n});\n","mage/msie/file-reader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    /**\n     * Init \"readAsBinaryString\" function for FileReader class.\n     * It need for IE11\n     * @param {Blob} fileData\n     */\n    var readAsBinaryStringIEFunc = function (fileData) {\n        var binary = '',\n            self = this,\n            reader = new FileReader();\n\n        /**\n         * Read file as binary string\n         */\n        reader.onload = function () {\n            var bytes, length, index;\n\n            /* eslint-disable no-undef */\n            bytes = new Uint8Array(reader.result);\n            /* eslint-enable */\n            length = bytes.length;\n\n            for (index = 0; index < length; index++) {\n                binary += String.fromCharCode(bytes[index]);\n            }\n            //self.result  - readonly so assign binary\n            self.content = binary;\n            $(self).trigger('onload');\n        };\n        reader.readAsArrayBuffer(fileData);\n    };\n\n    if (typeof FileReader.prototype.readAsBinaryString === 'undefined') {\n        FileReader.prototype.readAsBinaryString = readAsBinaryStringIEFunc;\n    }\n});\n","mage/apply/main.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'jquery',\n    './scripts'\n], function (_, $, processScripts) {\n    'use strict';\n\n    var dataAttr = 'data-mage-init',\n        nodeSelector = '[' + dataAttr + ']';\n\n    /**\n     * Initializes components assigned to a specified element via data-* attribute.\n     *\n     * @param {HTMLElement} el - Element to initialize components with.\n     * @param {Object|String} config - Initial components' config.\n     * @param {String} component - Components' path.\n     */\n    function init(el, config, component) {\n        require([component], function (fn) {\n            var $el;\n\n            if (typeof fn === 'object') {\n                fn = fn[component].bind(fn);\n            }\n\n            if (_.isFunction(fn)) {\n                fn = fn.bind(null, config, el);\n            } else {\n                $el = $(el);\n\n                if ($el[component]) {\n                    // eslint-disable-next-line jquery-no-bind-unbind\n                    fn = $el[component].bind($el, config);\n                }\n            }\n            // Init module in separate task to prevent blocking main thread.\n            setTimeout(fn);\n        }, function (error) {\n            if ('console' in window && typeof window.console.error === 'function') {\n                console.error(error);\n            }\n\n            return true;\n        });\n    }\n\n    /**\n     * Parses elements 'data-mage-init' attribute as a valid JSON data.\n     * Note: data-mage-init attribute will be removed.\n     *\n     * @param {HTMLElement} el - Element whose attribute should be parsed.\n     * @returns {Object}\n     */\n    function getData(el) {\n        var data = el.getAttribute(dataAttr);\n\n        el.removeAttribute(dataAttr);\n\n        return {\n            el: el,\n            data: JSON.parse(data)\n        };\n    }\n\n    return {\n        /**\n         * Initializes components assigned to HTML elements via [data-mage-init].\n         *\n         * @example Sample 'data-mage-init' declaration.\n         *      data-mage-init='{\"path/to/component\": {\"foo\": \"bar\"}}'\n         */\n        apply: function (context) {\n            var virtuals = processScripts(!context ? document : context),\n                nodes = document.querySelectorAll(nodeSelector);\n\n            _.toArray(nodes)\n                .map(getData)\n                .concat(virtuals)\n                .forEach(function (itemContainer) {\n                    var element = itemContainer.el;\n\n                    _.each(itemContainer.data, function (obj, key) {\n                            if (obj.mixins) {\n                                require(obj.mixins, function () { //eslint-disable-line max-nested-callbacks\n                                    var i, len;\n\n                                    for (i = 0, len = arguments.length; i < len; i++) {\n                                        $.extend(\n                                            true,\n                                            itemContainer.data[key],\n                                            arguments[i](itemContainer.data[key], element)\n                                        );\n                                    }\n\n                                    delete obj.mixins;\n                                    init.call(null, element, obj, key);\n                                });\n                            } else {\n                                init.call(null, element, obj, key);\n                            }\n\n                        }\n                    );\n\n                });\n        },\n        applyFor: init\n    };\n});\n","mage/apply/scripts.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'jquery'\n], function (_, $) {\n    'use strict';\n\n    var scriptSelector = 'script[type=\"text/x-magento-init\"]',\n        dataAttr = 'data-mage-init',\n        virtuals = [];\n\n    /**\n     * Adds components to the virtual list.\n     *\n     * @param {Object} components\n     */\n    function addVirtual(components) {\n        virtuals.push({\n            el: false,\n            data: components\n        });\n    }\n\n    /**\n     * Merges provided data with a current data\n     * of a elements' \"data-mage-init\" attribute.\n     *\n     * @param {Object} components - Object with components and theirs configuration.\n     * @param {HTMLElement} elem - Element whose data should be modified.\n     */\n    function setData(components, elem) {\n        var data = elem.getAttribute(dataAttr);\n\n        data = data ? JSON.parse(data) : {};\n        _.each(components, function (obj, key) {\n            if (_.has(obj, 'mixins')) {\n                data[key] = data[key] || {};\n                data[key].mixins = data[key].mixins || [];\n                data[key].mixins = data[key].mixins.concat(obj.mixins);\n                delete obj.mixins;\n            }\n        });\n\n        data = $.extend(true, data, components);\n        data = JSON.stringify(data);\n        elem.setAttribute(dataAttr, data);\n    }\n\n    /**\n     * Search for the elements by privded selector and extends theirs data.\n     *\n     * @param {Object} components - Object with components and theirs configuration.\n     * @param {String} selector - Selector for the elements.\n     */\n    function processElems(components, selector) {\n        var elems,\n            iterator;\n\n        if (selector === '*') {\n            addVirtual(components);\n\n            return;\n        }\n\n        elems = document.querySelectorAll(selector);\n        iterator = setData.bind(null, components);\n\n        _.toArray(elems).forEach(iterator);\n    }\n\n    /**\n     * Parses content of a provided script node.\n     * Note: node will be removed from DOM.\n     *\n     * @param {HTMLScriptElement} node - Node to be processed.\n     * @returns {Object}\n     */\n    function getNodeData(node) {\n        var data = node.textContent;\n\n        node.parentNode.removeChild(node);\n\n        return JSON.parse(data);\n    }\n\n    /**\n     * Parses 'script' tags with a custom type attribute and moves it's data\n     * to a 'data-mage-init' attribute of an element found by provided selector.\n     * Note: All found script nodes will be removed from DOM.\n     *\n     * @returns {Array} An array of components not assigned to the specific element.\n     *\n     * @example Sample declaration.\n     *      <script type=\"text/x-magento-init\">\n     *          {\n     *              \"body\": {\n     *                  \"path/to/component\": {\"foo\": \"bar\"}\n     *              }\n     *          }\n     *      </script>\n     *\n     * @example Providing data without selector.\n     *      {\n     *          \"*\": {\n     *              \"path/to/component\": {\"bar\": \"baz\"}\n     *          }\n     *      }\n     */\n    return function () {\n        var nodes = document.querySelectorAll(scriptSelector);\n\n        _.toArray(nodes)\n            .map(getNodeData)\n            .forEach(function (item) {\n                _.each(item, processElems);\n            });\n\n        return virtuals.splice(0, virtuals.length);\n    };\n});\n","mage/utils/objects.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'jquery',\n    'underscore',\n    'mage/utils/strings'\n], function (ko, $, _, stringUtils) {\n    'use strict';\n\n    var primitives = [\n        'undefined',\n        'boolean',\n        'number',\n        'string'\n    ];\n\n    /**\n     * Sets nested property of a specified object.\n     * @private\n     *\n     * @param {Object} parent - Object to look inside for the properties.\n     * @param {Array} path - Splitted path the property.\n     * @param {*} value - Value of the last property in 'path' array.\n     * returns {*} New value for the property.\n     */\n    function setNested(parent, path, value) {\n        var last = path.pop(),\n            len = path.length,\n            pi = 0,\n            part = path[pi];\n\n        for (; pi < len; part = path[++pi]) {\n            if (!_.isObject(parent[part])) {\n                parent[part] = {};\n            }\n\n            parent = parent[part];\n        }\n\n        if (typeof parent[last] === 'function') {\n            parent[last](value);\n        } else {\n            parent[last] = value;\n        }\n\n        return value;\n    }\n\n    /**\n     * Retrieves value of a nested property.\n     * @private\n     *\n     * @param {Object} parent - Object to look inside for the properties.\n     * @param {Array} path - Splitted path the property.\n     * @returns {*} Value of the property.\n     */\n    function getNested(parent, path) {\n        var exists = true,\n            len = path.length,\n            pi = 0;\n\n        for (; pi < len && exists; pi++) {\n            parent = parent[path[pi]];\n\n            if (typeof parent === 'undefined') {\n                exists = false;\n            }\n        }\n\n        if (exists) {\n            if (ko.isObservable(parent)) {\n                parent = parent();\n            }\n\n            return parent;\n        }\n    }\n\n    /**\n     * Removes property from a specified object.\n     * @private\n     *\n     * @param {Object} parent - Object from which to remove property.\n     * @param {Array} path - Splitted path to the property.\n     */\n    function removeNested(parent, path) {\n        var field = path.pop();\n\n        parent = getNested(parent, path);\n\n        if (_.isObject(parent)) {\n            delete parent[field];\n        }\n    }\n\n    return {\n\n        /**\n         * Retrieves or defines objects' property by a composite path.\n         *\n         * @param {Object} data - Container for the properties specified in path.\n         * @param {String} path - Objects' properties divided by dots.\n         * @param {*} [value] - New value for the last property.\n         * @returns {*} Returns value of the last property in chain.\n         *\n         * @example\n         *      utils.nested({}, 'one.two', 3);\n         *      => { one: {two: 3} }\n         */\n        nested: function (data, path, value) {\n            var action = arguments.length > 2 ? setNested : getNested;\n\n            path = path ? path.split('.') : [];\n\n            return action(data, path, value);\n        },\n\n        /**\n         * Removes nested property from an object.\n         *\n         * @param {Object} data - Data source.\n         * @param {String} path - Path to the property e.g. 'one.two.three'\n         */\n        nestedRemove: function (data, path) {\n            path = path.split('.');\n\n            removeNested(data, path);\n        },\n\n        /**\n         * Flattens objects' nested properties.\n         *\n         * @param {Object} data - Object to flatten.\n         * @param {String} [separator='.'] - Objects' keys separator.\n         * @returns {Object} Flattened object.\n         *\n         * @example Example with a default separator.\n         *      utils.flatten({one: { two: { three: 'value'} }});\n         *      => { 'one.two.three': 'value' };\n         *\n         * @example Example with a custom separator.\n         *      utils.flatten({one: { two: { three: 'value'} }}, '=>');\n         *      => {'one=>two=>three': 'value'};\n         */\n        flatten: function (data, separator, parent, result) {\n            separator = separator || '.';\n            result = result || {};\n\n            if (!data) {\n                return result;\n            }\n\n            // UnderscoreJS each breaks when an object has a length property so we use Object.keys\n            _.each(Object.keys(data), function (name) {\n                var node = data[name];\n\n                if ({}.toString.call(node) === '[object Function]') {\n                    return;\n                }\n\n                if (parent) {\n                    name = parent + separator + name;\n                }\n\n                typeof node === 'object' ?\n                    this.flatten(node, separator, name, result) :\n                    result[name] = node;\n\n            }, this);\n\n            return result;\n        },\n\n        /**\n         * Opposite operation of the 'flatten' method.\n         *\n         * @param {Object} data - Previously flattened object.\n         * @param {String} [separator='.'] - Keys separator.\n         * @returns {Object} Object with nested properties.\n         *\n         * @example Example using custom separator.\n         *      utils.unflatten({'one=>two': 'value'}, '=>');\n         *      => {\n         *          one: { two: 'value' }\n         *      };\n         */\n        unflatten: function (data, separator) {\n            var result = {};\n\n            separator = separator || '.';\n\n            _.each(data, function (value, nodes) {\n                nodes = nodes.split(separator);\n\n                setNested(result, nodes, value);\n            });\n\n            return result;\n        },\n\n        /**\n         * Same operation as 'flatten' method,\n         * but returns objects' keys wrapped in '[]'.\n         *\n         * @param {Object} data - Object that should be serialized.\n         * @returns {Object} Serialized data.\n         *\n         * @example\n         *      utils.serialize({one: { two: { three: 'value'} }});\n         *      => { 'one[two][three]': 'value' }\n         */\n        serialize: function (data) {\n            var result = {};\n\n            data = this.flatten(data);\n\n            _.each(data, function (value, keys) {\n                keys = stringUtils.serializeName(keys);\n                value = _.isUndefined(value) ? '' : value;\n\n                result[keys] = value;\n            }, this);\n\n            return result;\n        },\n\n        /**\n         * Performs deep extend of specified objects.\n         *\n         * @returns {Object|Array} Extended object.\n         */\n        extend: function () {\n            var args = _.toArray(arguments);\n\n            args.unshift(true);\n\n            return $.extend.apply($, args);\n        },\n\n        /**\n         * Performs a deep clone of a specified object.\n         *\n         * @param {(Object|Array)} data - Data that should be copied.\n         * @returns {Object|Array} Cloned object.\n         */\n        copy: function (data) {\n            var result = data,\n                isArray = Array.isArray(data),\n                placeholder;\n\n            if (this.isObject(data) || isArray) {\n                placeholder = isArray ? [] : {};\n                result = this.extend(placeholder, data);\n            }\n\n            return result;\n        },\n\n        /**\n         * Performs a deep clone of a specified object.\n         * Doesn't save links to original object.\n         *\n         * @param {*} original - Object to clone\n         * @returns {*}\n         */\n        hardCopy: function (original) {\n            if (original === null || typeof original !== 'object') {\n                return original;\n            }\n\n            return JSON.parse(JSON.stringify(original));\n        },\n\n        /**\n         * Removes specified nested properties from the target object.\n         *\n         * @param {Object} target - Object whose properties should be removed.\n         * @param {(...String|Array|Object)} list - List that specifies properties to be removed.\n         * @returns {Object} Modified object.\n         *\n         * @example Basic usage\n         *      var obj = {a: {b: 2}, c: 'a'};\n         *\n         *      omit(obj, 'a.b');\n         *      => {'a.b': 2};\n         *      obj => {a: {}, c: 'a'};\n         *\n         * @example Various syntaxes that would return same result\n         *      omit(obj, ['a.b', 'c']);\n         *      omit(obj, 'a.b', 'c');\n         *      omit(obj, {'a.b': true, 'c': true});\n         */\n        omit: function (target, list) {\n            var removed = {},\n                ignored = list;\n\n            if (this.isObject(list)) {\n                ignored = [];\n\n                _.each(list, function (value, key) {\n                    if (value) {\n                        ignored.push(key);\n                    }\n                });\n            } else if (_.isString(list)) {\n                ignored = _.toArray(arguments).slice(1);\n            }\n\n            _.each(ignored, function (path) {\n                var value = this.nested(target, path);\n\n                if (!_.isUndefined(value)) {\n                    removed[path] = value;\n\n                    this.nestedRemove(target, path);\n                }\n            }, this);\n\n            return removed;\n        },\n\n        /**\n         * Checks if provided value is a plain object.\n         *\n         * @param {*} value - Value to be checked.\n         * @returns {Boolean}\n         */\n        isObject: function (value) {\n            var objProto = Object.prototype;\n\n            return typeof value == 'object' ?\n            objProto.toString.call(value) === '[object Object]' :\n                false;\n        },\n\n        /**\n         *\n         * @param {*} value\n         * @returns {Boolean}\n         */\n        isPrimitive: function (value) {\n            return value === null || ~primitives.indexOf(typeof value);\n        },\n\n        /**\n         * Iterates over obj props/array elems recursively, applying action to each one\n         *\n         * @param {Object|Array} data - Data to be iterated.\n         * @param {Function} action - Callback to be called with each item as an argument.\n         * @param {Number} [maxDepth=7] - Max recursion depth.\n         */\n        forEachRecursive: function (data, action, maxDepth) {\n            maxDepth = typeof maxDepth === 'number' && !isNaN(maxDepth) ? maxDepth - 1 : 7;\n\n            if (!_.isFunction(action) || _.isFunction(data) || maxDepth < 0) {\n                return;\n            }\n\n            if (!_.isObject(data)) {\n                action(data);\n\n                return;\n            }\n\n            _.each(data, function (value) {\n                this.forEachRecursive(value, action, maxDepth);\n            }, this);\n\n            action(data);\n        },\n\n        /**\n         * Maps obj props/array elems recursively\n         *\n         * @param {Object|Array} data - Data to be iterated.\n         * @param {Function} action - Callback to transform each item.\n         * @param {Number} [maxDepth=7] - Max recursion depth.\n         *\n         * @returns {Object|Array}\n         */\n        mapRecursive: function (data, action, maxDepth) {\n            var newData;\n\n            maxDepth = typeof maxDepth === 'number' && !isNaN(maxDepth) ? maxDepth - 1 : 7;\n\n            if (!_.isFunction(action) || _.isFunction(data) || maxDepth < 0) {\n                return data;\n            }\n\n            if (!_.isObject(data)) {\n                return action(data);\n            }\n\n            if (_.isArray(data)) {\n                newData = _.map(data, function (item) {\n                    return this.mapRecursive(item, action, maxDepth);\n                }, this);\n\n                return action(newData);\n            }\n\n            newData = _.mapObject(data, function (val, key) {\n                if (data.hasOwnProperty(key)) {\n                    return this.mapRecursive(val, action, maxDepth);\n                }\n\n                return val;\n            }, this);\n\n            return action(newData);\n        },\n\n        /**\n         * Removes empty(in common sence) obj props/array elems\n         *\n         * @param {*} data - Data to be cleaned.\n         * @returns {*}\n         */\n        removeEmptyValues: function (data) {\n            if (!_.isObject(data)) {\n                return data;\n            }\n\n            if (_.isArray(data)) {\n                return data.filter(function (item) {\n                    return !this.isEmptyObj(item);\n                }, this);\n            }\n\n            return _.omit(data, this.isEmptyObj.bind(this));\n        },\n\n        /**\n         * Checks that argument of any type is empty in common sence:\n         * empty string, string with spaces only, object without own props, empty array, null or undefined\n         *\n         * @param {*} val - Value to be checked.\n         * @returns {Boolean}\n         */\n        isEmptyObj: function (val) {\n\n            return _.isObject(val) && _.isEmpty(val) ||\n            this.isEmpty(val) ||\n            val && val.trim && this.isEmpty(val.trim());\n        }\n    };\n});\n\n","mage/utils/misc.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'jquery',\n    'mage/utils/objects'\n], function (_, $, utils) {\n    'use strict';\n\n    var defaultAttributes,\n        ajaxSettings,\n        map;\n\n    defaultAttributes = {\n        method: 'post',\n        enctype: 'multipart/form-data'\n    };\n\n    ajaxSettings = {\n        default: {\n            method: 'POST',\n            cache: false,\n            processData: false,\n            contentType: false\n        },\n        simple: {\n            method: 'POST',\n            dataType: 'json'\n        }\n    };\n\n    map = {\n        'D': 'DDD',\n        'dd': 'DD',\n        'd': 'D',\n        'EEEE': 'dddd',\n        'EEE': 'ddd',\n        'e': 'd',\n        'yyyy': 'YYYY',\n        'yy': 'YY',\n        'y': 'YYYY',\n        'a': 'A'\n    };\n\n    return {\n\n        /**\n         * Generates a unique identifier.\n         *\n         * @param {Number} [size=7] - Length of a resulting identifier.\n         * @returns {String}\n         */\n        uniqueid: function (size) {\n            var code = Math.random() * 25 + 65 | 0,\n                idstr = String.fromCharCode(code);\n\n            size = size || 7;\n\n            while (idstr.length < size) {\n                code = Math.floor(Math.random() * 42 + 48);\n\n                if (code < 58 || code > 64) {\n                    idstr += String.fromCharCode(code);\n                }\n            }\n\n            return idstr;\n        },\n\n        /**\n         * Limits function call.\n         *\n         * @param {Object} owner\n         * @param {String} target\n         * @param {Number} limit\n         */\n        limit: function (owner, target, limit) {\n            var fn = owner[target];\n\n            owner[target] = _.debounce(fn.bind(owner), limit);\n        },\n\n        /**\n         * Converts mage date format to a moment.js format.\n         *\n         * @param {String} mageFormat\n         * @returns {String}\n         */\n        normalizeDate: function (mageFormat) {\n            var result = mageFormat;\n\n            _.each(map, function (moment, mage) {\n                result = result.replace(\n                    new RegExp(mage + '(?=([^\\u0027]*\\u0027[^\\u0027]*\\u0027)*[^\\u0027]*$)'),\n                    moment\n                );\n            });\n            result = result.replace(/'(.*?)'/g, '[$1]');\n            return result;\n        },\n\n        /**\n         * Puts provided value in range of min and max parameters.\n         *\n         * @param {Number} value - Value to be located.\n         * @param {Number} min - Min value.\n         * @param {Number} max - Max value.\n         * @returns {Number}\n         */\n        inRange: function (value, min, max) {\n            return Math.min(Math.max(min, value), max);\n        },\n\n        /**\n         * Serializes and sends data via POST request.\n         *\n         * @param {Object} options - Options object that consists of\n         *      a 'url' and 'data' properties.\n         * @param {Object} attrs - Attributes that will be added to virtual form.\n         */\n        submit: function (options, attrs) {\n            var form        = document.createElement('form'),\n                data        = utils.serialize(options.data),\n                attributes  = _.extend({}, defaultAttributes, attrs || {});\n\n            if (!attributes.action) {\n                attributes.action = options.url;\n            }\n\n            data['form_key'] = window.FORM_KEY;\n\n            _.each(attributes, function (value, name) {\n                form.setAttribute(name, value);\n            });\n\n            data = _.map(\n                data,\n                function (value, name) {\n                    return '<input type=\"hidden\" ' +\n                        'name=\"' + _.escape(name) + '\" ' +\n                        'value=\"' + _.escape(value) + '\"' +\n                        ' />';\n                }\n            ).join('');\n\n            form.insertAdjacentHTML('afterbegin', data);\n            document.body.appendChild(form);\n\n            form.submit();\n        },\n\n        /**\n         * Serializes and sends data via AJAX POST request.\n         *\n         * @param {Object} options - Options object that consists of\n         *      a 'url' and 'data' properties.\n         * @param {Object} config\n         */\n        ajaxSubmit: function (options, config) {\n            var t = new Date().getTime(),\n                settings;\n\n            options.data['form_key'] = window.FORM_KEY;\n            options.data = this.prepareFormData(options.data, config.ajaxSaveType);\n            settings = _.extend({}, ajaxSettings[config.ajaxSaveType], options || {});\n\n            if (!config.ignoreProcessEvents) {\n                $('body').trigger('processStart');\n            }\n\n            return $.ajax(settings)\n                .done(function (data) {\n                    if (config.response) {\n                        data.t = t;\n                        config.response.data(data);\n                        config.response.status(undefined);\n                        config.response.status(!data.error);\n                    }\n                })\n                .fail(function () {\n                    if (config.response) {\n                        config.response.status(undefined);\n                        config.response.status(false);\n                        config.response.data({\n                            error: true,\n                            messages: 'Something went wrong.',\n                            t: t\n                        });\n                    }\n                })\n                .always(function () {\n                    if (!config.ignoreProcessEvents) {\n                        $('body').trigger('processStop');\n                    }\n                });\n        },\n\n        /**\n         * Creates FormData object and append this data.\n         *\n         * @param {Object} data\n         * @param {String} type\n         * @returns {FormData}\n         */\n        prepareFormData: function (data, type) {\n            var formData;\n\n            if (type === 'default') {\n                formData = new FormData();\n                _.each(utils.serialize(data), function (val, name) {\n                    formData.append(name, val);\n                });\n            } else if (type === 'simple') {\n                formData = utils.serialize(data);\n            }\n\n            return formData;\n        },\n\n        /**\n         * Filters data object. Finds properties with suffix\n         * and sets their values to properties with the same name without suffix.\n         *\n         * @param {Object} data - The data object that should be filtered\n         * @param {String} suffix - The string by which data object should be filtered\n         * @param {String} separator - The string that is separator between property and suffix\n         *\n         * @returns {Object} Filtered data object\n         */\n        filterFormData: function (data, suffix, separator) {\n            data = data || {};\n            suffix = suffix || 'prepared-for-send';\n            separator = separator || '-';\n\n            _.each(data, function (value, key) {\n                if (_.isObject(value) && !Array.isArray(value)) {\n                    this.filterFormData(value, suffix, separator);\n                } else if (_.isString(key) && ~key.indexOf(suffix)) {\n                    data[key.split(separator)[0]] = value;\n                    delete data[key];\n                }\n            }, this);\n\n            return data;\n        },\n\n        /**\n         * Replaces special characters with their corresponding HTML entities.\n         *\n         * @param {String} string - Text to escape.\n         * @returns {String} Escaped text.\n         */\n        escape: function (string) {\n            return string ? $('<p></p>').text(string).html().replace(/\"/g, '&quot;') : string;\n        },\n\n        /**\n         * Replaces symbol codes with their unescaped counterparts.\n         *\n         * @param {String} data\n         *\n         * @returns {String}\n         */\n        unescape: function (data) {\n            var unescaped = _.unescape(data),\n                mapCharacters = {\n                    '&#039;': '\\''\n                };\n\n            _.each(mapCharacters, function (value, key) {\n                unescaped = unescaped.replace(key, value);\n            });\n\n            return unescaped;\n        },\n\n        /**\n         * Converts PHP IntlFormatter format to moment format.\n         *\n         * @param {String} format - PHP format\n         * @returns {String} - moment compatible formatting\n         */\n        convertToMomentFormat: function (format) {\n            var newFormat;\n\n            newFormat = format.replace(/yyyy|yy|y/, 'YYYY'); // replace the year\n            newFormat = newFormat.replace(/dd|d/g, 'DD'); // replace the date\n\n            return newFormat;\n        },\n\n        /**\n         * Get Url Parameters.\n         *\n         * @param {String} url - Url string\n         * @returns {Object}\n         */\n        getUrlParameters: function (url) {\n            var params = {},\n                queries = url.split('?'),\n                temp,\n                i,\n                l;\n\n            if (!queries[1]) {\n                return params;\n            }\n\n            queries = queries[1].split('&');\n\n            for (i = 0, l = queries.length; i < l; i++) {\n                temp = queries[i].split('=');\n\n                if (temp[1]) {\n                    params[temp[0]] = decodeURIComponent(temp[1].replace(/\\+/g, '%20'));\n                } else {\n                    params[temp[0]] = '';\n                }\n            }\n\n            return params;\n        }\n    };\n});\n","mage/utils/strings.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore'\n], function (_) {\n    'use strict';\n\n    var jsonRe = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/;\n\n    return {\n\n        /**\n         * Attempts to convert string to one of the primitive values,\n         * or to parse it as a valid json object.\n         *\n         * @param {String} str - String to be processed.\n         * @returns {*}\n         */\n        castString: function (str) {\n            try {\n                str = str === 'true' ? true :\n                    str === 'false' ? false :\n                        str === 'null' ? null :\n                            +str + '' === str ? +str :\n                                jsonRe.test(str) ? JSON.parse(str) :\n                                    str;\n            } catch (e) {\n            }\n\n            return str;\n        },\n\n        /**\n         * Splits string by separator if it's possible,\n         * otherwise returns the incoming value.\n         *\n         * @param {(String|Array|*)} str - String to split.\n         * @param {String} [separator=' '] - Seperator based on which to split the string.\n         * @returns {Array|*} Splitted string or the incoming value.\n         */\n        stringToArray: function (str, separator) {\n            separator = separator || ' ';\n\n            return typeof str === 'string' ?\n                str.split(separator) :\n                str;\n        },\n\n        /**\n         * Converts the incoming string which consists\n         * of a specified delimiters into a format commonly used in form elements.\n         *\n         * @param {String} name - The incoming string.\n         * @param {String} [separator='.']\n         * @returns {String} Serialized string.\n         *\n         * @example\n         *      utils.serializeName('one.two.three');\n         *      => 'one[two][three]';\n         */\n        serializeName: function (name, separator) {\n            var result;\n\n            separator = separator || '.';\n            name = name.split(separator);\n\n            result = name.shift();\n\n            name.forEach(function (part) {\n                result += '[' + part + ']';\n            });\n\n            return result;\n        },\n\n        /**\n         * Checks wether the incoming value is not empty,\n         * e.g. not 'null' or 'undefined'\n         *\n         * @param {*} value - Value to check.\n         * @returns {Boolean}\n         */\n        isEmpty: function (value) {\n            return value === '' || _.isUndefined(value) || _.isNull(value);\n        },\n\n        /**\n         * Adds 'prefix' to the 'part' value if it was provided.\n         *\n         * @param {String} prefix\n         * @param {String} part\n         * @returns {String}\n         */\n        fullPath: function (prefix, part) {\n            return prefix ? prefix + '.' + part : part;\n        },\n\n        /**\n         * Splits incoming string and returns its' part specified by offset.\n         *\n         * @param {String} parts\n         * @param {Number} [offset]\n         * @param {String} [delimiter=.]\n         * @returns {String}\n         */\n        getPart: function (parts, offset, delimiter) {\n            delimiter = delimiter || '.';\n            parts = parts.split(delimiter);\n            offset = this.formatOffset(parts, offset);\n\n            parts.splice(offset, 1);\n\n            return parts.join(delimiter) || '';\n        },\n\n        /**\n         * Converts nameThroughCamelCase to name-through-minus\n         *\n         * @param {String} string\n         * @returns {String}\n         */\n        camelCaseToMinus: function camelCaseToMinus(string) {\n            return ('' + string)\n                .split('')\n                .map(function (symbol, index) {\n                    return index ?\n                        symbol.toUpperCase() === symbol ?\n                        '-' + symbol.toLowerCase() :\n                            symbol :\n                        symbol.toLowerCase();\n                })\n                .join('');\n        },\n\n        /**\n         * Converts name-through-minus to nameThroughCamelCase\n         *\n         * @param {String} string\n         * @returns {String}\n         */\n        minusToCamelCase: function minusToCamelCase(string) {\n            return ('' + string)\n                .split('-')\n                .map(function (part, index) {\n                    return index ? part.charAt(0).toUpperCase() + part.slice(1) : part;\n                })\n                .join('');\n        }\n    };\n});\n","mage/utils/arrays.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    './strings'\n], function (_, utils) {\n    'use strict';\n\n    /**\n     * Defines index of an item in a specified container.\n     *\n     * @param {*} item - Item whose index should be defined.\n     * @param {Array} container - Container upon which to perform search.\n     * @returns {Number}\n     */\n    function getIndex(item, container) {\n        var index = container.indexOf(item);\n\n        if (~index) {\n            return index;\n        }\n\n        return _.findIndex(container, function (value) {\n            return value && value.name === item;\n        });\n    }\n\n    return {\n        /**\n         * Facade method to remove/add value from/to array\n         * without creating a new instance.\n         *\n         * @param {Array} arr - Array to be modified.\n         * @param {*} value - Value to add/remove.\n         * @param {Boolean} add - Flag that specfies operation.\n         * @returns {Utils} Chainable.\n         */\n        toggle: function (arr, value, add) {\n            return add ?\n                this.add(arr, value) :\n                this.remove(arr, value);\n        },\n\n        /**\n         * Removes the incoming value from array in case\n         * without creating a new instance of it.\n         *\n         * @param {Array} arr - Array to be modified.\n         * @param {*} value - Value to be removed.\n         * @returns {Utils} Chainable.\n         */\n        remove: function (arr, value) {\n            var index = arr.indexOf(value);\n\n            if (~index) {\n                arr.splice(index, 1);\n            }\n\n            return this;\n        },\n\n        /**\n         * Adds the incoming value to array if\n         * it's not alredy present in there.\n         *\n         * @param {Array} arr - Array to be modifed.\n         * @param {...*} arguments - Values to be added.\n         * @returns {Utils} Chainable.\n         */\n        add: function (arr) {\n            var values = _.toArray(arguments).slice(1);\n\n            values.forEach(function (value) {\n                if (!~arr.indexOf(value)) {\n                    arr.push(value);\n                }\n            });\n\n            return this;\n        },\n\n        /**\n         * Inserts specified item into container at a specified position.\n         *\n         * @param {*} item - Item to be inserted into container.\n         * @param {Array} container - Container of items.\n         * @param {*} [position=-1] - Position at which item should be inserted.\n         *      Position can represent:\n         *          - specific index in container\n         *          - item which might already be present in container\n         *          - structure with one of these properties: after, before\n         * @returns {Boolean|*}\n         *      - true if element has changed its' position\n         *      - false if nothing has changed\n         *      - inserted value if it wasn't present in container\n         */\n        insert: function (item, container, position) {\n            var currentIndex = getIndex(item, container),\n                newIndex,\n                target;\n\n            if (typeof position === 'undefined') {\n                position = -1;\n            } else if (typeof position === 'string') {\n                position = isNaN(+position) ? position : +position;\n            }\n\n            newIndex = position;\n\n            if (~currentIndex) {\n                target = container.splice(currentIndex, 1)[0];\n\n                if (typeof item === 'string') {\n                    item = target;\n                }\n            }\n\n            if (typeof position !== 'number') {\n                target = position.after || position.before || position;\n\n                newIndex = getIndex(target, container);\n\n                if (~newIndex && (position.after || newIndex >= currentIndex)) {\n                    newIndex++;\n                }\n            }\n\n            if (newIndex < 0) {\n                newIndex += container.length + 1;\n            }\n\n            container[newIndex] ?\n                container.splice(newIndex, 0, item) :\n                container[newIndex] = item;\n\n            return !~currentIndex ? item : currentIndex !== newIndex;\n        },\n\n        /**\n         * @param {Array} elems\n         * @param {Number} offset\n         * @return {Number|*}\n         */\n        formatOffset: function (elems, offset) {\n            if (utils.isEmpty(offset)) {\n                offset = -1;\n            }\n\n            offset = +offset;\n\n            if (offset < 0) {\n                offset += elems.length + 1;\n            }\n\n            return offset;\n        }\n    };\n});\n","mage/utils/wrapper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * Utility methods used to wrap and extend functions.\n *\n * @example Usage of a 'wrap' method with arguments delegation.\n *      var multiply = function (a, b) {\n *          return a * b;\n *      };\n *\n *      multiply = module.wrap(multiply, function (orig) {\n *          return 'Result is: ' + orig();\n *      });\n *\n *      multiply(2, 2);\n *      => 'Result is: 4'\n *\n * @example Usage of 'wrapSuper' method.\n *      var multiply = function (a, b) {\n *         return a * b;\n *      };\n *\n *      var obj = {\n *          multiply: module.wrapSuper(multiply, function () {\n *              return 'Result is: ' + this._super();\n *          });\n *      };\n *\n *      obj.multiply(2, 2);\n *      => 'Result is: 4'\n */\ndefine([\n    'underscore'\n], function (_) {\n    'use strict';\n\n    /**\n     * Checks if string has a '_super' substring.\n     */\n    var superReg = /\\b_super\\b/;\n\n    return {\n\n        /**\n         * Wraps target function with a specified wrapper, which will receive\n         * reference to the original function as a first argument.\n         *\n         * @param {Function} target - Function to be wrapped.\n         * @param {Function} wrapper - Wrapper function.\n         * @returns {Function} Wrapper function.\n         */\n        wrap: function (target, wrapper) {\n            if (!_.isFunction(target) || !_.isFunction(wrapper)) {\n                return wrapper;\n            }\n\n            return function () {\n                var args    = _.toArray(arguments),\n                    ctx     = this,\n                    _super;\n\n                /**\n                 * Function that will be passed to the wrapper.\n                 * If no arguments will be passed to it, then the original\n                 * function will be called with an arguments of a wrapper function.\n                 */\n                _super = function () {\n                    var superArgs = arguments.length ? arguments : args.slice(1);\n\n                    return target.apply(ctx, superArgs);\n                };\n\n                args.unshift(_super);\n\n                return wrapper.apply(ctx, args);\n            };\n        },\n\n        /**\n         * Wraps the incoming function to implement support of the '_super' method.\n         *\n         * @param {Function} target - Function to be wrapped.\n         * @param {Function} wrapper - Wrapper function.\n         * @returns {Function} Wrapped function.\n         */\n        wrapSuper: function (target, wrapper) {\n            if (!this.hasSuper(wrapper) || !_.isFunction(target)) {\n                return wrapper;\n            }\n\n            return function () {\n                var _super  = this._super,\n                    args    = arguments,\n                    result;\n\n                /**\n                 * Temporary define '_super' method which\n                 * contains call to the original function.\n                 */\n                this._super = function () {\n                    var superArgs = arguments.length ? arguments : args;\n\n                    return target.apply(this, superArgs);\n                };\n\n                result = wrapper.apply(this, args);\n\n                this._super = _super;\n\n                return result;\n            };\n        },\n\n        /**\n         * Checks wether the incoming method contains calls of the '_super' method.\n         *\n         * @param {Function} fn - Function to be checked.\n         * @returns {Boolean}\n         */\n        hasSuper: function (fn) {\n            return _.isFunction(fn) && superReg.test(fn);\n        },\n\n        /**\n         * Extends target object with provided extenders.\n         * If property in target and extender objects is a function,\n         * then it will be wrapped using 'wrap' method.\n         *\n         * @param {Object} target - Object to be extended.\n         * @param {...Object} extenders - Multiple extenders objects.\n         * @returns {Object} Modified target object.\n         */\n        extend: function (target) {\n            var extenders = _.toArray(arguments).slice(1),\n                iterator = this._extend.bind(this, target);\n\n            extenders.forEach(iterator);\n\n            return target;\n        },\n\n        /**\n         * Same as the 'extend' method, but operates only on one extender object.\n         *\n         * @private\n         * @param {Object} target\n         * @param {Object} extender\n         */\n        _extend: function (target, extender) {\n            _.each(extender, function (value, key) {\n                target[key] = this.wrap(target[key], extender[key]);\n            }, this);\n        }\n    };\n});\n","mage/utils/main.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(function (require) {\n    'use strict';\n\n    var utils = {},\n        _ = require('underscore'),\n        root = typeof self == 'object' && self.self === self && self ||\n            typeof global == 'object' && global.global === global && global ||\n            Function('return this')() || {};\n\n    root._ = _;\n\n    return _.extend(\n        utils,\n        require('./arrays'),\n        require('./compare'),\n        require('./misc'),\n        require('./objects'),\n        require('./strings'),\n        require('./template')\n    );\n});\n","mage/utils/template.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable no-shadow */\n\ndefine([\n    'jquery',\n    'underscore',\n    'mage/utils/objects',\n    'mage/utils/strings'\n], function ($, _, utils, stringUtils) {\n    'use strict';\n\n    var tmplSettings = _.templateSettings,\n        interpolate = /\\$\\{([\\s\\S]+?)\\}/g,\n        opener = '${',\n        template,\n        hasStringTmpls;\n\n    /**\n     * Identifies whether ES6 templates are supported.\n     */\n    hasStringTmpls = (function () {\n        var testString = 'var foo = \"bar\"; return `${ foo }` === foo';\n\n        try {\n            return Function(testString)();\n        } catch (e) {\n            return false;\n        }\n    })();\n\n    /**\n     * Objects can specify how to use templating for their properties - getting that configuration.\n     *\n     * To disable rendering for all properties of your object add __disableTmpl: true.\n     * To disable for specific property add __disableTmpl: {propertyName: true}.\n     * To limit recursion for a specific property add __disableTmpl: {propertyName: numberOfCycles}.\n     *\n     * @param {String} tmpl\n     * @param {Object | undefined} target\n     * @returns {Boolean|Object}\n     */\n    function isTmplIgnored(tmpl, target) {\n        var parsedTmpl;\n\n        try {\n            parsedTmpl = JSON.parse(tmpl);\n\n            if (typeof parsedTmpl === 'object') {\n                return tmpl.includes('__disableTmpl');\n            }\n        } catch (e) {\n        }\n\n        if (typeof target !== 'undefined') {\n            if (typeof target === 'object' && target.hasOwnProperty('__disableTmpl')) {\n                return target.__disableTmpl;\n            }\n        }\n\n        return false;\n\n    }\n\n    if (hasStringTmpls) {\n\n        /*eslint-disable no-unused-vars, no-eval*/\n        /**\n         * Evaluates template string using ES6 templates.\n         *\n         * @param {String} tmpl - Template string.\n         * @param {Object} $ - Data object used in a template.\n         * @returns {String} Compiled template.\n         */\n        template = function (tmpl, $) {\n            return eval('`' + tmpl + '`');\n        };\n\n        /*eslint-enable no-unused-vars, no-eval*/\n    } else {\n\n        /**\n         * Fallback function used when ES6 templates are not supported.\n         * Uses underscore templates renderer.\n         *\n         * @param {String} tmpl - Template string.\n         * @param {Object} data - Data object used in a template.\n         * @returns {String} Compiled template.\n         */\n        template = function (tmpl, data) {\n            var cached = tmplSettings.interpolate;\n\n            tmplSettings.interpolate = interpolate;\n\n            tmpl = _.template(tmpl, {\n                variable: '$'\n            })(data);\n\n            tmplSettings.interpolate = cached;\n\n            return tmpl;\n        };\n    }\n\n    /**\n     * Checks if provided value contains template syntax.\n     *\n     * @param {*} value - Value to be checked.\n     * @returns {Boolean}\n     */\n    function isTemplate(value) {\n        return typeof value === 'string' &&\n            value.indexOf(opener) !== -1 &&\n            // the below pattern almost always indicates an accident which should not cause template evaluation\n            // refuse to evaluate\n            value.indexOf('${{') === -1;\n    }\n\n    /**\n     * Iteratively processes provided string\n     * until no templates syntax will be found.\n     *\n     * @param {String} tmpl - Template string.\n     * @param {Object} data - Data object used in a template.\n     * @param {Boolean} [castString=false] - Flag that indicates whether template\n     *      should be casted after evaluation to a value of another type or\n     *      that it should be leaved as a string.\n     * @param {Number|undefined} maxCycles - Maximum number of rendering cycles, can be 0.\n     * @returns {*} Compiled template.\n     */\n    function render(tmpl, data, castString, maxCycles) {\n        var last = tmpl,\n            cycles = 0;\n\n        while (~tmpl.indexOf(opener) && (typeof maxCycles === 'undefined' || cycles < maxCycles)) {\n            if (!isTmplIgnored(tmpl)) {\n                tmpl = template(tmpl, data);\n            }\n\n            if (tmpl === last) {\n                break;\n            }\n\n            last = tmpl;\n            cycles++;\n        }\n\n        return castString ?\n            stringUtils.castString(tmpl) :\n            tmpl;\n    }\n\n    return {\n\n        /**\n         * Applies provided data to the template.\n         *\n         * @param {Object|String} tmpl\n         * @param {Object} [data] - Data object to match with template.\n         * @param {Boolean} [castString=false] - Flag that indicates whether template\n         *      should be casted after evaluation to a value of another type or\n         *      that it should be leaved as a string.\n         * @returns {*}\n         *\n         * @example Template defined as a string.\n         *      var source = { foo: 'Random Stuff', bar: 'Some' };\n         *\n         *      utils.template('${ $.bar } ${ $.foo }', source);\n         *      => 'Some Random Stuff';\n         *\n         * @example Template defined as an object.\n         *      var tmpl = {\n         *              key: {'${ $.$data.bar }': '${ $.$data.foo }'},\n         *              foo: 'bar',\n         *              x1: 2, x2: 5,\n         *              delta: '${ $.x2 - $.x1 }',\n         *              baz: 'Upper ${ $.foo.toUpperCase() }'\n         *      };\n         *\n         *      utils.template(tmpl, source);\n         *      => {\n         *          key: {'Some': 'Random Stuff'},\n         *          foo: 'bar',\n         *          x1: 2, x2: 5,\n         *          delta: 3,\n         *          baz: 'Upper BAR'\n         *      };\n         */\n        template: function (tmpl, data, castString, dontClone) {\n            if (typeof tmpl === 'string') {\n                return render(tmpl, data, castString);\n            }\n\n            if (!dontClone) {\n                tmpl = utils.copy(tmpl);\n            }\n\n            tmpl.$data = data || {};\n\n            /**\n             * Template iterator function.\n             */\n            _.each(tmpl, function iterate(value, key, list) {\n                var disabled,\n                    maxCycles;\n\n                if (key === '$data') {\n                    return;\n                }\n\n                if (isTemplate(key)) {\n                    delete list[key];\n\n                    key = render(key, tmpl);\n                    list[key] = value;\n                }\n\n                if (isTemplate(value)) {\n                    //Getting template disabling settings, can be true for all disabled and separate settings\n                    //for each property.\n                    disabled = isTmplIgnored(value, list);\n\n                    if (typeof disabled === 'object' && disabled.hasOwnProperty(key) && disabled[key] !== false) {\n                        //Checking if specific settings for a property provided.\n                        maxCycles = disabled[key];\n                    }\n\n                    if (disabled === true || maxCycles === true) {\n                        //Rendering for all properties is disabled.\n                        maxCycles = 0;\n                    }\n\n                    list[key] = render(value, tmpl, castString, maxCycles);\n                } else if ($.isPlainObject(value) || Array.isArray(value)) {\n                    _.each(value, iterate);\n                }\n            });\n\n            delete tmpl.$data;\n\n            return tmpl;\n        }\n    };\n});\n","mage/utils/compare.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'mage/utils/objects'\n], function (_, utils) {\n    'use strict';\n\n    var result = [];\n\n    /**\n     * Checks if all of the provided arrays contains equal values.\n     *\n     * @param {(Boolean|Array)} [keepOrder=false]\n     * @param {Array} target\n     * @returns {Boolean}\n     */\n    function equalArrays(keepOrder, target) {\n        var args = _.toArray(arguments),\n            arrays;\n\n        if (!Array.isArray(keepOrder)) {\n            arrays      = args.slice(2);\n        } else {\n            target      = keepOrder;\n            keepOrder   = false;\n            arrays      = args.slice(1);\n        }\n\n        if (!arrays.length) {\n            return true;\n        }\n\n        return arrays.every(function (array) {\n            if (array === target) {\n                return true;\n            } else if (array.length !== target.length) {\n                return false;\n            } else if (!keepOrder) {\n                return !_.difference(target, array).length;\n            }\n\n            return array.every(function (value, index) {\n                return target[index] === value;\n            });\n        });\n    }\n\n    /**\n     * Checks if two values are different.\n     *\n     * @param {*} a - First value.\n     * @param {*} b - Second value.\n     * @returns {Boolean}\n     */\n    function isDifferent(a, b) {\n        var oldIsPrimitive = utils.isPrimitive(a);\n\n        if (Array.isArray(a) && Array.isArray(b)) {\n            return !equalArrays(true, a, b);\n        }\n\n        return oldIsPrimitive ? a !== b : true;\n    }\n\n    /**\n     * @param {String} prefix\n     * @param {String} part\n     */\n    function getPath(prefix, part) {\n        return prefix ? prefix + '.' + part : part;\n    }\n\n    /**\n     * Checks if object has own specified property.\n     *\n     * @param {*} obj - Value to be checked.\n     * @param {String} key - Key of the property.\n     * @returns {Boolean}\n     */\n    function hasOwn(obj, key) {\n        return Object.prototype.hasOwnProperty.call(obj, key);\n    }\n\n    /**\n     * @param {Array} changes\n     */\n    function getContainers(changes) {\n        var containers  = {},\n            indexed     = _.indexBy(changes, 'path');\n\n        _.each(indexed, function (change, name) {\n            var path;\n\n            name.split('.').forEach(function (part) {\n                path = getPath(path, part);\n\n                if (path in indexed) {\n                    return;\n                }\n\n                (containers[path] = containers[path] || []).push(change);\n            });\n        });\n\n        return containers;\n    }\n\n    /**\n     * @param {String} path\n     * @param {String} name\n     * @param {String} type\n     * @param {String} newValue\n     * @param {String} oldValue\n     */\n    function addChange(path, name, type, newValue, oldValue) {\n        var data;\n\n        data = {\n            path: path,\n            name: name,\n            type: type\n        };\n\n        if (type !== 'remove') {\n            data.value = newValue;\n            data.oldValue = oldValue;\n        } else {\n            data.oldValue = newValue;\n        }\n\n        result.push(data);\n    }\n\n    /**\n     * @param {String} ns\n     * @param {String} name\n     * @param {String} type\n     * @param {String} iterator\n     * @param {String} placeholder\n     */\n    function setAll(ns, name, type, iterator, placeholder) {\n        var key;\n\n        if (arguments.length > 4) {\n            type === 'add' ?\n                addChange(ns, name, 'update', iterator, placeholder) :\n                addChange(ns, name, 'update', placeholder, iterator);\n        } else {\n            addChange(ns, name, type, iterator);\n        }\n\n        if (!utils.isObject(iterator)) {\n            return;\n        }\n\n        for (key in iterator) {\n            if (hasOwn(iterator, key)) {\n                setAll(getPath(ns, key), key, type, iterator[key]);\n            }\n        }\n    }\n\n    /*eslint-disable max-depth*/\n    /**\n     * @param {Object} old\n     * @param {Object} current\n     * @param {String} ns\n     * @param {String} name\n     */\n    function compare(old, current, ns, name) {\n        var key,\n            oldIsObj = utils.isObject(old),\n            newIsObj = utils.isObject(current);\n\n        if (oldIsObj && newIsObj) {\n            for (key in old) {\n                if (hasOwn(old, key) && !hasOwn(current, key)) {\n                    setAll(getPath(ns, key), key, 'remove', old[key]);\n                }\n            }\n\n            for (key in current) {\n                if (hasOwn(current, key)) {\n                    hasOwn(old, key) ?\n                        compare(old[key], current[key], getPath(ns, key), key) :\n                        setAll(getPath(ns, key), key, 'add', current[key]);\n                }\n            }\n        } else if (oldIsObj) {\n            setAll(ns, name, 'remove', old, current);\n        } else if (newIsObj) {\n            setAll(ns, name, 'add', current, old);\n        } else if (isDifferent(old, current)) {\n            addChange(ns, name, 'update', current, old);\n        }\n    }\n\n    /*eslint-enable max-depth*/\n\n    return {\n\n        /**\n         *\n         * @returns {Object}\n         */\n        compare: function () {\n            var changes;\n\n            compare.apply(null, arguments);\n\n            changes = result.splice(0);\n\n            return {\n                containers: getContainers(changes),\n                changes: changes,\n                equal: !changes.length\n            };\n        },\n\n        equalArrays: equalArrays\n    };\n});\n","Magento_ProductAlert/js/form-submitter.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    return function (data, element) {\n\n        $(element).trigger('submit');\n    };\n});\n","Magento_OfflinePayments/js/view/payment/offline-payments.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'uiComponent',\n    'Magento_Checkout/js/model/payment/renderer-list'\n], function (Component, rendererList) {\n    'use strict';\n\n    rendererList.push(\n        {\n            type: 'checkmo',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method'\n        },\n        {\n            type: 'banktransfer',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/banktransfer-method'\n        },\n        {\n            type: 'cashondelivery',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method'\n        },\n        {\n            type: 'purchaseorder',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method'\n        }\n    );\n\n    /** Add view logic here if needed */\n    return Component.extend({});\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/banktransfer-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'ko',\n    'Magento_Checkout/js/view/payment/default'\n], function (ko, Component) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/banktransfer'\n        },\n\n        /**\n         * Get value of instruction field.\n         * @returns {String}\n         */\n        getInstructions: function () {\n            return window.checkoutConfig.payment.instructions[this.item.method];\n        }\n    });\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'Magento_Checkout/js/view/payment/default',\n    'jquery',\n    'mage/validation'\n], function (Component, $) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/purchaseorder-form',\n            purchaseOrderNumber: ''\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('purchaseOrderNumber');\n\n            return this;\n        },\n\n        /**\n         * @return {Object}\n         */\n        getData: function () {\n            return {\n                method: this.item.method,\n                'po_number': this.purchaseOrderNumber(),\n                'additional_data': null\n            };\n        },\n\n        /**\n         * @return {jQuery}\n         */\n        validate: function () {\n            var form = 'form[data-role=purchaseorder-form]';\n\n            return $(form).validation() && $(form).validation('isValid');\n        }\n    });\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'Magento_Checkout/js/view/payment/default'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/checkmo'\n        },\n\n        /**\n         * Returns send check to info.\n         *\n         * @return {*}\n         */\n        getMailingAddress: function () {\n            return window.checkoutConfig.payment.checkmo.mailingAddress;\n        },\n\n        /**\n         * Returns payable to info.\n         *\n         * @return {*}\n         */\n        getPayableTo: function () {\n            return window.checkoutConfig.payment.checkmo.payableTo;\n        }\n    });\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'Magento_Checkout/js/view/payment/default'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/cashondelivery'\n        },\n\n        /**\n         * Returns payment method instructions.\n         *\n         * @return {*}\n         */\n        getInstructions: function () {\n            return window.checkoutConfig.payment.instructions[this.item.method];\n        }\n    });\n});\n","Magento_InstantPurchase/js/view/instant-purchase.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'jquery',\n    'underscore',\n    'uiComponent',\n    'Magento_Ui/js/modal/confirm',\n    'Magento_Customer/js/customer-data',\n    'mage/url',\n    'mage/template',\n    'mage/translate',\n    'text!Magento_InstantPurchase/template/confirmation.html',\n    'mage/validation'\n], function (ko, $, _, Component, confirm, customerData, urlBuilder, mageTemplate, $t, confirmationTemplate) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_InstantPurchase/instant-purchase',\n            buttonText: $t('Instant Purchase'),\n            purchaseUrl: urlBuilder.build('instantpurchase/button/placeOrder'),\n            showButton: false,\n            paymentToken: null,\n            shippingAddress: null,\n            billingAddress: null,\n            shippingMethod: null,\n            productFormSelector: '#product_addtocart_form',\n            confirmationTitle: $t('Instant Purchase Confirmation'),\n            confirmationData: {\n                message: $t('Are you sure you want to place order and pay?'),\n                shippingAddressTitle: $t('Shipping Address'),\n                billingAddressTitle: $t('Billing Address'),\n                paymentMethodTitle: $t('Payment Method'),\n                shippingMethodTitle: $t('Shipping Method')\n            }\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            var instantPurchase = customerData.get('instant-purchase');\n\n            this._super();\n\n            this.setPurchaseData(instantPurchase());\n            instantPurchase.subscribe(this.setPurchaseData, this);\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('showButton paymentToken shippingAddress billingAddress shippingMethod');\n\n            return this;\n        },\n\n        /**\n         * Set data from customerData.\n         *\n         * @param {Object} data\n         */\n        setPurchaseData: function (data) {\n            this.showButton(data.available);\n            this.paymentToken(data.paymentToken);\n            this.shippingAddress(data.shippingAddress);\n            this.billingAddress(data.billingAddress);\n            this.shippingMethod(data.shippingMethod);\n        },\n\n        /**\n         * Confirmation method\n         */\n        instantPurchase: function () {\n            var form = $(this.productFormSelector),\n                confirmTemplate = mageTemplate(confirmationTemplate),\n                confirmData = _.extend({}, this.confirmationData, {\n                    paymentToken: this.paymentToken().summary,\n                    shippingAddress: this.shippingAddress().summary,\n                    billingAddress: this.billingAddress().summary,\n                    shippingMethod: this.shippingMethod().summary\n                });\n\n            if (!(form.validation() && form.validation('isValid'))) {\n                return;\n            }\n\n            confirm({\n                title: this.confirmationTitle,\n                content: confirmTemplate({\n                    data: confirmData\n                }),\n                actions: {\n                    /** @inheritdoc */\n                    confirm: function () {\n                        $.ajax({\n                            url: this.purchaseUrl,\n                            data: form.serialize(),\n                            type: 'post',\n                            dataType: 'json',\n\n                            /** Show loader before send */\n                            beforeSend: function () {\n                                $('body').trigger('processStart');\n                            }\n                        }).always(function () {\n                            $('body').trigger('processStop');\n                        });\n                    }.bind(this)\n                }\n            });\n        }\n    });\n});\n","Smartwave_Megamenu/js/sw_megamenu.js":"(function (factory) {\n    'use strict';\n\n    if (typeof define === 'function' && define.amd) {\n        define([\n            'jquery'\n        ], factory);\n    } else {\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n\n    $.fn.swMegamenu = function() {\n        $(\".navigation.sw-megamenu li.classic .submenu, .navigation.sw-megamenu li.staticwidth .submenu, .navigation.sw-megamenu li.classic .subchildmenu .subchildmenu\").each(function(){\n            $(this).css(\"left\",\"-9999px\");\n            $(this).css(\"right\",\"auto\");\n        });\n        $(this).find(\"li.classic .subchildmenu > li.parent\").mouseover(function(){\n            var popup = $(this).children(\"ul.subchildmenu\");\n            var w_width = $(window).innerWidth();\n\n            if(popup) {\n                var pos = $(this).offset();\n                var c_width = $(popup).outerWidth();\n                if(w_width <= pos.left + $(this).outerWidth() + c_width) {\n                    $(popup).css(\"left\",\"auto\");\n                    $(popup).css(\"right\",\"100%\");\n                } else {\n                    $(popup).css(\"left\",\"100%\");\n                    $(popup).css(\"right\",\"auto\");\n                }\n            }\n        });\n        $(this).find(\"li.staticwidth.parent,li.classic.parent\").mouseover(function(){\n            var popup = $(this).children(\".submenu\");\n            var w_width = $(window).innerWidth();\n\n            if(popup) {\n                var pos = $(this).offset();\n                var c_width = $(popup).outerWidth();\n                if(w_width <= pos.left + $(this).outerWidth() + c_width) {\n                    $(popup).css(\"left\",\"auto\");\n                    $(popup).css(\"right\",\"0\");\n                } else {\n                    $(popup).css(\"left\",\"0\");\n                    $(popup).css(\"right\",\"auto\"); \n                }\n            }\n        });\n        $(window).resize(function(){\n            $(\".navigation.sw-megamenu li.classic .submenu, .navigation.sw-megamenu li.staticwidth .submenu, .navigation.sw-megamenu li.classic .subchildmenu .subchildmenu\").each(function(){\n                $(this).css(\"left\",\"-9999px\");\n                $(this).css(\"right\",\"auto\");\n            });\n        });\n        $(\".nav-toggle\").off('click').on('click',function(e){\n            if(!$(\"html\").hasClass(\"nav-open\")) {\n                $(\"html\").addClass(\"nav-before-open\");\n                setTimeout(function(){\n                    $(\"html\").addClass(\"nav-open\");\n                }, 300);\n            }\n            else {\n                $(\"html\").removeClass(\"nav-open\");\n                setTimeout(function(){\n                    $(\"html\").removeClass(\"nav-before-open\");\n                }, 300);\n            }\n        });\n        $(\"li.ui-menu-item > .open-children-toggle\").off(\"click\").on(\"click\", function(){\n            if(!$(this).parent().children(\".submenu\").hasClass(\"opened\")) {\n                $(this).parent().children(\".submenu\").addClass(\"opened\");\n                $(this).parent().children(\"a\").addClass(\"ui-state-active\");\n            }\n            else {\n                $(this).parent().children(\".submenu\").removeClass(\"opened\");\n                $(this).parent().children(\"a\").removeClass(\"ui-state-active\");\n            }\n        });\n    };\n}));\n","Magento_Variable/js/grid/columns/radioselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'mage/translate',\n    'Magento_Ui/js/grid/columns/column',\n    'jquery'\n], function (_, $t, Column, jQuery) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            bodyTmpl: 'Magento_Variable/grid/cells/radioselect',\n            draggable: false,\n            sortable: false,\n            selectedVariableCode: null,\n            selectedVariableType: null\n        },\n\n        /**\n         * Calls 'initObservable' of parent\n         *\n         * @returns {Object} Chainable.\n         */\n        initObservable: function () {\n            this._super().observe(['selectedVariableCode']);\n\n            return this;\n        },\n\n        /**\n         * Remove disable class from Insert Variable button after Variable has been chosen.\n         *\n         * @return {Boolean}\n         */\n        selectVariable: function () {\n            if (jQuery('#insert_variable').hasClass('disabled')) {\n                jQuery('#insert_variable').removeClass('disabled');\n            }\n\n            return true;\n        }\n    });\n});\n","Magento_ReCaptchaFrontendUi/js/reCaptchaScriptLoader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    var scriptTagAdded = false;\n\n    return {\n        /**\n         * Add script tag. Script tag should be added once\n         */\n        addReCaptchaScriptTag: function () {\n            var element, scriptTag;\n\n            if (!scriptTagAdded) {\n                element = document.createElement('script');\n                scriptTag = document.getElementsByTagName('script')[0];\n\n                element.async = true;\n                element.src = 'https://www.google.com/recaptcha/api.js' +\n                    '?onload=globalOnRecaptchaOnLoadCallback&render=explicit';\n\n                scriptTag.parentNode.insertBefore(element, scriptTag);\n                scriptTagAdded = true;\n            }\n        }\n    };\n});\n","Magento_ReCaptchaFrontendUi/js/ui-messages-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['Magento_ReCaptchaFrontendUi/js/registry'], function (registry) {\n    'use strict';\n\n    return function (originalComponent) {\n        return originalComponent.extend({\n            /**\n             * Initialize reset on messages\n             * @returns {initialize}\n             */\n            initialize: function () {\n                this._super();\n\n                this.messageContainer.errorMessages.subscribe(function () {\n                    var\n                        i,\n                        captchaList = registry.captchaList(),\n                        tokenFieldsList = registry.tokenFields();\n\n                    for (i = 0; i < captchaList.length; i++) {\n                        // eslint-disable-next-line no-undef\n                        grecaptcha.reset(captchaList[i]);\n\n                        if (tokenFieldsList[i]) {\n                            tokenFieldsList[i].value = '';\n                        }\n                    }\n                }, null, 'arrayChange');\n\n                return this;\n            }\n        });\n    };\n});\n","Magento_ReCaptchaFrontendUi/js/reCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global grecaptcha */\ndefine(\n    [\n        'uiComponent',\n        'jquery',\n        'ko',\n        'underscore',\n        'Magento_ReCaptchaFrontendUi/js/registry',\n        'Magento_ReCaptchaFrontendUi/js/reCaptchaScriptLoader',\n        'Magento_ReCaptchaFrontendUi/js/nonInlineReCaptchaRenderer'\n    ], function (Component, $, ko, _, registry, reCaptchaLoader, nonInlineReCaptchaRenderer) {\n        'use strict';\n\n        return Component.extend({\n\n            defaults: {\n                template: 'Magento_ReCaptchaFrontendUi/reCaptcha',\n                reCaptchaId: 'recaptcha'\n            },\n\n            /**\n             * @inheritdoc\n             */\n            initialize: function () {\n                this._super();\n                this._loadApi();\n            },\n\n            /**\n             * Loads recaptchaapi API and triggers event, when loaded\n             * @private\n             */\n            _loadApi: function () {\n                if (this._isApiRegistered !== undefined) {\n                    if (this._isApiRegistered === true) {\n                        $(window).trigger('recaptchaapiready');\n                    }\n\n                    return;\n                }\n                this._isApiRegistered = false;\n\n                // global function\n                window.globalOnRecaptchaOnLoadCallback = function () {\n                    this._isApiRegistered = true;\n                    $(window).trigger('recaptchaapiready');\n                }.bind(this);\n\n                reCaptchaLoader.addReCaptchaScriptTag();\n            },\n\n            /**\n             * Checking that reCAPTCHA is invisible type\n             * @returns {Boolean}\n             */\n            getIsInvisibleRecaptcha: function () {\n                if (this.settings ===\n\n                    void 0) {\n                    return false;\n                }\n\n                return this.settings.invisible;\n            },\n\n            /**\n             * reCAPTCHA callback\n             * @param {String} token\n             */\n            reCaptchaCallback: function (token) {\n                if (this.getIsInvisibleRecaptcha()) {\n                    this.tokenField.value = token;\n                    this.$parentForm.submit();\n                }\n            },\n\n            /**\n             * Initialize reCAPTCHA after first rendering\n             */\n            initCaptcha: function () {\n                var $parentForm,\n                    $wrapper,\n                    $reCaptcha,\n                    widgetId,\n                    parameters;\n\n                if (this.captchaInitialized || this.settings ===\n\n                    void 0) {\n                    return;\n                }\n\n                this.captchaInitialized = true;\n\n                /*\n                 * Workaround for data-bind issue:\n                 * We cannot use data-bind to link a dynamic id to our component\n                 * See:\n                 * https://stackoverflow.com/questions/46657573/recaptcha-the-bind-parameter-must-be-an-element-or-id\n                 *\n                 * We create a wrapper element with a wrapping id and we inject the real ID with jQuery.\n                 * In this way we have no data-bind attribute at all in our reCAPTCHA div\n                 */\n                $wrapper = $('#' + this.getReCaptchaId() + '-wrapper');\n                $reCaptcha = $wrapper.find('.g-recaptcha');\n                $reCaptcha.attr('id', this.getReCaptchaId());\n\n                $parentForm = $wrapper.parents('form');\n\n                if (this.settings === undefined) {\n\n                    return;\n                }\n\n                parameters = _.extend(\n                    {\n                        'callback': function (token) { // jscs:ignore jsDoc\n                            this.reCaptchaCallback(token);\n                            this.validateReCaptcha(true);\n                        }.bind(this),\n                        'expired-callback': function () {\n                            this.validateReCaptcha(false);\n                        }.bind(this)\n                    },\n                    this.settings.rendering\n                );\n\n                if (parameters.size === 'invisible' && parameters.badge !== 'inline') {\n                    nonInlineReCaptchaRenderer.add($reCaptcha, parameters);\n                }\n\n                // eslint-disable-next-line no-undef\n                widgetId = grecaptcha.render(this.getReCaptchaId(), parameters);\n                this.initParentForm($parentForm, widgetId);\n\n                registry.ids.push(this.getReCaptchaId());\n                registry.captchaList.push(widgetId);\n                registry.tokenFields.push(this.tokenField);\n\n            },\n\n            /**\n             * Initialize parent form.\n             *\n             * @param {Object} parentForm\n             * @param {String} widgetId\n             */\n            initParentForm: function (parentForm, widgetId) {\n                var listeners;\n\n                if (this.getIsInvisibleRecaptcha() && parentForm.length > 0) {\n                    parentForm.submit(function (event) {\n                        if (!this.tokenField.value) {\n                            // eslint-disable-next-line no-undef\n                            grecaptcha.execute(widgetId);\n                            event.preventDefault(event);\n                            event.stopImmediatePropagation();\n                        }\n                    }.bind(this));\n\n                    // Move our (last) handler topmost. We need this to avoid submit bindings with ko.\n                    listeners = $._data(parentForm[0], 'events').submit;\n                    listeners.unshift(listeners.pop());\n\n                    // Create a virtual token field\n                    this.tokenField = $('<input type=\"text\" name=\"token\" style=\"display: none\" />')[0];\n                    this.$parentForm = parentForm;\n                    parentForm.append(this.tokenField);\n                } else {\n                    this.tokenField = null;\n                }\n                if ($('#send2').length > 0) {$('#send2').prop('disabled', false);}\n            },\n\n            /**\n             * Validates reCAPTCHA\n             * @param {*} state\n             * @returns {jQuery}\n             */\n            validateReCaptcha: function (state) {\n                if (!this.getIsInvisibleRecaptcha()) {\n                    return $(document).find('input[type=checkbox].required-captcha').prop('checked', state);\n                }\n            },\n\n            /**\n             * Render reCAPTCHA\n             */\n            renderReCaptcha: function () {\n                if (window.grecaptcha && window.grecaptcha.render) { // Check if reCAPTCHA is already loaded\n                    this.initCaptcha();\n                } else { // Wait for reCAPTCHA to be loaded\n                    $(window).on('recaptchaapiready', function () {\n                        this.initCaptcha();\n                    }.bind(this));\n                }\n            },\n\n            /**\n             * Get reCAPTCHA ID\n             * @returns {String}\n             */\n            getReCaptchaId: function () {\n                return this.reCaptchaId;\n            }\n        });\n    });\n","Magento_ReCaptchaFrontendUi/js/registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['ko'], function (ko) {\n    'use strict';\n\n    return {\n        ids: ko.observableArray([]),\n        captchaList: ko.observableArray([]),\n        tokenFields: ko.observableArray([])\n    };\n});\n","Magento_ReCaptchaFrontendUi/js/nonInlineReCaptchaRenderer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global grecaptcha */\ndefine([\n    'jquery',\n    'jquery/z-index'\n], function ($) {\n    'use strict';\n\n    var reCaptchaEntities = [],\n        initialized = false,\n        rendererRecaptchaId = 'recaptcha-invisible',\n        rendererReCaptcha = null;\n\n    return {\n        /**\n         * Add reCaptcha entity to checklist.\n         *\n         * @param {jQuery} reCaptchaEntity\n         * @param {Object} parameters\n         */\n        add: function (reCaptchaEntity, parameters) {\n            if (!initialized) {\n                this.init();\n                grecaptcha.render(rendererRecaptchaId, parameters);\n                setInterval(this.resolveVisibility, 100);\n                initialized = true;\n            }\n\n            reCaptchaEntities.push(reCaptchaEntity);\n        },\n\n        /**\n         * Show additional reCaptcha instance if any other should be visible, otherwise hide it.\n         */\n        resolveVisibility: function () {\n            reCaptchaEntities.some(function (entity) {\n                return entity.is(':visible') &&\n                    // 900 is some magic z-index value of modal popups.\n                    (entity.closest('[data-role=\\'modal\\']').length === 0 || entity.zIndex() > 900);\n            }) ? rendererReCaptcha.show() : rendererReCaptcha.hide();\n        },\n\n        /**\n         * Initialize additional reCaptcha instance.\n         */\n        init: function () {\n            rendererReCaptcha = $('<div/>', {\n                'id': rendererRecaptchaId\n            });\n            rendererReCaptcha.hide();\n            $('body').append(rendererReCaptcha);\n        }\n    };\n});\n","Magento_InventoryInStorePickupFrontend/js/checkout-data-ext.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Customer/js/customer-data'\n], function (\n    storage\n) {\n    'use strict';\n\n    return function (checkoutData) {\n\n        var cacheKey = 'checkout-data',\n\n            /**\n             * @param {Object} data\n             */\n            saveData = function (data) {\n                storage.set(cacheKey, data);\n            },\n\n            /**\n             * @return {Object}\n             */\n            getData = function () {\n                //Makes sure that checkout storage is initiated (any method can be used)\n                checkoutData.getSelectedShippingAddress();\n\n                return storage.get(cacheKey)();\n            };\n\n        /**\n         * Save the pickup address in persistence storage\n         *\n         * @param {Object} data\n         */\n        checkoutData.setSelectedPickupAddress = function (data) {\n            var obj = getData();\n\n            obj.selectedPickupAddress = data;\n            saveData(obj);\n        };\n\n        /**\n         * Get the pickup address from persistence storage\n         *\n         * @return {*}\n         */\n        checkoutData.getSelectedPickupAddress = function () {\n            return getData().selectedPickupAddress || null;\n        };\n\n        return checkoutData;\n    };\n});\n","Magento_InventoryInStorePickupFrontend/js/view/store-pickup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'underscore',\n    'jquery',\n    'knockout',\n    'uiRegistry',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/action/select-shipping-method',\n    'Magento_Checkout/js/checkout-data',\n    'Magento_Checkout/js/model/shipping-service',\n    'Magento_Checkout/js/model/step-navigator',\n    'Magento_Checkout/js/model/shipping-rate-service',\n    'Magento_InventoryInStorePickupFrontend/js/model/shipping-rate-processor/store-pickup-address',\n    'Magento_InventoryInStorePickupFrontend/js/model/pickup-locations-service',\n    'Magento_InventoryInStorePickupFrontend/js/model/pickup-address-converter',\n    'Magento_Checkout/js/model/checkout-data-resolver',\n    'Magento_Checkout/js/action/select-shipping-address'\n], function (\n    Component,\n    _,\n    $,\n    ko,\n    registry,\n    quote,\n    selectShippingMethodAction,\n    checkoutData,\n    shippingService,\n    stepNavigator,\n    shippingRateService,\n    shippingRateProcessor,\n    pickupLocationsService,\n    pickupAddressConverter,\n    checkoutDataResolver,\n    selectShippingAddress\n) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_InventoryInStorePickupFrontend/store-pickup',\n            deliveryMethodSelectorTemplate: 'Magento_InventoryInStorePickupFrontend/delivery-method-selector',\n            isVisible: false,\n            isAvailable: false,\n            isStorePickupSelected: false,\n            rate: {\n                'carrier_code': 'instore',\n                'method_code': 'pickup'\n            },\n            nearbySearchLimit: 50,\n            defaultCountry: window.checkoutConfig.defaultCountryId,\n            delimiter: window.checkoutConfig.storePickupApiSearchTermDelimiter,\n            rates: shippingService.getShippingRates(),\n            inStoreMethod: null,\n            lastSelectedNonPickUpShippingAddress: null\n        },\n\n        /**\n         * @inheritdoc\n         */\n        initialize: function () {\n            this._super();\n\n            shippingRateService.registerProcessor('store-pickup-address', shippingRateProcessor);\n\n            this.convertAddressType(quote.shippingAddress());\n\n            this.isStorePickupSelected.subscribe(function () {\n                this.preselectLocation();\n            }, this);\n            this.preselectLocation();\n\n            this.syncWithShipping();\n        },\n\n        /**\n         * Init component observable variables\n         *\n         * @return {exports}\n         */\n        initObservable: function () {\n            this._super().observe(['isVisible']);\n\n            this.isStorePickupSelected = ko.pureComputed(function () {\n                return _.isMatch(quote.shippingMethod(), this.rate);\n            }, this);\n\n            this.isAvailable = ko.pureComputed(function () {\n                return _.findWhere(this.rates(), {\n                    'carrier_code': this.rate['carrier_code'],\n                    'method_code': this.rate['method_code']\n                });\n            }, this);\n\n            return this;\n        },\n\n        /**\n         * Synchronize store pickup visibility with shipping step.\n         *\n         * @returns void\n         */\n        syncWithShipping: function () {\n            var shippingStep = _.findWhere(stepNavigator.steps(), {\n                code: 'shipping'\n            });\n\n            shippingStep.isVisible.subscribe(function (isShippingVisible) {\n                this.isVisible(this.isAvailable && isShippingVisible);\n            }, this);\n            this.isVisible(this.isAvailable && shippingStep.isVisible());\n        },\n\n        /**\n         * @returns void\n         */\n        selectShipping: function () {\n            var nonPickupShippingMethod = _.find(\n                this.rates(),\n                function (rate) {\n                    return (\n                        rate['carrier_code'] !== this.rate['carrier_code'] &&\n                        rate['method_code'] !== this.rate['method_code']\n                    );\n                },\n                this\n            ),\n                nonPickupShippingAddress;\n\n            checkoutData.setSelectedShippingAddress(this.lastSelectedNonPickUpShippingAddress);\n            this.selectShippingMethod(nonPickupShippingMethod);\n\n            if (this.isStorePickupAddress(quote.shippingAddress())) {\n                nonPickupShippingAddress = checkoutDataResolver.getShippingAddressFromCustomerAddressList();\n\n                if (nonPickupShippingAddress) {\n                    selectShippingAddress(nonPickupShippingAddress);\n                }\n            }\n        },\n\n        /**\n         * @returns void\n         */\n        selectStorePickup: function () {\n            var pickupShippingMethod = _.findWhere(\n                this.rates(),\n                {\n                    'carrier_code': this.rate['carrier_code'],\n                    'method_code': this.rate['method_code']\n                },\n                this\n            );\n\n            this.lastSelectedNonPickUpShippingAddress = checkoutData.getSelectedShippingAddress();\n            checkoutData.setSelectedShippingAddress(null);\n            this.preselectLocation();\n            this.selectShippingMethod(pickupShippingMethod);\n        },\n\n        /**\n         * @param {Object} shippingMethod\n         */\n        selectShippingMethod: function (shippingMethod) {\n            selectShippingMethodAction(shippingMethod);\n            checkoutData.setSelectedShippingRate(\n                shippingMethod ? shippingMethod['carrier_code'] + '_' + shippingMethod['method_code'] : null\n            );\n        },\n\n        /**\n         * @param {Object} shippingAddress\n         * @returns void\n         */\n        convertAddressType: function (shippingAddress) {\n            var pickUpAddress;\n\n            if (\n                !this.isStorePickupAddress(shippingAddress) &&\n                this.isStorePickupSelected()\n            ) {\n                pickUpAddress = pickupAddressConverter.formatAddressToPickupAddress(shippingAddress);\n\n                if (quote.shippingAddress() !== pickUpAddress) {\n                    quote.shippingAddress(pickUpAddress);\n                }\n            }\n        },\n\n        /**\n         * @returns void\n         */\n        preselectLocation: function () {\n            var selectedLocation,\n                shippingAddress,\n                selectedPickupAddress,\n                customAttributes,\n                selectedSource,\n                selectedSourceCode,\n                nearestLocation,\n                productsInfo = [],\n                items = quote.getItems();\n\n            if (!this.isStorePickupSelected()) {\n                return;\n            }\n\n            selectedLocation = pickupLocationsService.selectedLocation();\n\n            if (selectedLocation) {\n                pickupLocationsService.selectForShipping(selectedLocation);\n\n                return;\n            }\n\n            shippingAddress = quote.shippingAddress();\n            customAttributes = shippingAddress.customAttributes || [];\n            selectedSource = _.findWhere(customAttributes, {\n                'attribute_code': 'sourceCode'\n            });\n\n            if (selectedSource) {\n                selectedSourceCode = selectedSource.value;\n            }\n\n            if (!selectedSourceCode) {\n                selectedSourceCode = this.getPickupLocationCodeFromAddress(shippingAddress);\n            }\n\n            if (!selectedSourceCode) {\n                selectedPickupAddress = pickupLocationsService.getSelectedPickupAddress();\n                selectedSourceCode = this.getPickupLocationCodeFromAddress(selectedPickupAddress);\n            }\n\n            if (selectedSourceCode) {\n                pickupLocationsService\n                    .getLocation(selectedSourceCode)\n                    .then(function (location) {\n                        pickupLocationsService.selectForShipping(location);\n                    });\n            } else if (shippingAddress.city && shippingAddress.postcode) {\n                _.each(items, function (item) {\n                    if (item['qty_options'] === undefined || item['qty_options'].length === 0) {\n                        productsInfo.push(\n                            {\n                                sku: item.sku\n                            }\n                        );\n                    }\n                });\n                pickupLocationsService\n                    .getNearbyLocations({\n                        area: {\n                            radius: this.nearbySearchRadius,\n                            searchTerm: shippingAddress.postcode + this.delimiter +\n                                        shippingAddress.countryId || this.defaultCountry\n                        },\n                        extensionAttributes: {\n                            productsInfo: productsInfo\n                        },\n                        pageSize: this.nearbySearchLimit\n                    })\n                    .then(function (locations) {\n                        nearestLocation = locations[0];\n\n                        if (nearestLocation) {\n                            pickupLocationsService.selectForShipping(\n                                nearestLocation\n                            );\n                        }\n                    });\n            }\n        },\n\n        /**\n         * @param {Object} address\n         * @returns {Boolean}\n         */\n        isStorePickupAddress: function (address) {\n            return address.getType() === 'store-pickup-address';\n        },\n\n        /**\n         * @param {Object} address\n         * @returns {String|null}\n         */\n        getPickupLocationCodeFromAddress: function (address) {\n            if (address &&\n                !_.isEmpty(address.extensionAttributes) &&\n                address.extensionAttributes['pickup_location_code']\n            ) {\n                return address.extensionAttributes['pickup_location_code'];\n            }\n\n            return null;\n        }\n    });\n});\n","Magento_InventoryInStorePickupFrontend/js/view/shipping-information-ext.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Checkout/js/model/quote'\n], function (quote) {\n    'use strict';\n\n    var storePickupShippingInformation = {\n        defaults: {\n            template: 'Magento_InventoryInStorePickupFrontend/shipping-information'\n        },\n\n        /**\n         * Get shipping method title based on delivery method.\n         *\n         * @return {String}\n         */\n        getShippingMethodTitle: function () {\n            var shippingMethod = quote.shippingMethod(),\n                locationName = '',\n                title;\n\n            if (!this.isStorePickup()) {\n\n                return this._super();\n            }\n\n            title = shippingMethod['carrier_title'] + ' - ' + shippingMethod['method_title'];\n\n            if (quote.shippingAddress().firstname !== undefined) {\n                locationName = quote.shippingAddress().firstname + ' ' + quote.shippingAddress().lastname;\n                title += ' \"' + locationName + '\"';\n            }\n\n            return title;\n        },\n\n        /**\n         * Get is store pickup delivery method selected.\n         *\n         * @returns {Boolean}\n         */\n        isStorePickup: function () {\n            var shippingMethod = quote.shippingMethod(),\n                isStorePickup = false;\n\n            if (shippingMethod !== null) {\n                isStorePickup = shippingMethod['carrier_code'] === 'instore' &&\n                    shippingMethod['method_code'] === 'pickup';\n            }\n\n            return isStorePickup;\n        }\n    };\n\n    return function (shippingInformation) {\n        return shippingInformation.extend(storePickupShippingInformation);\n    };\n});\n","Magento_InventoryInStorePickupFrontend/js/view/store-selector.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'uiComponent',\n    'uiRegistry',\n    'Magento_Ui/js/modal/modal',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Customer/js/model/customer',\n    'Magento_Checkout/js/model/step-navigator',\n    'Magento_Checkout/js/model/address-converter',\n    'Magento_Checkout/js/action/set-shipping-information',\n    'Magento_InventoryInStorePickupFrontend/js/model/pickup-locations-service'\n], function (\n    $,\n    _,\n    Component,\n    registry,\n    modal,\n    quote,\n    customer,\n    stepNavigator,\n    addressConverter,\n    setShippingInformationAction,\n    pickupLocationsService\n) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_InventoryInStorePickupFrontend/store-selector',\n            selectedLocationTemplate:\n                'Magento_InventoryInStorePickupFrontend/store-selector/selected-location',\n            storeSelectorPopupTemplate:\n                'Magento_InventoryInStorePickupFrontend/store-selector/popup',\n            storeSelectorPopupItemTemplate:\n                'Magento_InventoryInStorePickupFrontend/store-selector/popup-item',\n            loginFormSelector:\n                '#store-selector form[data-role=email-with-possible-login]',\n            defaultCountryId: window.checkoutConfig.defaultCountryId,\n            delimiter: window.checkoutConfig.storePickupApiSearchTermDelimiter,\n            selectedLocation: pickupLocationsService.selectedLocation,\n            quoteIsVirtual: quote.isVirtual,\n            searchQuery: '',\n            nearbyLocations: null,\n            isLoading: pickupLocationsService.isLoading,\n            popup: null,\n            searchDebounceTimeout: 300,\n            imports: {\n                nearbySearchRadius: '${ $.parentName }:nearbySearchRadius',\n                nearbySearchLimit: '${ $.parentName }:nearbySearchLimit'\n            }\n        },\n\n        /**\n         * Init component\n         *\n         * @return {exports}\n         */\n        initialize: function () {\n            var updateNearbyLocations, country;\n\n            this._super();\n\n            updateNearbyLocations = _.debounce(function (searchQuery) {\n                country = quote.shippingAddress() && quote.shippingAddress().countryId ?\n                    quote.shippingAddress().countryId : this.defaultCountryId;\n                searchQuery = this.getSearchTerm(searchQuery, country);\n                this.updateNearbyLocations(searchQuery);\n            }, this.searchDebounceTimeout).bind(this);\n            this.searchQuery.subscribe(updateNearbyLocations);\n\n            return this;\n        },\n\n        /**\n         * Init component observable variables\n         *\n         * @return {exports}\n         */\n        initObservable: function () {\n            return this._super().observe(['nearbyLocations', 'searchQuery']);\n        },\n\n        /**\n         * Set shipping information handler\n         */\n        setPickupInformation: function () {\n            if (this.validatePickupInformation()) {\n                setShippingInformationAction().done(function () {\n                    stepNavigator.next();\n                });\n            }\n        },\n\n        /**\n         * @return {*}\n         */\n        getPopup: function () {\n            if (!this.popup) {\n                this.popup = modal(\n                    this.popUpList.options,\n                    $(this.popUpList.element)\n                );\n            }\n\n            return this.popup;\n        },\n\n        /**\n         * Get Search Term from search query and country.\n         *\n         * @param {String} searchQuery\n         * @param {String} country\n         * @returns {String}\n         */\n        getSearchTerm: function (searchQuery, country) {\n            return searchQuery ? searchQuery + this.delimiter + country : searchQuery;\n        },\n\n        /**\n         * @returns void\n         */\n        openPopup: function () {\n            var shippingAddress = quote.shippingAddress(),\n                country = shippingAddress.countryId ? shippingAddress.countryId :\n                this.defaultCountryId,\n                searchTerm = '';\n\n            this.getPopup().openModal();\n\n            if (shippingAddress.city && shippingAddress.postcode) {\n                searchTerm = this.getSearchTerm(shippingAddress.postcode, country);\n            }\n\n            this.updateNearbyLocations(searchTerm);\n        },\n\n        /**\n         * @param {Object} location\n         * @returns void\n         */\n        selectPickupLocation: function (location) {\n            pickupLocationsService.selectForShipping(location);\n            this.getPopup().closeModal();\n        },\n\n        /**\n         * @param {Object} location\n         * @returns {*|Boolean}\n         */\n        isPickupLocationSelected: function (location) {\n            return _.isEqual(this.selectedLocation(), location);\n        },\n\n        /**\n         * @param {String} searchQuery\n         * @returns {*}\n         */\n        updateNearbyLocations: function (searchQuery) {\n            var self = this,\n                productsInfo = [],\n                items = quote.getItems(),\n                searchCriteria;\n\n            _.each(items, function (item) {\n                if (item['qty_options'] === undefined || item['qty_options'].length === 0) {\n                    productsInfo.push(\n                        {\n                            sku: item.sku\n                        }\n                    );\n                }\n            });\n\n            searchCriteria = {\n                extensionAttributes: {\n                    productsInfo: productsInfo\n                },\n                pageSize: this.nearbySearchLimit\n            };\n\n            if (searchQuery) {\n                searchCriteria.area = {\n                    radius: this.nearbySearchRadius,\n                    searchTerm: searchQuery\n                };\n            }\n\n            return pickupLocationsService\n                .getNearbyLocations(searchCriteria)\n                .then(function (locations) {\n                    self.nearbyLocations(locations);\n                })\n                .fail(function () {\n                    self.nearbyLocations([]);\n                });\n        },\n\n        /**\n         * @returns {Boolean}\n         */\n        validatePickupInformation: function () {\n            var emailValidationResult,\n                loginFormSelector = this.loginFormSelector;\n\n            if (!customer.isLoggedIn()) {\n                $(loginFormSelector).validation();\n                emailValidationResult = $(loginFormSelector + ' input[name=username]').valid() ? true : false;\n\n                if (!emailValidationResult) {\n                    $(this.loginFormSelector + ' input[name=username]').trigger('focus');\n\n                    return false;\n                }\n            }\n\n            return true;\n        }\n    });\n});\n","Magento_InventoryInStorePickupFrontend/js/view/form/element/email.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['jquery', 'Magento_Checkout/js/view/form/element/email'], function (\n    $,\n    Component\n) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template:\n                'Magento_InventoryInStorePickupFrontend/form/element/email',\n            links: {\n                email:\n                    'checkout.steps.shipping-step.shippingAddress.customer-email:email'\n            }\n        }\n    });\n});\n","Magento_InventoryInStorePickupFrontend/js/model/checkout-data-resolver-ext.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'mage/utils/wrapper',\n    'Magento_Checkout/js/checkout-data',\n    'Magento_Checkout/js/action/select-shipping-address',\n    'Magento_Checkout/js/model/address-converter',\n    'Magento_InventoryInStorePickupFrontend/js/model/pickup-address-converter'\n], function (\n    wrapper,\n    checkoutData,\n    selectShippingAddress,\n    addressConverter,\n    pickupAddressConverter\n) {\n    'use strict';\n\n    return function (checkoutDataResolver) {\n        checkoutDataResolver.resolveShippingAddress = wrapper.wrapSuper(\n            checkoutDataResolver.resolveShippingAddress,\n            function () {\n                var shippingAddress,\n                    pickUpAddress;\n\n                if (checkoutData.getSelectedPickupAddress() && checkoutData.getSelectedShippingAddress()) {\n                    shippingAddress = addressConverter.formAddressDataToQuoteAddress(\n                        checkoutData.getSelectedPickupAddress()\n                    );\n                    pickUpAddress = pickupAddressConverter.formatAddressToPickupAddress(\n                        shippingAddress\n                    );\n\n                    if (pickUpAddress.getKey() === checkoutData.getSelectedShippingAddress()) {\n                        selectShippingAddress(pickUpAddress);\n\n                        return;\n                    }\n                }\n                this._super();\n            });\n\n        return checkoutDataResolver;\n    };\n});\n","Magento_InventoryInStorePickupFrontend/js/model/pickup-address-converter.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(['underscore'], function (_) {\n    'use strict';\n\n    return {\n        /**\n         * Format address to use in store pickup\n         *\n         * @param {Object} address\n         * @return {*}\n         */\n        formatAddressToPickupAddress: function (address) {\n            var sourceCode = _.findWhere(address.customAttributes, {\n                'attribute_code': 'sourceCode'\n            });\n\n            if (!sourceCode &&\n                !_.isEmpty(address.extensionAttributes) &&\n                address.extensionAttributes['pickup_location_code']\n            ) {\n                sourceCode = {\n                    value: address.extensionAttributes['pickup_location_code']\n                };\n            }\n\n            if (sourceCode && address.getType() !== 'store-pickup-address') {\n                address = _.extend({}, address, {\n                    saveInAddressBook: 0,\n\n                    /**\n                     * Is address can be used for billing\n                     *\n                     * @return {Boolean}\n                     */\n                    canUseForBilling: function () {\n                        return false;\n                    },\n\n                    /**\n                     * Returns address type\n                     *\n                     * @return {String}\n                     */\n                    getType: function () {\n                        return 'store-pickup-address';\n                    },\n\n                    /**\n                     * Returns address key\n                     *\n                     * @return {*}\n                     */\n                    getKey: function () {\n                        return this.getType() + sourceCode.value;\n                    }\n                });\n            }\n\n            return address;\n        }\n    };\n});\n","Magento_InventoryInStorePickupFrontend/js/model/quote-ext.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'Magento_InventoryInStorePickupFrontend/js/model/pickup-address-converter'\n], function (ko, pickupAddressConverter) {\n    'use strict';\n\n    return function (quote) {\n        var shippingAddress = quote.shippingAddress;\n\n        /**\n         * Makes sure that shipping address gets appropriate type when it points\n         * to a store pickup location.\n         */\n        quote.shippingAddress = ko.pureComputed({\n            /**\n             * Return quote shipping address\n             */\n            read: function () {\n                return shippingAddress();\n            },\n\n            /**\n             * Set quote shipping address\n             */\n            write: function (address) {\n                shippingAddress(\n                    pickupAddressConverter.formatAddressToPickupAddress(address)\n                );\n            }\n        });\n\n        return quote;\n    };\n});\n","Magento_InventoryInStorePickupFrontend/js/model/pickup-locations-service.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'knockout',\n    'Magento_InventoryInStorePickupFrontend/js/model/resource-url-manager',\n    'mage/storage',\n    'Magento_Customer/js/customer-data',\n    'Magento_Checkout/js/checkout-data',\n    'Magento_Checkout/js/model/address-converter',\n    'Magento_Checkout/js/action/select-shipping-address',\n    'underscore',\n    'mage/translate',\n    'mage/url',\n    'Magento_InventoryInStorePickupFrontend/js/model/pickup-address-converter'\n], function (\n    $,\n    ko,\n    resourceUrlManager,\n    storage,\n    customerData,\n    checkoutData,\n    addressConverter,\n    selectShippingAddressAction,\n    _,\n    $t,\n    url,\n    pickupAddressConverter\n) {\n    'use strict';\n\n    var websiteCode = window.checkoutConfig.websiteCode,\n        countryData = customerData.get('directory-data');\n\n    return {\n        isLoading: ko.observable(false),\n        selectedLocation: ko.observable(null),\n        locationsCache: [],\n\n        /**\n         * Get shipping rates for specified address.\n         *\n         * @param {String} sourceCode\n         */\n        getLocation: function (sourceCode) {\n            var serviceUrl = resourceUrlManager.getUrlForPickupLocation(websiteCode, sourceCode);\n\n            this.isLoading(true);\n\n            return storage\n                .get(serviceUrl, {}, false)\n                .then(function (result) {\n                    var addresses = result.items || [],\n                        address = addresses[0] || {};\n\n                    return this.formatAddress(address);\n                }.bind(this))\n                .fail(function (response) {\n                    this.processError(response);\n\n                    return [];\n                }.bind(this))\n                .always(function () {\n                    this.isLoading(false);\n                }.bind(this));\n        },\n\n        /**\n         * Get nearby pickup locations based on given search criteria.\n         *\n         * @param {Object} searchCriteria - Search criteria object.\n         * @see Magento/InventoryInStorePickup/Model/SearchCriteria/GetNearbyLocationsCriteria.php\n         */\n        getNearbyLocations: function (searchCriteria) {\n            var self = this,\n                serviceUrl = resourceUrlManager.getUrlForNearbyPickupLocations(websiteCode, searchCriteria);\n\n            if (self.locationsCache[serviceUrl]) {\n                return $.Deferred().resolve(self.locationsCache[serviceUrl]).promise();\n            }\n\n            self.isLoading(true);\n\n            return storage\n                .get(serviceUrl, {}, false)\n                .then(function (result) {\n                    self.locationsCache[serviceUrl] = _.map(result.items, function (address) {\n                        return self.formatAddress(address);\n                    });\n\n                    return self.locationsCache[serviceUrl];\n                })\n                .fail(function (response) {\n                    self.processError(response);\n\n                    return [];\n                })\n                .always(function () {\n                    self.isLoading(false);\n                });\n        },\n\n        /**\n         * Select location for sipping.\n         *\n         * @param {Object} location\n         * @returns void\n         */\n        selectForShipping: function (location) {\n            var address = $.extend(\n                {},\n                addressConverter.formAddressDataToQuoteAddress({\n                    firstname: location.name,\n                    lastname: 'Store',\n                    street: location.street,\n                    city: location.city,\n                    postcode: location.postcode,\n                    'country_id': location['country_id'],\n                    telephone: location.telephone,\n                    'region_id': location['region_id'],\n                    'save_in_address_book': 0,\n                    'extension_attributes': {\n                        'pickup_location_code': location['pickup_location_code']\n                    }\n                }));\n\n            address = pickupAddressConverter.formatAddressToPickupAddress(address);\n            this.selectedLocation(location);\n            selectShippingAddressAction(address);\n            checkoutData.setSelectedShippingAddress(address.getKey());\n            checkoutData.setSelectedPickupAddress(\n                addressConverter.quoteAddressToFormAddressData(address)\n            );\n        },\n\n        /**\n         * Formats address returned by REST endpoint to match checkout address field naming.\n         *\n         * @param {Object} address - Address object returned by REST endpoint.\n         */\n        formatAddress: function (address) {\n            return {\n                name: address.name,\n                description: address.description,\n                latitude: address.latitude,\n                longitude: address.longitude,\n                street: [address.street],\n                city: address.city,\n                postcode: address.postcode,\n                'country_id': address['country_id'],\n                country: this.getCountryName(address['country_id']),\n                telephone: address.phone,\n                'region_id': address['region_id'],\n                region: this.getRegionName(\n                    address['country_id'],\n                    address['region_id']\n                ),\n                'pickup_location_code': address['pickup_location_code']\n            };\n        },\n\n        /**\n         * Get country name by id.\n         *\n         * @param {*} countryId\n         * @return {String}\n         */\n        getCountryName: function (countryId) {\n            return countryData()[countryId] !== undefined ?\n                countryData()[countryId].name\n                : ''; //eslint-disable-line\n        },\n\n        /**\n         * Returns region name based on given country and region identifiers.\n         *\n         * @param {String} countryId - Country identifier.\n         * @param {String} regionId - Region identifier.\n         */\n        getRegionName: function (countryId, regionId) {\n            var regions = countryData()[countryId] ?\n                countryData()[countryId].regions\n                : null;\n\n            return regions && regions[regionId] ? regions[regionId].name : '';\n        },\n\n        /**\n         * Process response errors.\n         *\n         * @param {Object} response\n         * @returns void\n         */\n        processError: function (response) {\n            var expr = /([%])\\w+/g,\n                error;\n\n            if (response.status === 401) {\n                //eslint-disable-line eqeqeq\n                window.location.replace(url.build('customer/account/login/'));\n\n                return;\n            }\n\n            try {\n                error = JSON.parse(response.responseText);\n            } catch (exception) {\n                error = $t(\n                    'Something went wrong with your request. Please try again later.'\n                );\n            }\n\n            if (error.hasOwnProperty('parameters')) {\n                error = error.message.replace(expr, function (varName) {\n                    varName = varName.substr(1);\n\n                    if (error.parameters.hasOwnProperty(varName)) {\n                        return error.parameters[varName];\n                    }\n\n                    return error.parameters.shift();\n                });\n            }\n        },\n\n        /**\n         * Returns selected pick up address from local storage\n         *\n         * @returns {Object|null}\n         */\n        getSelectedPickupAddress: function () {\n            var shippingAddress,\n                pickUpAddress;\n\n            if (checkoutData.getSelectedPickupAddress()) {\n                shippingAddress = addressConverter.formAddressDataToQuoteAddress(\n                    checkoutData.getSelectedPickupAddress()\n                );\n                pickUpAddress = pickupAddressConverter.formatAddressToPickupAddress(\n                    shippingAddress\n                );\n\n                return pickUpAddress;\n            }\n\n            return null;\n        }\n    };\n});\n","Magento_InventoryInStorePickupFrontend/js/model/resource-url-manager.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['jquery', 'Magento_Checkout/js/model/resource-url-manager'], function (\n    $,\n    resourceUrlManager\n) {\n    'use strict';\n\n    return {\n        /**\n         * Returns URL for REST API to fetch nearby pickup locations defined for given sales channel.\n         *\n         * @param {String} salesChannelCode - Code of the sales channel.\n         * @param {Object} searchCriteria\n         */\n        getUrlForNearbyPickupLocations: function (\n            salesChannelCode,\n            searchCriteria\n        ) {\n            var urls = {\n                    default: '/inventory/in-store-pickup/pickup-locations/'\n                },\n                criteria = {\n                    searchRequest: {\n                        scopeCode: salesChannelCode\n                    }\n                };\n\n            searchCriteria = {\n                searchRequest: searchCriteria\n            };\n\n            return (\n                resourceUrlManager.getUrl(urls, {}) +\n                '?' +\n                $.param($.extend(true, criteria, searchCriteria))\n            );\n        },\n\n        /**\n         * Returns URL for REST API to fetch all pickup locations defined for given sales channel.\n         *\n         * @param {String} salesChannelType - Type of the sales channel, e.g. website.\n         * @param {String} salesChannelCode - Code of the sales channel.\n         */\n        getUrlForPickupLocationsAssignedToSalesChannel: function (\n            salesChannelType,\n            salesChannelCode\n        ) {\n            var params = {\n                    salesChannelType: salesChannelType,\n                    salesChannelCode: salesChannelCode\n                },\n                urls = {\n                    default: '/inventory/in-store-pickup/pickup-locations-assigned-to-sales-channel/' +\n                        ':salesChannelType/:salesChannelCode'\n                };\n\n            return resourceUrlManager.getUrl(urls, params);\n        },\n\n        /**\n         * Returns URL for REST API to fetch pickup location with given code defined for given sales channel.\n         *\n         * @param {String} salesChannelCode - Code of the sales channel.\n         * @param {String} pickupLocationCode - Code of the pickup location.\n         */\n        getUrlForPickupLocation: function (\n            salesChannelCode,\n            pickupLocationCode\n        ) {\n            var urls = {\n                    default: '/inventory/in-store-pickup/pickup-locations/'\n                },\n                searchRequest = {\n                    searchRequest: {\n                        filters: {\n                            pickupLocationCode: {\n                                value: pickupLocationCode\n                            }\n                        },\n                        scopeCode: salesChannelCode\n                    }\n                };\n\n            return resourceUrlManager.getUrl(urls, {}) +\n                '?' +\n                $.param(searchRequest);\n        }\n    };\n});\n","Magento_InventoryInStorePickupFrontend/js/model/shipping-rate-processor/store-pickup-address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    return {\n        /*eslint-disable no-unused-vars*/\n        /**\n         * @param {Object} address\n         */\n        getRates: function (address) {}\n    };\n});\n","js/jquery.parallax.min.js":"//============================================================\n//\n// The MIT License\n//\n// Copyright (C) 2014 Matthew Wagerfield - @wagerfield\n//\n// Permission is hereby granted, free of charge, to any\n// person obtaining a copy of this software and associated\n// documentation files (the \"Software\"), to deal in the\n// Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute,\n// sublicense, and/or sell copies of the Software, and to\n// permit persons to whom the Software is furnished to do\n// so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice\n// shall be included in all copies or substantial portions\n// of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY\n// OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT\n// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO\n// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\n// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\n// OR OTHER DEALINGS IN THE SOFTWARE.\n//\n//============================================================\n\n/**\n * jQuery || Zepto Parallax Plugin\n * @author Matthew Wagerfield - @wagerfield\n * @description Creates a parallax effect between an array of layers,\n *              driving the motion from the gyroscope output of a smartdevice.\n *              If no gyroscope is available, the cursor position is used.\n */\n;(function($, window, document, undefined) {\n\n  // Strict Mode\n  'use strict';\n\n  // Constants\n  var NAME = 'parallax';\n  var MAGIC_NUMBER = 30;\n  var DEFAULTS = {\n    relativeInput: false,\n    clipRelativeInput: false,\n    calibrationThreshold: 100,\n    calibrationDelay: 500,\n    supportDelay: 500,\n    calibrateX: false,\n    calibrateY: true,\n    invertX: true,\n    invertY: true,\n    limitX: false,\n    limitY: false,\n    scalarX: 10.0,\n    scalarY: 10.0,\n    frictionX: 0.1,\n    frictionY: 0.1,\n    originX: 0.5,\n    originY: 0.5\n  };\n\n  function Plugin(element, options) {\n\n    // DOM Context\n    this.element = element;\n\n    // Selections\n    this.$context = $(element).data('api', this);\n    this.$layers = this.$context.find('.layer');\n\n    // Data Extraction\n    var data = {\n      calibrateX: this.$context.data('calibrate-x') || null,\n      calibrateY: this.$context.data('calibrate-y') || null,\n      invertX: this.$context.data('invert-x') || null,\n      invertY: this.$context.data('invert-y') || null,\n      limitX: parseFloat(this.$context.data('limit-x')) || null,\n      limitY: parseFloat(this.$context.data('limit-y')) || null,\n      scalarX: parseFloat(this.$context.data('scalar-x')) || null,\n      scalarY: parseFloat(this.$context.data('scalar-y')) || null,\n      frictionX: parseFloat(this.$context.data('friction-x')) || null,\n      frictionY: parseFloat(this.$context.data('friction-y')) || null,\n      originX: parseFloat(this.$context.data('origin-x')) || null,\n      originY: parseFloat(this.$context.data('origin-y')) || null\n    };\n\n    // Delete Null Data Values\n    for (var key in data) {\n      if (data[key] === null) delete data[key];\n    }\n\n    // Compose Settings Object\n    $.extend(this, DEFAULTS, options, data);\n\n    // States\n    this.calibrationTimer = null;\n    this.calibrationFlag = true;\n    this.enabled = false;\n    this.depths = [];\n    this.raf = null;\n\n    // Element Bounds\n    this.bounds = null;\n    this.ex = 0;\n    this.ey = 0;\n    this.ew = 0;\n    this.eh = 0;\n\n    // Element Center\n    this.ecx = 0;\n    this.ecy = 0;\n\n    // Element Range\n    this.erx = 0;\n    this.ery = 0;\n\n    // Calibration\n    this.cx = 0;\n    this.cy = 0;\n\n    // Input\n    this.ix = 0;\n    this.iy = 0;\n\n    // Motion\n    this.mx = 0;\n    this.my = 0;\n\n    // Velocity\n    this.vx = 0;\n    this.vy = 0;\n\n    // Callbacks\n    this.onMouseMove = this.onMouseMove.bind(this);\n    this.onDeviceOrientation = this.onDeviceOrientation.bind(this);\n    this.onOrientationTimer = this.onOrientationTimer.bind(this);\n    this.onCalibrationTimer = this.onCalibrationTimer.bind(this);\n    this.onAnimationFrame = this.onAnimationFrame.bind(this);\n    this.onWindowResize = this.onWindowResize.bind(this);\n\n    // Initialise\n    this.initialise();\n  }\n\n  Plugin.prototype.transformSupport = function(value) {\n    var element = document.createElement('div');\n    var propertySupport = false;\n    var propertyValue = null;\n    var featureSupport = false;\n    var cssProperty = null;\n    var jsProperty = null;\n    for (var i = 0, l = this.vendors.length; i < l; i++) {\n      if (this.vendors[i] !== null) {\n        cssProperty = this.vendors[i][0] + 'transform';\n        jsProperty = this.vendors[i][1] + 'Transform';\n      } else {\n        cssProperty = 'transform';\n        jsProperty = 'transform';\n      }\n      if (element.style[jsProperty] !== undefined) {\n        propertySupport = true;\n        break;\n      }\n    }\n    switch(value) {\n      case '2D':\n        featureSupport = propertySupport;\n        break;\n      case '3D':\n        if (propertySupport) {\n          var body = document.body || document.createElement('body');\n          var documentElement = document.documentElement;\n          var documentOverflow = documentElement.style.overflow;\n          if (!document.body) {\n            documentElement.appendChild(body);\n          }\n          body.appendChild(element);\n          element.style[jsProperty] = 'translate3d(1px,1px,1px)';\n          propertyValue = window.getComputedStyle(element).getPropertyValue(cssProperty);\n          featureSupport = propertyValue !== undefined && propertyValue.length > 0 && propertyValue !== \"none\";\n          documentElement.style.overflow = documentOverflow;\n          body.removeChild(element);\n        }\n        break;\n    }\n    return featureSupport;\n  };\n\n  Plugin.prototype.ww = null;\n  Plugin.prototype.wh = null;\n  Plugin.prototype.wcx = null;\n  Plugin.prototype.wcy = null;\n  Plugin.prototype.wrx = null;\n  Plugin.prototype.wry = null;\n  Plugin.prototype.portrait = null;\n  Plugin.prototype.desktop = !navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|BB10|mobi|tablet|opera mini|nexus 7)/i);\n  Plugin.prototype.vendors = [null,['-webkit-','webkit'],['-moz-','Moz'],['-o-','O'],['-ms-','ms']];\n  Plugin.prototype.motionSupport = !!window.DeviceMotionEvent;\n  Plugin.prototype.orientationSupport = !!window.DeviceOrientationEvent;\n  Plugin.prototype.orientationStatus = 0;\n  Plugin.prototype.transform2DSupport = Plugin.prototype.transformSupport('2D');\n  Plugin.prototype.transform3DSupport = Plugin.prototype.transformSupport('3D');\n  Plugin.prototype.propertyCache = {};\n\n  Plugin.prototype.initialise = function() {\n\n    // Configure Styles\n    if (this.$context.css('position') === 'static') {\n      this.$context.css({\n        position:'relative'\n      });\n    }\n\n    // Hardware Accelerate Context\n    this.accelerate(this.$context);\n\n    // Setup\n    this.updateLayers();\n    this.updateDimensions();\n    this.enable();\n    this.queueCalibration(this.calibrationDelay);\n  };\n\n  Plugin.prototype.updateLayers = function() {\n\n    // Cache Layer Elements\n    this.$layers = this.$context.find('.layer');\n    this.depths = [];\n\n    // Configure Layer Styles\n    this.$layers.css({\n      position:'absolute',\n      display:'block',\n      left: 0,\n      top: 0\n    });\n    this.$layers.first().css({\n      position:'relative'\n    });\n\n    // Hardware Accelerate Layers\n    this.accelerate(this.$layers);\n\n    // Cache Depths\n    this.$layers.each($.proxy(function(index, element) {\n      this.depths.push($(element).data('depth') || 0);\n    }, this));\n  };\n\n  Plugin.prototype.updateDimensions = function() {\n    this.ww = window.innerWidth;\n    this.wh = window.innerHeight;\n    this.wcx = this.ww * this.originX;\n    this.wcy = this.wh * this.originY;\n    this.wrx = Math.max(this.wcx, this.ww - this.wcx);\n    this.wry = Math.max(this.wcy, this.wh - this.wcy);\n  };\n\n  Plugin.prototype.updateBounds = function() {\n    this.bounds = this.element.getBoundingClientRect();\n    this.ex = this.bounds.left;\n    this.ey = this.bounds.top;\n    this.ew = this.bounds.width;\n    this.eh = this.bounds.height;\n    this.ecx = this.ew * this.originX;\n    this.ecy = this.eh * this.originY;\n    this.erx = Math.max(this.ecx, this.ew - this.ecx);\n    this.ery = Math.max(this.ecy, this.eh - this.ecy);\n  };\n\n  Plugin.prototype.queueCalibration = function(delay) {\n    clearTimeout(this.calibrationTimer);\n    this.calibrationTimer = setTimeout(this.onCalibrationTimer, delay);\n  };\n\n  Plugin.prototype.enable = function() {\n    if (!this.enabled) {\n      this.enabled = true;\n      if (this.orientationSupport) {\n        this.portrait = null;\n        window.addEventListener('deviceorientation', this.onDeviceOrientation);\n        setTimeout(this.onOrientationTimer, this.supportDelay);\n      } else {\n        this.cx = 0;\n        this.cy = 0;\n        this.portrait = false;\n        window.addEventListener('mousemove', this.onMouseMove);\n      }\n      window.addEventListener('resize', this.onWindowResize);\n      this.raf = requestAnimationFrame(this.onAnimationFrame);\n    }\n  };\n\n  Plugin.prototype.disable = function() {\n    if (this.enabled) {\n      this.enabled = false;\n      if (this.orientationSupport) {\n        window.removeEventListener('deviceorientation', this.onDeviceOrientation);\n      } else {\n        window.removeEventListener('mousemove', this.onMouseMove);\n      }\n      window.removeEventListener('resize', this.onWindowResize);\n      cancelAnimationFrame(this.raf);\n    }\n  };\n\n  Plugin.prototype.calibrate = function(x, y) {\n    this.calibrateX = x === undefined ? this.calibrateX : x;\n    this.calibrateY = y === undefined ? this.calibrateY : y;\n  };\n\n  Plugin.prototype.invert = function(x, y) {\n    this.invertX = x === undefined ? this.invertX : x;\n    this.invertY = y === undefined ? this.invertY : y;\n  };\n\n  Plugin.prototype.friction = function(x, y) {\n    this.frictionX = x === undefined ? this.frictionX : x;\n    this.frictionY = y === undefined ? this.frictionY : y;\n  };\n\n  Plugin.prototype.scalar = function(x, y) {\n    this.scalarX = x === undefined ? this.scalarX : x;\n    this.scalarY = y === undefined ? this.scalarY : y;\n  };\n\n  Plugin.prototype.limit = function(x, y) {\n    this.limitX = x === undefined ? this.limitX : x;\n    this.limitY = y === undefined ? this.limitY : y;\n  };\n\n  Plugin.prototype.origin = function(x, y) {\n    this.originX = x === undefined ? this.originX : x;\n    this.originY = y === undefined ? this.originY : y;\n  };\n\n  Plugin.prototype.clamp = function(value, min, max) {\n    value = Math.max(value, min);\n    value = Math.min(value, max);\n    return value;\n  };\n\n  Plugin.prototype.css = function(element, property, value) {\n    var jsProperty = this.propertyCache[property];\n    if (!jsProperty) {\n      for (var i = 0, l = this.vendors.length; i < l; i++) {\n        if (this.vendors[i] !== null) {\n          jsProperty = $.camelCase(this.vendors[i][1] + '-' + property);\n        } else {\n          jsProperty = property;\n        }\n        if (element.style[jsProperty] !== undefined) {\n          this.propertyCache[property] = jsProperty;\n          break;\n        }\n      }\n    }\n    element.style[jsProperty] = value;\n  };\n\n  Plugin.prototype.accelerate = function($element) {\n    for (var i = 0, l = $element.length; i < l; i++) {\n      var element = $element[i];\n      this.css(element, 'transform', 'translate3d(0,0,0)');\n      this.css(element, 'transform-style', 'preserve-3d');\n      this.css(element, 'backface-visibility', 'hidden');\n    }\n  };\n\n  Plugin.prototype.setPosition = function(element, x, y) {\n    x += 'px';\n    y += 'px';\n    if (this.transform3DSupport) {\n      this.css(element, 'transform', 'translate3d('+x+','+y+',0)');\n    } else if (this.transform2DSupport) {\n      this.css(element, 'transform', 'translate('+x+','+y+')');\n    } else {\n      element.style.left = x;\n      element.style.top = y;\n    }\n  };\n\n  Plugin.prototype.onOrientationTimer = function(event) {\n    if (this.orientationSupport && this.orientationStatus === 0) {\n      this.disable();\n      this.orientationSupport = false;\n      this.enable();\n    }\n  };\n\n  Plugin.prototype.onCalibrationTimer = function(event) {\n    this.calibrationFlag = true;\n  };\n\n  Plugin.prototype.onWindowResize = function(event) {\n    this.updateDimensions();\n  };\n\n  Plugin.prototype.onAnimationFrame = function() {\n    this.updateBounds();\n    var dx = this.ix - this.cx;\n    var dy = this.iy - this.cy;\n    if ((Math.abs(dx) > this.calibrationThreshold) || (Math.abs(dy) > this.calibrationThreshold)) {\n      this.queueCalibration(0);\n    }\n    if (this.portrait) {\n      this.mx = this.calibrateX ? dy : this.iy;\n      this.my = this.calibrateY ? dx : this.ix;\n    } else {\n      this.mx = this.calibrateX ? dx : this.ix;\n      this.my = this.calibrateY ? dy : this.iy;\n    }\n    this.mx *= this.ew * (this.scalarX / 100);\n    this.my *= this.eh * (this.scalarY / 100);\n    if (!isNaN(parseFloat(this.limitX))) {\n      this.mx = this.clamp(this.mx, -this.limitX, this.limitX);\n    }\n    if (!isNaN(parseFloat(this.limitY))) {\n      this.my = this.clamp(this.my, -this.limitY, this.limitY);\n    }\n    this.vx += (this.mx - this.vx) * this.frictionX;\n    this.vy += (this.my - this.vy) * this.frictionY;\n    for (var i = 0, l = this.$layers.length; i < l; i++) {\n      var depth = this.depths[i];\n      var layer = this.$layers[i];\n      var xOffset = this.vx * depth * (this.invertX ? -1 : 1);\n      var yOffset = this.vy * depth * (this.invertY ? -1 : 1);\n      this.setPosition(layer, xOffset, yOffset);\n    }\n    this.raf = requestAnimationFrame(this.onAnimationFrame);\n  };\n\n  Plugin.prototype.onDeviceOrientation = function(event) {\n\n    // Validate environment and event properties.\n    if (!this.desktop && event.beta !== null && event.gamma !== null) {\n\n      // Set orientation status.\n      this.orientationStatus = 1;\n\n      // Extract Rotation\n      var x = (event.beta  || 0) / MAGIC_NUMBER; //  -90 :: 90\n      var y = (event.gamma || 0) / MAGIC_NUMBER; // -180 :: 180\n\n      // Detect Orientation Change\n      var portrait = window.innerHeight > window.innerWidth;\n      if (this.portrait !== portrait) {\n        this.portrait = portrait;\n        this.calibrationFlag = true;\n      }\n\n      // Set Calibration\n      if (this.calibrationFlag) {\n        this.calibrationFlag = false;\n        this.cx = x;\n        this.cy = y;\n      }\n\n      // Set Input\n      this.ix = x;\n      this.iy = y;\n    }\n  };\n\n  Plugin.prototype.onMouseMove = function(event) {\n\n    // Cache mouse coordinates.\n    var clientX = event.clientX;\n    var clientY = event.clientY;\n\n    // Calculate Mouse Input\n    if (!this.orientationSupport && this.relativeInput) {\n\n      // Clip mouse coordinates inside element bounds.\n      if (this.clipRelativeInput) {\n        clientX = Math.max(clientX, this.ex);\n        clientX = Math.min(clientX, this.ex + this.ew);\n        clientY = Math.max(clientY, this.ey);\n        clientY = Math.min(clientY, this.ey + this.eh);\n      }\n\n      // Calculate input relative to the element.\n      this.ix = (clientX - this.ex - this.ecx) / this.erx;\n      this.iy = (clientY - this.ey - this.ecy) / this.ery;\n\n    } else {\n\n      // Calculate input relative to the window.\n      this.ix = (clientX - this.wcx) / this.wrx;\n      this.iy = (clientY - this.wcy) / this.wry;\n    }\n  };\n\n  var API = {\n    enable: Plugin.prototype.enable,\n    disable: Plugin.prototype.disable,\n    updateLayers: Plugin.prototype.updateLayers,\n    calibrate: Plugin.prototype.calibrate,\n    friction: Plugin.prototype.friction,\n    invert: Plugin.prototype.invert,\n    scalar: Plugin.prototype.scalar,\n    limit: Plugin.prototype.limit,\n    origin: Plugin.prototype.origin\n  };\n\n  $.fn[NAME] = function (value) {\n    var args = arguments;\n    return this.each(function () {\n      var $this = $(this);\n      var plugin = $this.data(NAME);\n      if (!plugin) {\n        plugin = new Plugin(this, value);\n        $this.data(NAME, plugin);\n      }\n      if (API[value]) {\n        plugin[value].apply(plugin, Array.prototype.slice.call(args, 1));\n      }\n    });\n  };\n\n})(window.jQuery || window.Zepto, window, document);\n\n/**\n * Request Animation Frame Polyfill.\n * @author Tino Zijdel\n * @author Paul Irish\n * @see https://gist.github.com/paulirish/1579671\n */\n;(function() {\n\n  var lastTime = 0;\n  var vendors = ['ms', 'moz', 'webkit', 'o'];\n\n  for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {\n    window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];\n    window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];\n  }\n\n  if (!window.requestAnimationFrame) {\n    window.requestAnimationFrame = function(callback, element) {\n      var currTime = new Date().getTime();\n      var timeToCall = Math.max(0, 16 - (currTime - lastTime));\n      var id = window.setTimeout(function() { callback(currTime + timeToCall); },\n        timeToCall);\n      lastTime = currTime + timeToCall;\n      return id;\n    };\n  }\n\n  if (!window.cancelAnimationFrame) {\n    window.cancelAnimationFrame = function(id) {\n      clearTimeout(id);\n    };\n  }\n\n}());\n","js/jquery.floatelement.js":"(function (factory) {\r\n    'use strict';\r\n\r\n    if (typeof define === 'function' && define.amd) {\r\n        define([\r\n            'jquery'\r\n        ], factory);\r\n    } else {\r\n        factory(window.jQuery);\r\n    }\r\n}(function ($) {\r\n    'use strict';\r\n\r\n    var $window = $(window);\r\n\r\n    $.fn.themePluginFloatElement = function(options) {\r\n        var settings = {\r\n            startPos: \"top\",\r\n            speed: 3,\r\n            horizontal: false,\r\n            transition: false\r\n        };\r\n        var $el, $options;\r\n\r\n        function initialize(t, options) {\r\n            return t.data(\"__floatElement\") ? this : ($el = t,\r\n            setData(),\r\n            setOptions(options),\r\n            build(),\r\n            this)\r\n        }\r\n\r\n        function setData() {\r\n            return $el.data(\"__floatElement\")\r\n        }\r\n\r\n        function setOptions(options) {\r\n            return $options = $.extend(!0, {}, settings, options, {\r\n                wrapper: $el\r\n            })\r\n        }\r\n\r\n        function build() {\r\n            var t, o = $options.wrapper, s = $(window);\r\n            return $options.style && o.attr(\"style\", $options.style),\r\n            s.width() > 767 && (\"none\" == $options.startPos ? t = \"\" : \"top\" == $options.startPos ? (o.css({\r\n                top: 0\r\n            }),\r\n            t = \"\") : (o.css({\r\n                bottom: 0\r\n            }),\r\n            t = \"-\"),\r\n            $options.transition && o.css({\r\n                transition: \"ease transform 500ms\"\r\n            }),\r\n            movement(t),\r\n            s.on(\"scroll\", function() {\r\n                movement(t)\r\n            }))\r\n        }\r\n\r\n        function movement(t) {\r\n            var i = $($options.wrapper)\r\n              , o = $(window)\r\n              , s = o.scrollTop()\r\n              , n = 100 * (i.offset().top - s) / o.height();\r\n            $options.horizontal ? i.css({\r\n                transform: \"translate3d(\" + t + n / $options.speed + \"%, \" + t + n / $options.speed + \"%, 0)\"\r\n            }) : i.css({\r\n                transform: \"translate3d(0, \" + t + n / $options.speed + \"%, 0)\"\r\n            })\r\n        }\r\n\r\n        initialize(this, options);\r\n\r\n        return this;\r\n    }\r\n}));","js/jquery.infinite-scroller.js":"define([\n    'jquery'\n], function ($) {\n    \"use strict\";\n    $.widget('smartwave.infiniteScroll', {\n        options: {\n            productsListSelector: '#layer-product-list',\n            next_page: '',\n            loading: false,\n            infinite_loaded_count: 0,\n            active: false\n        },\n        _create: function () {\n            this.inFinite();\n        },\n        inFinite: function(){\n            var self = this;\n            self.options.next_page = \"\";\n            if($(self.options.productsListSelector +' .infinite-loader').length > 0){\n                self.options.active = true;\n            }\n            $(\".pages-items li > a.next\").each(function(){\n                self.options.next_page = $(this).attr(\"href\");\n            });\n            $(window).scroll(function(){\n                if(!self.options.loading && self.options.active && self.options.next_page && $(window).scrollTop() >= $(\".infinite-loader\").offset().top-$(window).height()+100){\n                    if(self.options.infinite_loaded_count < 2){\n                        self.options.loading = true;\n                        $(\".pages-items li > a.next\").each(function(){\n                            self.options.next_page = $(this).attr(\"href\");\n                        });\n                        self.ajaxInfinite(self.options.next_page);\n                    }\n                }\n            });\n            $(\".infinite-loader .btn-load-more\").click(function(){\n                if(!self.options.loading && self.options.next_page && self.options.infinite_loaded_count >= 2){\n                    self.options.loading = true;\n                    self.ajaxInfinite(self.options.next_page);\n                }\n            });\n        },\n        ajaxInfinite: function (submitUrl) {\n            var self = this;\n            self.options.infinite_loaded_count++;\n            $('.infinite-loader .btn-load-more').hide();\n            $('.infinite-loader .loading').fadeIn(300);\n            $.ajax({\n                type: 'GET',\n                url: submitUrl,\n                dataType: \"html\",\n                beforeSend: function () {\n                    $('.infinite-loader .btn-load-more').hide();\n                    $('.infinite-loader .loading').fadeIn(300);\n                },\n                success: function (res) {\n                    self.options.loading = false;\n                    var items = $(res).find(self.options.productsListSelector +' .product-items .item');\n                    var b = $('<div/>').html($(res).find(self.options.productsListSelector));\n                    if (items.length > 0) {\n                        if($(b).find('div.products-grid')){\n                            $(self.options.productsListSelector + ' .products.wrapper').last()\n                                .after($(res).find(self.options.productsListSelector +' div.products-grid.wrapper').detach())\n                                .trigger('contentUpdated');\n                        }\n                        if($(b).find('div.products-list')){\n                            $(self.options.productsListSelector + ' .products.wrapper').last()\n                                .after($(res).find(self.options.productsListSelector +' div.products-list.wrapper').detach())\n                                .trigger('contentUpdated');\n                        }\n                        if($(b).find('.pages a.next').length>0){\n                            $(self.options.productsListSelector + ' .pages a.next').attr('href', $(res).find('.pages a.next').attr('href'));\n                        }else{\n                            $(self.options.productsListSelector + ' .pages a.next').remove();\n                        }\n                        $(b).remove();\n                        $(\"form[data-role=tocart-form]\").catalogAddToCart();\n                        $('.main .products.grid .product-items li.product-item:nth-child(2n)').addClass('nth-child-2n');\n                        $('.main .products.grid .product-items li.product-item:nth-child(2n+1)').addClass('nth-child-2np1');\n                        $('.main .products.grid .product-items li.product-item:nth-child(3n)').addClass('nth-child-3n');\n                        $('.main .products.grid .product-items li.product-item:nth-child(3n+1)').addClass('nth-child-3np1');\n                        $('.main .products.grid .product-items li.product-item:nth-child(4n)').addClass('nth-child-4n');\n                        $('.main .products.grid .product-items li.product-item:nth-child(4n+1)').addClass('nth-child-4np1');\n                        $('.main .products.grid .product-items li.product-item:nth-child(5n)').addClass('nth-child-5n');\n                        $('.main .products.grid .product-items li.product-item:nth-child(5n+1)').addClass('nth-child-5np1');\n                        $('.main .products.grid .product-items li.product-item:nth-child(6n)').addClass('nth-child-6n');\n                        $('.main .products.grid .product-items li.product-item:nth-child(6n+1)').addClass('nth-child-6np1');\n                        $('.main .products.grid .product-items li.product-item:nth-child(7n)').addClass('nth-child-7n');\n                        $('.main .products.grid .product-items li.product-item:nth-child(7n+1)').addClass('nth-child-7np1');\n                        $('.main .products.grid .product-items li.product-item:nth-child(8n)').addClass('nth-child-8n');\n                        $('.main .products.grid .product-items li.product-item:nth-child(8n+1)').addClass('nth-child-8np1');\n                        var hist = submitUrl;\n                        if(submitUrl.indexOf(\"p=\") > -1){\n                            var len = submitUrl.length-submitUrl.indexOf(\"p=\");\n                            var str_temp = submitUrl.substr(submitUrl.indexOf(\"p=\"),len);\n                            var page_param = \"\";\n                            if(str_temp.indexOf(\"&\") == -1){\n                                page_param = str_temp;\n                            } else {\n                                page_param = str_temp.substr(0,str_temp.indexOf(\"&\"));\n                            }\n                            hist = submitUrl.replace(page_param, \"\");\n                        }\n                        if (typeof window.history.pushState === 'function') {\n                            window.history.pushState({url: hist}, '', hist);\n                        }\n                        if(typeof enable_quickview != 'undefined' && enable_quickview == true) {\n                            requirejs(['jquery', 'weltpixel_quickview' ],\n                                function($, quickview) {\n                                    $('.weltpixel-quickview').off('click').on('click', function() {\n                                        var prodUrl = $(this).attr('data-quickview-url');\n                                        if (prodUrl.length) {\n                                            quickview.displayContent(prodUrl);\n                                        }\n                                    });\n                                });\n                        }\n                        $(\".products-grid .weltpixel-quickview\").each(function(){\n                            $(this).appendTo($(this).parent().parent().children(\".product-item-photo\"));\n                        });\n                        self.options.next_page = \"\";\n                        $(\".pages-items li > a.next\").each(function(){\n                            self.options.next_page = $(this).attr(\"href\");\n                        });\n                        if(self.options.infinite_loaded_count >= 2){\n                            $('.infinite-loader .loading').hide();\n                            if(self.options.next_page){\n                                $('.infinite-loader .btn-load-more').show();\n                                $(\".infinite-loader .btn-load-more\").unbind(\"click\").click(function(){\n                                    if(!self.options.loading && self.options.next_page && self.options.infinite_loaded_count >= 2){\n                                        self.options.loading = true;\n                                        self.ajaxInfinite(self.options.next_page);\n                                    }\n                                });\n                            }\n                        } else {\n                            $('.infinite-loader .loading').fadeOut(300);\n                        }\n                    }\n\n                },\n                error: function () {\n                    window.location.reload();\n                }\n            });\n        }\n    });\n    return $.smartwave.infiniteScroll;\n});","js/theme.js":"/**\n * Copyright \u00a9 2015 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\nrequire([\n    'jquery',\n    'mage/smart-keyboard-handler',\n    'mage/mage',\n    'mage/ie-class-fixer',\n    'domReady!'\n], function ($, keyboardHandler) {\n    'use strict';\n    $(document).ready(function(){\n        $('.cart-summary').mage('sticky', {\n            container: '#maincontent'\n        });\n\n        $('.panel.header .header.links').clone().appendTo('#store\\\\.links');\n    });\n    keyboardHandler.apply();\n});\nrequire([\n    'jquery'\n], function ($) {\n    (function() {\n        var ev = new $.Event('classadded'),\n            orig = $.fn.addClass;\n        $.fn.addClass = function() {\n            $(this).trigger(ev, arguments);\n            return orig.apply(this, arguments);\n        }\n    })();\n    $.fn.extend({\n        scrollToMe: function(){\n            if($(this).length){\n                var top = $(this).offset().top - 100;\n                $('html,body').animate({scrollTop: top}, 300);\n            }\n        },\n        scrollToJustMe: function(){\n            if($(this).length){\n                var top = jQuery(this).offset().top;\n                $('html,body').animate({scrollTop: top}, 300);\n            }\n        }\n    });\n    $(document).ready(function(){\n        var windowScroll_t;\n        $(window).scroll(function(){\n            clearTimeout(windowScroll_t);\n            windowScroll_t = setTimeout(function(){\n                if(jQuery(this).scrollTop() > 100){\n                    $('#totop').fadeIn();\n                }else{\n                    $('#totop').fadeOut();\n                }\n            }, 500);\n        });\n        $('#totop').off(\"click\").on(\"click\",function(){\n            $('html, body').animate({scrollTop: 0}, 600);\n        });\n        if ($('body').hasClass('checkout-cart-index')) {\n            if ($('#co-shipping-method-form .fieldset.rates').length > 0 && $('#co-shipping-method-form .fieldset.rates :checked').length === 0) {\n                $('#block-shipping').on('collapsiblecreate', function () {\n                    $('#block-shipping').collapsible('forceActivate');\n                });\n            }\n        }\n        $(\".products-grid .weltpixel-quickview\").each(function(){\n            $(this).appendTo($(this).parent().parent().children(\".product-item-photo\"));\n        });\n        $(\".word-rotate\").each(function() {\n\n            var $this = $(this),\n                itemsWrapper = $(this).find(\".word-rotate-items\"),\n                items = itemsWrapper.find(\"> span\"),\n                firstItem = items.eq(0),\n                firstItemClone = firstItem.clone(),\n                itemHeight = 0,\n                currentItem = 1,\n                currentTop = 0;\n\n            itemHeight = firstItem.height();\n\n            itemsWrapper.append(firstItemClone);\n\n            $this\n                .height(itemHeight)\n                .addClass(\"active\");\n\n            setInterval(function() {\n                currentTop = (currentItem * itemHeight);\n\n                itemsWrapper.animate({\n                    top: -(currentTop) + \"px\"\n                }, 300, function() {\n                    currentItem++;\n                    if(currentItem > items.length) {\n                        itemsWrapper.css(\"top\", 0);\n                        currentItem = 1;\n                    }\n                });\n\n            }, 2000);\n\n        });\n        $(\".top-links-icon\").off(\"click\").on(\"click\", function(e){\n            if($(this).parent().children(\"ul.links\").hasClass(\"show\")) {\n                $(this).parent().children(\"ul.links\").removeClass(\"show\");\n            } else {\n                $(this).parent().children(\"ul.links\").addClass(\"show\");\n            }\n            e.stopPropagation();\n        });\n        $(\".top-links-icon\").parent().click(function(e){\n            e.stopPropagation();\n        });\n        $(\".search-toggle-icon\").click(function(e){\n            if($(this).parent().children(\".block-search\").hasClass(\"show\")) {\n                $(this).parent().children(\".block-search\").removeClass(\"show\");\n                $(this).removeClass('open');\n            } else {\n                $(this).parent().children(\".block-search\").addClass(\"show\");\n                $(this).addClass('open');\n            }\n            e.stopPropagation();\n        });\n        $(\".search-toggle-icon\").parent().click(function(e){\n            e.stopPropagation();\n        });\n        $(\"html,body\").click(function(){\n            $(\".search-toggle-icon\").parent().children(\".block-search\").removeClass(\"show\");\n            $('.autocomplete-suggestions').hide();\n            $(\".search-toggle-icon\").removeClass('open');\n            $(\".top-links-icon\").parent().children(\"ul.links\").removeClass(\"show\");\n        });\n\n        /********************* Qty Holder **************************/\n        $(document).on(\"click\", \".qtyplus\", function(e) {\n            // Stop acting like a button\n            e.preventDefault();\n            // Get its current value\n            var currentVal = parseInt($(this).parents('form').find('input[name=\"qty\"]').val());\n            // If is not undefined\n            if (!isNaN(currentVal)) {\n                // Increment\n                $(this).parents('form').find('input[name=\"qty\"]').val(currentVal + 1);\n            } else {\n                // Otherwise put a 0 there\n                $(this).parents('form').find('input[name=\"qty\"]').val(0);\n            }\n        });\n        // This button will decrement the value till 0\n        $(document).on(\"click\", \".qtyminus\", function(e) {\n            // Stop acting like a button\n            e.preventDefault();\n            // Get the field name\n            fieldName = $(this).attr('field');\n            // Get its current value\n            var currentVal = parseInt($(this).parents('form').find('input[name=\"qty\"]').val());\n            // If it isn't undefined or its greater than 0\n            if (!isNaN(currentVal) && currentVal > 0) {\n                // Decrement one\n                $(this).parents('form').find('input[name=\"qty\"]').val(currentVal - 1);\n            } else {\n                // Otherwise put a 0 there\n                $(this).parents('form').find('input[name=\"qty\"]').val(0);\n            }\n        });\n        $(\".qty-inc\").unbind('click').click(function(){\n            if($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").is(':enabled')){\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val((+$(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val() + 1) || 0);\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").trigger('change');\n                $(this).focus();\n            }\n        });\n        $(\".qty-dec\").unbind('click').click(function(){\n            if($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").is(':enabled')){\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val(($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val() - 1 > 0) ? ($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val() - 1) : 0);\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").trigger('change');\n                $(this).focus();\n            }\n        });\n    });\n});\nrequire([\n    'jquery',\n    'js/jquery.lazyload'\n], function ($) {\n    $(document).ready(function(){\n        $(\"img.porto-lazyload:not(.porto-lazyload-loaded)\").lazyload({effect:\"fadeIn\"});\n        if ($('.porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').length) {\n            $('.porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('changed.owl.carousel', function() {\n                $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\n            });\n            $('.porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('initialized.owl.carousel', function() {\n                $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\n            });\n        }\n        window.setTimeout(function(){\n            $('.sidebar-filterproducts').find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\n        },500);\n    });\n});\n","js/jquery.lazyload.js":"/*!\r\n * Lazy Load - JavaScript plugin for lazy loading images\r\n *\r\n * Copyright (c) 2007-2019 Mika Tuupola\r\n *\r\n * Licensed under the MIT license:\r\n *   http://www.opensource.org/licenses/mit-license.php\r\n *\r\n * Project home:\r\n *   https://appelsiini.net/projects/lazyload\r\n *\r\n * Version: 2.0.0-rc.2\r\n *\r\n */\r\n\r\n(function (root, factory) {\r\n    if (typeof exports === \"object\") {\r\n        module.exports = factory(root);\r\n    } else if (typeof define === \"function\" && define.amd) {\r\n        define([], factory);\r\n    } else {\r\n        root.LazyLoad = factory(root);\r\n    }\r\n}) (typeof global !== \"undefined\" ? global : this.window || this.global, function (root) {\r\n\r\n    \"use strict\";\r\n\r\n    if (typeof define === \"function\" && define.amd){\r\n        root = window;\r\n    }\r\n\r\n    const defaults = {\r\n        src: \"data-src\",\r\n        srcset: \"data-srcset\",\r\n        selector: \".lazyload\",\r\n        root: null,\r\n        rootMargin: \"0px\",\r\n        threshold: 0\r\n    };\r\n\r\n    /**\r\n    * Merge two or more objects. Returns a new object.\r\n    * @private\r\n    * @param {Boolean}  deep     If true, do a deep (or recursive) merge [optional]\r\n    * @param {Object}   objects  The objects to merge together\r\n    * @returns {Object}          Merged values of defaults and options\r\n    */\r\n    const extend = function ()  {\r\n\r\n        let extended = {};\r\n        let deep = false;\r\n        let i = 0;\r\n        let length = arguments.length;\r\n\r\n        /* Check if a deep merge */\r\n        if (Object.prototype.toString.call(arguments[0]) === \"[object Boolean]\") {\r\n            deep = arguments[0];\r\n            i++;\r\n        }\r\n\r\n        /* Merge the object into the extended object */\r\n        let merge = function (obj) {\r\n            for (let prop in obj) {\r\n                if (Object.prototype.hasOwnProperty.call(obj, prop)) {\r\n                    /* If deep merge and property is an object, merge properties */\r\n                    if (deep && Object.prototype.toString.call(obj[prop]) === \"[object Object]\") {\r\n                        extended[prop] = extend(true, extended[prop], obj[prop]);\r\n                    } else {\r\n                        extended[prop] = obj[prop];\r\n                    }\r\n                }\r\n            }\r\n        };\r\n\r\n        /* Loop through each object and conduct a merge */\r\n        for (; i < length; i++) {\r\n            let obj = arguments[i];\r\n            merge(obj);\r\n        }\r\n\r\n        return extended;\r\n    };\r\n\r\n    function LazyLoad(images, options) {\r\n        this.settings = extend(defaults, options || {});\r\n        this.images = images || document.querySelectorAll(this.settings.selector);\r\n        this.observer = null;\r\n        this.init();\r\n    }\r\n\r\n    LazyLoad.prototype = {\r\n        init: function() {\r\n\r\n            /* Without observers load everything and bail out early. */\r\n            if (!root.IntersectionObserver) {\r\n                this.loadImages();\r\n                return;\r\n            }\r\n\r\n            let self = this;\r\n            let observerConfig = {\r\n                root: this.settings.root,\r\n                rootMargin: this.settings.rootMargin,\r\n                threshold: [this.settings.threshold]\r\n            };\r\n\r\n            this.observer = new IntersectionObserver(function(entries) {\r\n                Array.prototype.forEach.call(entries, function (entry) {\r\n                    if (entry.isIntersecting) {\r\n                        self.observer.unobserve(entry.target);\r\n                        let src = entry.target.getAttribute(self.settings.src);\r\n                        let srcset = entry.target.getAttribute(self.settings.srcset);\r\n                        if (\"img\" === entry.target.tagName.toLowerCase()) {\r\n                            if (src) {\r\n                                entry.target.src = src;\r\n                            }\r\n                            if (srcset) {\r\n                                entry.target.srcset = srcset;\r\n                            }\r\n                        } else {\r\n                            entry.target.style.backgroundImage = \"url(\" + src + \")\";\r\n                        }\r\n                    }\r\n                });\r\n            }, observerConfig);\r\n\r\n            Array.prototype.forEach.call(this.images, function (image) {\r\n                self.observer.observe(image);\r\n            });\r\n        },\r\n\r\n        loadAndDestroy: function () {\r\n            if (!this.settings) { return; }\r\n            this.loadImages();\r\n            this.destroy();\r\n        },\r\n\r\n        loadImages: function () {\r\n            if (!this.settings) { return; }\r\n\r\n            let self = this;\r\n            Array.prototype.forEach.call(this.images, function (image) {\r\n                let src = image.getAttribute(self.settings.src);\r\n                let srcset = image.getAttribute(self.settings.srcset);\r\n                if (\"img\" === image.tagName.toLowerCase()) {\r\n                    if (src) {\r\n                        image.src = src;\r\n                    }\r\n                    if (srcset) {\r\n                        image.srcset = srcset;\r\n                    }\r\n                } else {\r\n                    image.style.backgroundImage = \"url('\" + src + \"')\";\r\n                }\r\n            });\r\n        },\r\n\r\n        destroy: function () {\r\n            if (!this.settings) { return; }\r\n            this.observer.disconnect();\r\n            this.settings = null;\r\n        }\r\n    };\r\n\r\n    root.lazyload = function(images, options) {\r\n        return new LazyLoad(images, options);\r\n    };\r\n\r\n    if (root.jQuery) {\r\n        const $ = root.jQuery;\r\n        $.fn.lazyload = function (options) {\r\n            options = options || {};\r\n            options.attribute = options.attribute || \"data-src\";\r\n            new LazyLoad($.makeArray(this), options);\r\n            return this;\r\n        };\r\n    }\r\n\r\n    return LazyLoad;\r\n});\r\n","js/navigation-menu.js":"/**\n * Copyright \u00a9 2015 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*jshint jquery:true*/\n\ndefine([\n    \"jquery\",\n    \"matchMedia\",\n    \"mage/template\",\n    \"mage/dropdowns\",\n    \"mage/terms\"\n],function($, mediaCheck, mageTemplate) {\n    'use strict';\n\n    $.widget('mage.navigationMenu', {\n        options: {\n            itemsContainer: '> ul',\n            topLevel: 'li.level0',\n            topLevelSubmenu: '> .submenu',\n            topLevelHoverClass: 'hover',\n            expandedTopLevel: '.more',\n            hoverInTimeout: 300,\n            hoverOutTimeout: 500,\n            submenuAnimationSpeed: 200,\n            collapsable: true,\n            collapsableDropdownTemplate:\n                '<script type=\"text/x-magento-template\">' +\n                    '<li class=\"level0 level-top more parent\">' +\n                        '<div class=\"submenu\">' +\n                            '<ul><%= elems %></ul>' +\n                        '</div>' +\n                    '</li>' +\n                '</script>'\n        },\n\n        _create: function() {\n            this.itemsContainer = $(this.options.itemsContainer, this.element);\n            this.topLevel = $(this.options.topLevel, this.element);\n            this.topLevelSubmenu = $(this.options.topLevelSubmenu, this.topLevel);\n\n            this._bind();\n        },\n\n        _init: function() {\n            if (this.options.collapsable) {\n                setTimeout($.proxy(function() {\n                    this._checkToCollapseOrExpand();\n                }, this), 100);\n            }\n        },\n\n        _bind: function() {\n            this._on({\n                'mouseenter > ul > li.level0': function(e) {\n                    if (!this.entered) { // fix IE bug with 'mouseenter' event\n                        this.timeoutId && clearTimeout(this.timeoutId);\n                        this.timeoutId = setTimeout($.proxy(function() {\n                            this._openSubmenu(e);\n                        }, this), this.options.hoverInTimeout);\n                        this.entered = true;\n                    }\n                },\n                'mouseleave > ul > li.level0': function(e) {\n                    this.entered = null;\n\n                    this.timeoutId && clearTimeout(this.timeoutId);\n                    this.timeoutId = setTimeout($.proxy(function() {\n                        this._closeSubmenu(e.currentTarget);\n                    }, this), this.options.hoverOutTimeout);\n                },\n                'click': function(e) {\n                    e.stopPropagation();\n                }\n            });\n\n            $(document)\n                .on('click.hideMenu', $.proxy(function(e) {\n                    var isOpened = this.topLevel.filter(function() {\n                        return $(this).data('opened');\n                    });\n\n                    if (isOpened) {\n                        this._closeSubmenu(null, false);\n                    }\n                }, this));\n\n            $(window)\n                .on('resize', $.proxy(function() {\n                    this.timeoutOnResize && clearTimeout(this.timeoutOnResize);\n                    this.timeoutOnResize = setTimeout($.proxy(function() {\n                        if (this.options.collapsable) {\n                            if ($(this.options.expandedTopLevel, this.element).length) {\n                                this._expandMenu();\n                            }\n                            this._checkToCollapseOrExpand();\n                        }\n                    }, this), 300);\n                }, this));\n        },\n\n        _openSubmenu: function(e) {\n            var menuItem = e.currentTarget;\n\n            if (!$(menuItem).data('opened')) {\n                this._closeSubmenu(menuItem, true, true);\n\n                $(this.options.topLevelSubmenu, menuItem)\n                    .slideDown(this.options.submenuAnimationSpeed, $.proxy(function() {\n                        $(menuItem).addClass(this.options.topLevelHoverClass);\n                        $(menuItem).data('opened', true);\n                    }, this));\n            } else if ($(e.target).closest(this.options.topLevel)) {\n                $(e.target)\n                    .addClass(this.options.topLevelHoverClass)\n                    .siblings(this.options.topLevel)\n                        .removeClass(this.options.topLevelHoverClass);\n            }\n        },\n\n        _closeSubmenu: function(menuItem, excludeCurrent, fast) {\n            var topLevel = $(this.options.topLevel, this.element),\n                activeSubmenu = $(this.options.topLevelSubmenu, menuItem || null);\n\n            $(this.options.topLevelSubmenu, topLevel)\n                .filter(function() {\n                    return excludeCurrent ? $(this).not(activeSubmenu) : true;\n                })\n                .slideUp(fast ? 0 : this.options.submenuAnimationSpeed);\n\n            topLevel\n                .removeClass(this.options.topLevelHoverClass)\n                .data('opened', false);\n        },\n\n        _checkToCollapseOrExpand: function() {\n            if ($(\"html\").hasClass(\"lt-640\") || $(\"html\").hasClass(\"w-640\")) {\n                return;\n            }\n\n            var navWidth = this.itemsContainer.width(),\n                totalWidth = 0,\n                startCollapseIndex = 0;\n\n            $.each($(this.options.topLevel, this.element), function(index, item) {\n                totalWidth = totalWidth + $(item).outerWidth(true);\n\n                if (totalWidth > navWidth && !startCollapseIndex) {\n                    startCollapseIndex = index - 2;\n                }\n            });\n\n            this[startCollapseIndex ? '_collapseMenu' : '_expandMenu'](startCollapseIndex);\n        },\n\n        _collapseMenu: function(startCollapseIndex) {\n            this.elemsToCollapse = this.topLevel.filter(function(index) {\n                return index > startCollapseIndex;\n            });\n            this.elemsToCollapseClone = $('<div></div>').append(this.elemsToCollapse.clone()).html();\n\n            this.collapsableDropdown = $(\n                mageTemplate(\n                    this.options.collapsableDropdownTemplate,\n                    {elems: this.elemsToCollapseClone}\n                )\n            );\n\n            this.itemsContainer.append(this.collapsableDropdown);\n            this.elemsToCollapse.detach();\n        },\n\n        _expandMenu: function() {\n            this.elemsToCollapse && this.elemsToCollapse.appendTo(this.itemsContainer);\n            this.collapsableDropdown && this.collapsableDropdown.remove();\n        },\n\n        _destroy: function() {\n            this._expandMenu();\n        }\n    });\n\n    /*\n     * Provides \"Continium\" effect for submenu\n     * */\n    $.widget('mage.navigationMenu', $.mage.navigationMenu, {\n        options: {\n            parentLevel: '> ul > li.level0',\n            submenuAnimationSpeed: 150,\n            submenuContiniumEffect: false\n        },\n\n        _init: function() {\n            this._super();\n            this._applySubmenuStyles();\n        },\n\n        _applySubmenuStyles: function() {\n            $(this.options.topLevelSubmenu, $(this.options.topLevel, this.element))\n                .removeAttr('style');\n\n            $(this.options.topLevelSubmenu, $(this.options.parentLevel, this.element))\n                .css({\n                    display: 'block',\n                    height: 0,\n                    overflow: 'hidden'\n                });\n        },\n\n        _openSubmenu: function(e) {\n            var menuItem = e.currentTarget,\n                submenu = $(this.options.topLevelSubmenu, menuItem),\n                openedItems = $(this.options.topLevel, this.element).filter(function() {\n                    return $(this).data('opened');\n                });\n\n            if (submenu.length) {\n                this.heightToAnimate = $(this.options.itemsContainer, submenu).outerHeight(true);\n\n                if (openedItems.length) {\n                    this._closeSubmenu(menuItem, true, this.heightToAnimate, $.proxy(function() {\n                        submenu.css({\n                            height: 'auto'\n                        });\n                        $(menuItem)\n                            .addClass(this.options.topLevelHoverClass);\n                    }, this), e);\n                } else {\n                    submenu.animate({\n                        height: this.heightToAnimate\n                    }, this.options.submenuAnimationSpeed, $.proxy(function() {\n                        $(menuItem)\n                            .addClass(this.options.topLevelHoverClass);\n                    }, this));\n                }\n\n                $(menuItem)\n                    .data('opened', true);\n            } else {\n                this._closeSubmenu(menuItem);\n            }\n        },\n\n        _closeSubmenu: function(menuItem, excludeCurrent, heightToAnimate, callback, e) {\n            var topLevel = $(this.options.topLevel, this.itemsContainer),\n                expandedTopLevel = e && $(e.target).closest(this.options.expandedTopLevel);\n\n            if (!excludeCurrent) {\n                $(this.options.topLevelSubmenu, $(this.options.parentLevel, this.element))\n                    .animate({\n                        height: 0\n                    });\n\n                topLevel\n                    .data('opened', false)\n                    .removeClass(this.options.topLevelHoverClass);\n            } else {\n                var prevOpenedItem = topLevel.filter(function() {\n                        return $(this).data('opened');\n                    }),\n                    prevOpenedSubmenu = $(this.options.topLevelSubmenu, prevOpenedItem);\n\n                prevOpenedSubmenu.animate({\n                    height: heightToAnimate\n                }, this.options.submenuAnimationSpeed, 'linear', function() {\n                    $(this).css({\n                        height: 0\n                    });\n                    callback && callback();\n                });\n\n                prevOpenedItem\n                    .data('opened', false)\n                    .removeClass(this.options.topLevelHoverClass);\n            }\n        },\n\n        _collapseMenu: function() {\n            this._superApply(arguments);\n            this._applySubmenuStyles();\n        }\n    });\n\n    //  Responsive menu\n    $.widget('mage.navigationMenu', $.mage.navigationMenu, {\n        options: {\n            responsive: false,\n            origNavPlaceholder: '.page-header',\n            mainContainer: 'body',\n            pageWrapper: '.page-wrapper',\n            openedMenuClass: 'opened',\n            toggleActionPlaceholder: '.block-search',\n            itemWithSubmenu: 'li.parent',\n            titleWithSubmenu: 'li.parent > a',\n            submenu: 'li.parent > .submenu',\n            toggleActionTemplate:\n                '<script type=\"text/x-magento-template\">' +\n                    '<span data-action=\"toggle-nav\" class=\"action toggle nav\">Toggle Nav</span>' +\n                '</script>',\n            submenuActionsTemplate:\n                '<script type=\"text/x-magento-template\">' +\n                    '<li class=\"action all\">' +\n                        '<a href=\"<%= categoryURL %>\"><span>All <%= category %></span></a>' +\n                    '</li>' +\n                '</script>',\n            navigationSectionsWrapperTemplate:\n                '<script type=\"text/x-magento-template\">' +\n                    '<dl class=\"navigation-tabs\" data-sections=\"tabs\">' +\n                    '</dl>' +\n                '</script>',\n            navigationItemWrapperTemplate:\n                '<script type=\"text/x-magento-template\">' +\n                    '<dt class=\"item title <% if (active) { %>active<% } %>\" data-section=\"title\">' +\n                        '<a class=\"switch\" data-toggle=\"switch\" href=\"#TODO\"><%= title %></a>' +\n                    '</dt>' +\n                    '<dd class=\"item content <% if (active) { %>active<%}%>\" data-section=\"content\">' +\n                    '</dd>' +\n                '</script>'\n        },\n\n        _init: function() {\n            this._super();\n\n            this.mainContainer = $(this.options.mainContainer);\n            this.pageWrapper = $(this.options.pageWrapper);\n            this.toggleAction = $(mageTemplate(this.options.toggleActionTemplate, {}));\n\n            if (this.options.responsive) {\n                mediaCheck({\n                    media: '(min-width: 768px)',\n                    entry: $.proxy(function() {\n                        this._toggleDesktopMode();\n                    }, this),\n                    exit: $.proxy(function() {\n                        this._toggleMobileMode();\n                    }, this)\n                });\n            }\n        },\n\n        _bind: function() {\n            this._super();\n            this._bindDocumentEvents();\n        },\n\n        _bindDocumentEvents: function() {\n            if (!this.eventsBound) {\n                $(document)\n                    .on('click.toggleMenu', '.action.toggle.nav', $.proxy(function(e) {\n                        if ($(this.element).data('opened')) {\n                            this._hideMenu();\n                        } else {\n                            this._showMenu();\n                        }\n                        e.stopPropagation();\n                        this.mobileNav.scrollTop(0);\n                        this._fixedBackLink();\n                    }, this))\n                    .on('click.hideMenu', this.options.pageWrapper, $.proxy(function() {\n                        if ($(this.element).data('opened')) {\n                            this._hideMenu();\n                            this.mobileNav.scrollTop(0);\n                            this._fixedBackLink();\n                        }\n                    }, this))\n                    .on('click.showSubmenu', this.options.titleWithSubmenu, $.proxy(function(e) {\n                        this._showSubmenu(e);\n\n                        e.preventDefault();\n                        this.mobileNav.scrollTop(0);\n                        this._fixedBackLink();\n                    }, this))\n                    .on('click.hideSubmenu', '.action.back', $.proxy(function(e) {\n                        this._hideSubmenu(e);\n                        this.mobileNav.scrollTop(0);\n                        this._fixedBackLink();\n                    }, this));\n\n                this.eventsBound = true;\n            }\n        },\n\n        _showMenu: function() {\n            $(this.element).data('opened', true);\n            this.mainContainer.add( \"html\" ).addClass(this.options.openedMenuClass);\n        },\n\n        _hideMenu: function() {\n            $(this.element).data('opened', false);\n            this.mainContainer.add( \"html\" ).removeClass(this.options.openedMenuClass);\n        },\n\n        _showSubmenu: function(e) {\n            $(e.currentTarget).addClass('action back');\n            var submenu = $(e.currentTarget).siblings('.submenu');\n\n            submenu.addClass('opened');\n        },\n\n        _hideSubmenu: function(e) {\n            var submenuSelector = '.submenu',\n                submenu = $(e.currentTarget).next(submenuSelector);\n            $(e.currentTarget).removeClass('action back');\n            submenu.removeClass('opened');\n        },\n\n        _renderSubmenuActions: function() {\n            $.each(\n                $(this.options.itemWithSubmenu),\n                $.proxy(\n                    function(index, item) {\n                        var actions = $(\n                            mageTemplate(\n                                this.options.submenuActionsTemplate,\n                                {\n                                    category: $('> a > span', item).text(),\n                                    categoryURL: $('> a', item).attr('href')\n                                }\n                            )\n                            ),\n                            submenu = $('> .submenu', item),\n                            items = $('> ul', submenu);\n                            items.prepend(actions);\n                    },\n                    this\n                )\n            );\n        },\n\n        _toggleMobileMode: function() {\n            this._expandMenu();\n\n            $(this.options.topLevelSubmenu, $(this.options.topLevel, this.element))\n                .removeAttr('style');\n\n            this.toggleAction.insertBefore(this.options.toggleActionPlaceholder);\n            this.mobileNav = $(this.element).detach().clone();\n            this.mainContainer.prepend(this.mobileNav);\n            this.mobileNav.find('> ul').addClass('nav');\n            this._insertExtraItems();\n            this._wrapItemsInSections();\n            this.mobileNav.scroll($.proxy(\n                function() {\n                    this._fixedBackLink();\n                }, this\n            ));\n\n            this._renderSubmenuActions();\n            this._bindDocumentEvents();\n        },\n\n        _toggleDesktopMode: function() {\n            this.mobileNav && this.mobileNav.remove();\n            this.toggleAction.detach();\n            $(this.element).insertAfter(this.options.origNavPlaceholder);\n\n            $(document)\n                .off('click.toggleMenu', '.action.toggle.nav')\n                .off('click.hideMenu', this.options.pageWrapper)\n                .off('click.showSubmenu', this.options.titleWithSubmenu)\n                .off('click.hideSubmenu', '.action.back');\n\n            this.eventsBound = false;\n\n            this._applySubmenuStyles();\n        },\n\n        _insertExtraItems: function() {\n            if ($('.header.panel .switcher').length) {\n                var settings = $('.header.panel .switcher')\n                    .clone()\n                    .addClass('settings');\n\n                this.mobileNav.prepend(settings);\n            }\n\n            if ($('.footer .switcher').length) {\n                var footerSettings = $('.footer .switcher')\n                    .clone()\n                    .addClass('settings');\n\n                this.mobileNav.prepend(footerSettings);\n            }\n\n\n            if ($('.header.panel .header.links li').length) {\n                var account = $('.header.panel > .header.links')\n                    .clone()\n                    .addClass('account');\n\n                this.mobileNav.prepend(account);\n            }\n        },\n\n        _wrapItemsInSections: function() {\n            var account = $('> .account', this.mobileNav),\n                settings = $('> .settings', this.mobileNav),\n                nav = $('> .nav', this.mobileNav),\n                navigationSectionsWrapper = $(mageTemplate(this.options.navigationSectionsWrapperTemplate, {})),\n                navigationItemWrapper;\n\n            this.mobileNav.append(navigationSectionsWrapper);\n\n            if (nav.length) {\n                navigationItemWrapper = $(mageTemplate(this.options.navigationItemWrapperTemplate, {title: 'Menu'}));\n                navigationSectionsWrapper.append(navigationItemWrapper);\n                navigationItemWrapper.eq(1).append(nav);\n            }\n\n            if (account.length) {\n                navigationItemWrapper = $(mageTemplate(this.options.navigationItemWrapperTemplate, {title: 'Account'}));\n                navigationSectionsWrapper.append(navigationItemWrapper);\n                navigationItemWrapper.eq(1).append(account);\n            }\n\n            if (settings.length) {\n                navigationItemWrapper = $(\n                    mageTemplate(this.options.navigationItemWrapperTemplate, {title: 'Settings'})\n                );\n                navigationSectionsWrapper.append(navigationItemWrapper);\n                navigationItemWrapper.eq(1).append(settings);\n            }\n\n            navigationSectionsWrapper.addClass(\"navigation-tabs-\" + navigationSectionsWrapper.find('[data-section=\"title\"]').length);\n            navigationSectionsWrapper.terms();\n        },\n\n        _fixedBackLink: function() {\n            var linksBack = this.mobileNav.find('.submenu .action.back');\n            var linkBack = this.mobileNav.find('.submenu.opened > ul > .action.back').last();\n\n            linksBack.removeClass('fixed');\n\n            if(linkBack.length) {\n                var subMenu = linkBack.parent(),\n                    navOffset = this.mobileNav.find('.nav').position().top,\n                    linkBackHeight = linkBack.height();\n\n                if (navOffset <= 0) {\n                    linkBack.addClass('fixed');\n                    subMenu.css({\n                        paddingTop: linkBackHeight\n                    })\n                } else {\n                    linkBack.removeClass('fixed');\n                    subMenu.css({\n                        paddingTop: 0\n                    })\n                }\n            }\n        }\n    });\n\n    return $.mage.navigationMenu;\n});\n","js/jquery.sticky.min.js":"(function(t,s){s.fn.themePin=function(t){var o=0,e=0,i=[],a=!1,n=s(window),p=[],r=[];t=t||{};var c=function(){for(var o=0,e=i.length;o<e;o++){var p=i[o];if(t.minWidth&&n.width()<=t.minWidth)p.parent().is(\".pin-wrapper\")&&p.unwrap(),p.css({width:\"\",left:\"\",top:\"\",position:\"\"}),t.activeClass&&p.removeClass(t.activeClass),p.removeClass(\"sticky-transition\"),p.removeClass(\"sticky-absolute\"),a=!0;else{a=!1;var r=t.containerSelector?p.closest(t.containerSelector).length?p.closest(t.containerSelector):s(t.containerSelector):s(document.body),c=p.offset(),d=r.offset();if(void 0!==d){var l=p.parent().offset();p.parent().is(\".pin-wrapper\")||p.wrap(\"<div class='pin-wrapper'>\");var f=s.extend({top:0,bottom:0},t.padding||{}),h=parseInt(p.parent().parent().css(\"padding-top\")),u=parseInt(p.parent().parent().css(\"padding-bottom\"));t.autoInit&&(s(\"#header\").hasClass(\"header-side\")?(f.top=0,s(\".page-top.fixed-pos\").length&&(f.top+=s(\".page-top.fixed-pos\").height())):f.top=0,void 0!==t.paddingOffsetTop?f.top+=parseInt(t.paddingOffsetTop,10):f.top+=0,void 0!==t.paddingOffsetBottom?f.bottom=parseInt(t.paddingOffsetBottom,10):f.bottom=0);var m=p.css(\"border-bottom\"),v=p.outerHeight();p.css(\"border-bottom\",\"1px solid transparent\");var C=p.outerHeight()-v-1;p.css(\"border-bottom\",m),p.css({width:p.outerWidth()<=p.parent().width()?p.outerWidth():p.parent().width()}),p.parent().css(\"height\",p.outerHeight()+C),!t.autoFit&&!t.fitToBottom||p.outerHeight()<=n.height()?p.data(\"themePin\",{pad:f,from:(t.containerSelector?d.top:c.top)-f.top+h,pb:u,parentTop:l.top-h,offset:C}):p.data(\"themePin\",{pad:f,fromFitTop:(t.containerSelector?d.top:c.top)-f.top+h,from:(t.containerSelector?d.top:c.top)+p.outerHeight()-s(window).height()+h,pb:u,parentTop:l.top-h,offset:C})}}}},d=function(){if(!a){o=n.scrollTop();for(var c=window.innerHeight||n.height(),d=0,l=i.length;d<l;d++){var f,h=s(i[d]),u=h.data(\"themePin\"),m=u.to;if(u){var v=t.containerSelector?h.closest(t.containerSelector).length?h.closest(t.containerSelector):s(t.containerSelector):s(document.body),C=h.outerHeight()+u.pad.top<=c;if(u.end=v.offset().top+v.height(),C?u.to=v.offset().top+v.height()-h.outerHeight()-u.pad.bottom-u.pb:(u.to=v.offset().top+v.height()-c-u.pb,u.to2=v.height()-h.outerHeight()-u.pad.bottom-u.pb),C){var b=u.from-u.pad.bottom,g=u.to-u.pad.top-u.offset;if(void 0!==u.fromFitTop&&u.fromFitTop&&(b=u.fromFitTop-u.pad.bottom),b+h.outerHeight()>u.end||b>=g){h.css({position:\"\",top:\"\",left:\"\"}),t.activeClass&&h.removeClass(t.activeClass),h.removeClass(\"sticky-transition\"),h.removeClass(\"sticky-absolute\");continue}o>b&&o<g?(!(\"fixed\"==h.css(\"position\"))&&h.css({left:h.offset().left,top:u.pad.top}).css(\"position\",\"fixed\"),t.activeClass&&h.addClass(t.activeClass),h.removeClass(\"sticky-transition\"),h.removeClass(\"sticky-absolute\")):o>=g?(h.css({left:\"\",top:g-u.parentTop+u.pad.top}).css(\"position\",\"absolute\"),t.activeClass&&h.addClass(t.activeClass),h.hasClass(\"sticky-absolute\")&&h.addClass(\"sticky-transition\"),h.addClass(\"sticky-absolute\")):(h.css({position:\"\",top:\"\",left:\"\"}),t.activeClass&&h.removeClass(t.activeClass),h.removeClass(\"sticky-transition\"),h.removeClass(\"sticky-absolute\"))}else if(m!=u.to&&(p[d]=r[d]=!1),h.height()+u.pad.top+u.pad.bottom>c||p[d]||r[d]){var y=parseInt(h.parent().parent().css(\"padding-top\"));o+u.pad.top-y<=u.parentTop?(h.css({position:\"\",top:\"\",bottom:\"\",left:\"\"}),p[d]=r[d]=!1):o>=u.to?(h.css({left:\"\",top:u.to2,bottom:\"\"}).css(\"position\",\"absolute\"),t.activeClass&&h.addClass(t.activeClass),h.hasClass(\"sticky-absolute\")&&h.addClass(\"sticky-transition\"),h.addClass(\"sticky-absolute\")):o>=e?p[d]?(p[d]=!1,f=h.offset().top-u.parentTop,h.css({left:\"\",top:f,bottom:\"\"}).css(\"position\",\"absolute\"),t.activeClass&&h.addClass(t.activeClass),h.hasClass(\"sticky-absolute\")&&h.addClass(\"sticky-transition\"),h.addClass(\"sticky-absolute\")):!r[d]&&h.height()+h.offset().top+u.pad.bottom<o+c&&(r[d]=!0,!(\"fixed\"==h.css(\"position\"))&&h.css({left:h.offset().left,bottom:u.pad.bottom,top:\"\"}).css(\"position\",\"fixed\"),t.activeClass&&h.addClass(t.activeClass),h.removeClass(\"sticky-transition\"),h.removeClass(\"sticky-absolute\")):o<e&&(r[d]?(r[d]=!1,f=h.offset().top-u.parentTop,h.css({left:\"\",top:f,bottom:\"\"}).css(\"position\",\"absolute\"),t.activeClass&&h.addClass(t.activeClass),h.hasClass(\"sticky-absolute\")&&h.addClass(\"sticky-transition\"),h.addClass(\"sticky-absolute\")):!p[d]&&h.offset().top>=o+u.pad.top&&(p[d]=!0,!(\"fixed\"==h.css(\"position\"))&&h.css({left:h.offset().left,top:u.pad.top,bottom:\"\"}).css(\"position\",\"fixed\"),t.activeClass&&h.addClass(t.activeClass),h.removeClass(\"sticky-transition\"),h.removeClass(\"sticky-absolute\")))}else o>=u.parentTop-u.pad.top?h.css({position:\"fixed\",top:u.pad.top}):h.css({position:\"\",top:\"\",bottom:\"\",left:\"\"}),p[d]=r[d]=!1}}e=o}},l=function(){c(),d()};return this.each(function(){var t=s(this),o=s(this).data(\"themePin\")||{};o&&o.update||(i.push(t),s(\"img\",this).one(\"load\",c),o.update=l,s(this).data(\"themePin\",o),p.push(!1),r.push(!1))}),s(window).on(\"smartresize\",function(){c(),d()}),s(window).on(\"touchmove scroll\",d),c(),s(this).bind(\"recalc.pin\",function(){c(),d()}),this},t=t||{};var o=function(t,s){return this.initialize(t,s)};o.defaults={autoInit:!1,minWidth:992,activeClass:\"sticky-active\",padding:{top:0,bottom:0},offsetTop:0,offsetBottom:0,autoFit:!1,fitToBottom:!1},o.prototype={initialize:function(t,s){return t.data(\"__sticky\")?this:(this.$el=t,this.setData().setOptions(s).build(),this)},setData:function(){return this.$el.data(\"__sticky\",this),this},setOptions:function(t){return this.options=s.extend(!0,{},o.defaults,t,{wrapper:this.$el}),this},build:function(){if(!s.isFunction(s.fn.themePin))return this;var t=this.options.wrapper;return t.themePin(this.options),s(window).on(\"resize\",function(){if(setTimeout(function(){t.trigger(\"recalc.pin\")},800),s(window).width()>991){var o=t.parent();t.outerWidth(o.width()),\"fixed\"==t.css(\"position\")&&t.css(\"left\",o.offset().left)}}),this}},s.extend(t,{Sticky:o}),s.fn.themeSticky=function(o){return this.map(function(){var e=s(this);return e.data(\"__sticky\")?(e.trigger(\"recalc.pin\"),setTimeout(function(){e.trigger(\"recalc.pin\")},800),e.data(\"__sticky\")):new t.Sticky(e,o)})}}).apply(this,[window.theme,jQuery]);\n","js/responsive.js":"/**\n * Copyright \u00a9 2015 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'matchMedia',\n    'mage/tabs',\n    'domReady!'\n], function ($, mediaCheck) {\n    'use strict';\n\n    mediaCheck({\n        media: '(min-width: 768px)',\n        // Switch to Desktop Version\n        entry: function () {\n            (function () {\n\n                var productInfoMain = $('.product-info-main'),\n                    productInfoAdditional = $('#product-info-additional');\n\n                if (productInfoAdditional.length) {\n                    productInfoAdditional.addClass('hidden');\n                    productInfoMain.removeClass('responsive');\n                }\n\n            })();\n\n            var galleryElement = $('[data-role=media-gallery]');\n\n            if (galleryElement.length && galleryElement.data('mageZoom')) {\n                galleryElement.zoom('enable');\n            }\n\n            if (galleryElement.length && galleryElement.data('mageGallery')) {\n                galleryElement.gallery('option', 'disableLinks', true);\n                galleryElement.gallery('option', 'showNav', false);\n                galleryElement.gallery('option', 'showThumbs', true);\n            }\n\n            setTimeout(function () {\n\t\t\t\tif(!$('.product.info.detailed').hasClass(\"sticky\"))\n\t                $('.product.data.items').tabs('option', 'openOnFocus', true);\n            }, 500);\n        },\n        // Switch to Mobile Version\n        exit: function () {\n            $('.action.toggle.checkout.progress')\n                .on('click.gotoCheckoutProgress', function () {\n                    var myWrapper = '#checkout-progress-wrapper';\n                    scrollTo(myWrapper + ' .title');\n                    $(myWrapper + ' .title').addClass('active');\n                    $(myWrapper + ' .content').show();\n                });\n\n            $('body')\n                .on('click.checkoutProgress', '#checkout-progress-wrapper .title', function () {\n                    $(this).toggleClass('active');\n                    $('#checkout-progress-wrapper .content').toggle();\n                });\n\n            var galleryElement = $('[data-role=media-gallery]');\n\n            setTimeout(function () {\n                if (galleryElement.length && galleryElement.data('mageZoom')) {\n                    galleryElement.zoom('disable');\n                }\n\n                if (galleryElement.length && galleryElement.data('mageGallery')) {\n                    galleryElement.gallery('option', 'disableLinks', false);\n                    galleryElement.gallery('option', 'showNav', true);\n                    galleryElement.gallery('option', 'showThumbs', false);\n                }\n            }, 2000);\n\n            setTimeout(function () {\n\t\t\t\tif(!$('.product.info.detailed').hasClass(\"sticky\"))\n\t\t\t\t\t$('.product.data.items').tabs('option', 'openOnFocus', false);\n            }, 500);\n        }\n    });\n});\n","Magento_ReCaptchaCheckout/js/webapiReCaptchaRegistry-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    return function (originalFunction) {\n        /**\n         * {@inheritDoc}\n         */\n       originalFunction.addListener = function (id , func) {\n            this._listeners[id] = func;\n       };\n\n        return originalFunction;\n    };\n\n});\n","Magento_ReCaptchaCheckout/js/model/place-order-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable max-nested-callbacks */\n\ndefine([\n    'jquery',\n    'mage/utils/wrapper',\n    'Magento_ReCaptchaWebapiUi/js/webapiReCaptchaRegistry'\n], function ($, wrapper, recaptchaRegistry) {\n    'use strict';\n\n    return function (placeOrder) {\n        return wrapper.wrap(placeOrder, function (originalAction, serviceUrl, payload, messageContainer) {\n            var recaptchaDeferred;\n\n            if (recaptchaRegistry.triggers.hasOwnProperty('recaptcha-checkout-place-order')) {\n                //ReCaptcha is present for checkout\n                recaptchaDeferred = $.Deferred();\n                recaptchaRegistry.addListener('recaptcha-checkout-place-order', function (token) {\n                    //Add reCaptcha value to place-order request and resolve deferred with the API call results\n                    payload.xReCaptchaValue = token;\n                    originalAction(serviceUrl, payload, messageContainer).done(function () {\n                        recaptchaDeferred.resolve.apply(recaptchaDeferred, arguments);\n                    }).fail(function () {\n                        recaptchaDeferred.reject.apply(recaptchaDeferred, arguments);\n                    });\n                });\n                //Trigger ReCaptcha validation\n                recaptchaRegistry.triggers['recaptcha-checkout-place-order']();\n\n                if (\n                    !recaptchaRegistry._isInvisibleType.hasOwnProperty('recaptcha-checkout-place-order') ||\n                    recaptchaRegistry._isInvisibleType['recaptcha-checkout-place-order'] === false\n                ) {\n                    //remove listener so that place order action is only triggered by the 'Place Order' button\n                    recaptchaRegistry.removeListener('recaptcha-checkout-place-order');\n                }\n\n                return recaptchaDeferred;\n            }\n\n            //No ReCaptcha, just sending the request\n            return originalAction(serviceUrl, payload, messageContainer);\n        });\n    };\n});\n","Magento_Newsletter/js/newsletter-sign-up.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'uiElement',\n    'mage/url',\n    'subscriptionStatusResolver',\n    'mage/validation'\n], function ($, Component, urlBuilder, subscriptionStatusResolver) {\n    'use strict';\n\n    return Component.extend({\n\n        defaults: {\n            signUpElement: '',\n            submitButton: '',\n            element: null\n        },\n\n        /** @inheritdoc */\n        initialize: function (config, element) {\n            this._super();\n            this.element = element;\n            $(element).on('change', $.proxy(this.updateSignUpStatus, this));\n            this.updateSignUpStatus();\n        },\n\n        /**\n         * Send status request and update subscription element according to result.\n         */\n        updateSignUpStatus: function () {\n            var element = $(this.element),\n                email = element.val(),\n                self = this,\n                newsletterSubscription;\n\n            if ($(self.signUpElement).is(':checked')) {\n                return;\n            }\n\n            if (!email || !$.validator.methods['validate-email'].call(this, email, element)) {\n                return;\n            }\n\n            newsletterSubscription = $.Deferred();\n\n            $(self.submitButton).prop('disabled', true);\n\n            subscriptionStatusResolver(email, newsletterSubscription);\n\n            $.when(newsletterSubscription).done(function (isSubscribed) {\n                if (isSubscribed) {\n                    $(self.signUpElement).prop('checked', true);\n                }\n            }).always(function () {\n                $(self.submitButton).prop('disabled', false);\n            });\n        }\n    });\n});\n","Magento_Newsletter/js/subscription-status-resolver.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/url'\n], function ($, urlBuilder) {\n    'use strict';\n\n    return function (email, deferred) {\n        return $.getJSON(\n            urlBuilder.build('newsletter/ajax/status'),\n            {\n                email: email\n            }\n        ).done(function (response) {\n            if (response.errors) {\n                deferred.reject();\n            } else {\n                deferred.resolve(response.subscribed);\n            }\n        }).fail(function () {\n            deferred.reject();\n        });\n    };\n});\n"}
}});