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/thenirvana.org/www/wp-content/plugins/revslider/includes/
Upload File :
Current File : /home/thenirvana.org/www/wp-content/plugins/revslider/includes/external-sources.class.php
<?php
/**
 * External Sources Input Classes for Back and Front End
 * @since: 5.0
 * @author    ThemePunch <info@themepunch.com>
 * @link      https://revolution.themepunch.com/
 * @copyright 2019 ThemePunch
 */

if(!defined('ABSPATH')) exit();

use InstagramScraper\Instagram;

/**
 * Facebook
 *
 * with help of the API this class delivers album images from Facebook
 *
 * @package    socialstreams
 * @subpackage socialstreams/facebook
 * @author     ThemePunch <info@themepunch.com>
 */

class RevSliderFacebook extends RevSliderFunctions {
	/**
	 * Stream Array
	 *
	 * @since	1.0.0
	 * @access	private
	 * @var		array	$stream		Stream Data Array
	 */
	private $stream;

	/**
	* Transient seconds
	*
	* @since	1.0.0
	* @access	private
	* @var		number	$transient	Transient time in seconds
	*/
	private $transient_sec;

	public function __construct($transient_sec = 1200){
		$this->transient_sec = 	$transient_sec;
	} 

	/**
	 * Get User ID from its URL
	 *
	 * @since	1.0.0
	 * @param	string	$user_url URL of the Page
	 */
	public function get_user_from_url($user_url){
		$theid = str_replace('https', '', $user_url);
		$theid = str_replace(array('https', 'http', '://', 'www.', 'facebook', '.com', "/"), '', $user_url);
		$theid = explode('?', $theid);
		
		return trim($theid[0]);
	}

	/**
	 * Get Photosets List from User
	 *
	 * @since	1.0.0
	 * @param	string	$user_id 	Facebook User id (not name)
	 * @param	int	$item_count 	number of photos to pull
	 */
	public function get_photo_sets($user_id, $item_count = 10, $access_token){
		//photoset params
		$url = "https://graph.facebook.com/$user_id/albums?access_token=" . $access_token;
		$photo_sets_list = json_decode(wp_remote_fopen($url));
		if(!empty($photo_sets_list->error->message)){
			return array("error",$photo_sets_list->error->message);
		}
		return $this->get_val($photo_sets_list, 'data');
	}

	/**
	 * Get Photoset Photos
	 *
	 * @since	5.1.1 
	 * @param	string	$photo_set_id 	Photoset ID
	 * @param	int		$item_count 	number of photos to pull
	 */
	public function get_photo_set_photos($photo_set_id, $item_count = 10, $access_token){
		$url = "https://graph.facebook.com/".$photo_set_id."/photos?fields=photos&access_token=" . $access_token ."&fields=id,from,message,picture,images,link,name,icon,privacy,type,status_type,application,created_time,updated_time,is_hidden,is_expired,comments.limit(1).summary(true),likes.limit(1).summary(true)";

		$transient_name = 'revslider_' . md5($url);

		if($this->transient_sec > 0 && false !== ($data = get_transient($transient_name))){
			return $data;
		}
		
		$photo_set_photos = json_decode(wp_remote_fopen($url));
		
		$data = $this->get_val($photo_set_photos, 'data');
		if($data !== ''){
			set_transient($transient_name, $data, $this->transient_sec);
		}
		
		return $data;
	}

	/**
	 * Get Photosets List from User as Options for Selectbox
	 *
	 * @since	1.0.0
	 * @param	string	$user_url 	Facebook User id (not name)
	 * @param	int	$item_count 	number of photos to pull
	 */
	public function get_photo_set_photos_options($user_url, $current_album, $access_token, $item_count = 99){
		$user_id = $this->get_user_from_url($user_url);
		$photo_sets = $this->get_photo_sets($user_id, 999, $access_token);
		
		if(isset( $photo_sets[0] ) && $photo_sets[0] == "error"){
			return $photo_sets;
		}
		
		if(empty($current_album)) $current_album = '';
		
		$return = array();
		if(is_array($photo_sets)){
			foreach($photo_sets as $photo_set){
				$return[] = '<option title="'.$this->get_val($photo_set, 'name').'" '.selected($this->get_val($photo_set, 'id'), $current_album, false).' value="'.$this->get_val($photo_set, 'id').'">'.$this->get_val($photo_set, 'name').'</option>"';
			}
		}
		return $return;
	}
	

	/**
	 * Get Feed
	 *
	 * @since	1.0.0
	 * @param	string	$user 	User ID
	 * @param	int		$item_count 	number of itmes to pull
	 */
	public function get_photo_feed($user, $access_token, $item_count = 10){
		$url = "https://graph.facebook.com/$user/feed?access_token=" . $access_token ."&fields=full_picture,picture,attachments{media,media_type,url},icon,message,likes.limit(1).summary(true),comments.limit(1).summary(true)";

		$transient_name = 'revslider_' . md5($url);
		if($this->transient_sec > 0 && false !== ($data = get_transient($transient_name))){
			return $data;
		}
		
		$feed = json_decode(wp_remote_fopen($url));

		$data = $this->get_val($feed, 'data');
		if($data !== ''){
			set_transient($transient_name, $data, $this->transient_sec);
		}
		
		return $data;
	}

	/**
	 * Decode URL from feed
	 *
	 * @since	1.0.0
	 * @param	string	$url 	facebook Output Data
	 */
	private function decode_facebook_url($url){
		$url = str_replace('u00253A', ':', $url);
		$url = str_replace('\u00255C\u00252F', '/', $url);
		$url = str_replace('u00252F', '/', $url);
		$url = str_replace('u00253F', '?', $url);
		$url = str_replace('u00253D', '=', $url);
		$url = str_replace('u002526', '&', $url);
		
		return $url;
	}
}  // End Class

/**
 * Twitter
 *
 * with help of the API this class delivers all kind of tweeted images from twitter
 *
 * @package		socialstreams
 * @subpackage	socialstreams/twitter
 * @author		ThemePunch <info@themepunch.com>
 */

class RevSliderTwitter extends RevSliderFunctions {

	/**
	* Consumer Key
	*
	* @since	1.0.0
	* @access	private
	* @var		string	$consumer_key    Consumer Key
	*/
	private $consumer_key;

	/**
	* Consumer Secret
	*
	* @since	1.0.0
	* @access	private
	* @var		string	$consumer_secret    Consumer Secret
	*/
	private $consumer_secret;

	/**
	* Access Token
	*
	* @since	1.0.0
	* @access	private
	* @var		string	$access_token	Access Token
	*/
	private $access_token;

	/**
	* Access Token Secret
	*
	* @since	1.0.0
	* @access	private
	* @var		string	$access_token_secret	Access Token Secret
	*/
	private $access_token_secret;

	/**
	* Twitter Account
	*
	* @since	1.0.0
	* @access	private
	* @var		string	$twitter_account	Account User Name
	*/
	private $twitter_account;

	/**
	* Transient seconds
	*
	* @since	1.0.0
	* @access	private
	* @var		number	$transient Transient time in seconds
	*/
	private $transient_sec;

	/**
	* Stream Array
	*
	* @since	1.0.0
	* @access	private
	* @var		array	$stream	Stream Data Array
	*/
	private $stream;

	/**
	* Initialize the class and set its properties.
	*
	* @since	1.0.0
	* @param	string	$consumer_key Twitter App Registration Consomer Key
	* @param	string	$consumer_secret Twitter App Registration Consomer Secret
	* @param	string	$access_token Twitter App Registration Access Token
	* @param	string	$access_token_secret Twitter App Registration Access Token Secret
	*/
	public function __construct($consumer_key, $consumer_secret, $access_token, $access_token_secret, $transient_sec = 1200){
		$this->consumer_key			= $consumer_key;
		$this->consumer_secret		= $consumer_secret;
		$this->access_token			= $access_token;
		$this->access_token_secret  = $access_token_secret;
		$this->transient_sec		= $transient_sec;
	} 

	/**
	* Get Tweets
	*
	* @since	1.0.0
	* @param	string	$twitter_account	Twitter account without trailing @ char
	*/
	public function get_public_photos($twitter_account, $include_rts, $exclude_replies, $count, $imageonly){
		
		//require_once( 'class-wp-twitter-api.php');
		//Set your personal data retrieved at https://dev.twitter.com/apps
		$credentials = array(
			'consumer_key'		=> $this->consumer_key,
			'consumer_secret'	=> $this->consumer_secret 
		);
		// Let's instantiate our class with our credentials
		$twitter_api = new RevSliderTwitterApi($credentials, $this->transient_sec);
		
		$include_rts = ($include_rts == 'on') ? 'true' : 'false';
		$exclude_replies = ($include_rts == 'on') ? 'false' : 'true'; 
	
		$query = '&tweet_mode=extended&count=500&include_entities=true&include_rts='.$include_rts.'&exclude_replies='.$exclude_replies.'&screen_name='.$twitter_account;
		
		$tweets = $twitter_api->query($query);
	
		return (!empty($tweets)) ? $tweets : '';
	}


	/**
	* Find Key in array and return value (multidim array possible)
	*
	* @since	1.0.0
	* @param	string	$key	Needle
	* @param	array	$form	Haystack
	*/
	public function array_find_element_by_key($key, $form){
		if(is_array($form) && array_key_exists($key, $form)){
			$ret = $form[$key];
			
			return $ret;
		}
		
		if(is_array($form)){
			foreach($form as $k => $v){
				if(is_array($v)){
					$ret = $this->array_find_element_by_key($key, $form[$k]);
					if($ret){
						return $ret;
					}
				}
			}
		}
		
		return false;
	}
} // End Class

/**
* Class WordPress Twitter API
*
* https://github.com/micc83/Twitter-API-1.1-Client-for-Wordpress/blob/master/class-wp-twitter-api.php
* @version 1.0.0
*/
class RevSliderTwitterApi extends RevSliderFunctions {
	public $bearer_token;
	// Default credentials
	public $args = array(
		'consumer_key'		=> 'default_consumer_key',
		'consumer_secret'	=> 'default_consumer_secret'
	);
	// Default type of the resource and cache duration
	public $query_args = array(
		'type'	=> 'statuses/user_timeline',
		'cache'	=> 1800
	);

	public $has_error = false;
	
	/**
	* WordPress Twitter API Constructor
	*
	* @param array $args
	*/
	public function __construct($args = array(), $transient_sec = 1200){
		
		if(is_array($args) && !empty($args))
			$this->args = array_merge($this->args, $args);
		
		if(!$this->bearer_token = get_option('twitter_bearer_token'))
			$this->bearer_token = $this->get_bearer_token();
		
		$this->query_args['cache'] = $transient_sec;
	}
	
	/**
	* Get the token from oauth Twitter API
	*
	* @return string Oauth Token
	*/
	private function get_bearer_token(){
			
		$bearer_token_credentials = $this->get_val($this->args, 'consumer_key') . ':' . $this->get_val($this->args, 'consumer_secret');
		$bearer_token_credentials_64 = base64_encode($bearer_token_credentials);
		
		$args = array(
			'method'		=> 'POST',
			'timeout'		=> 5,
			'redirection'	=> 5,
			'httpversion'	=> '1.0',
			'blocking'		=> true,
			'headers'		=> array(
				'Authorization'		=> 'Basic ' . $bearer_token_credentials_64,
				'Content-Type'		=> 'application/x-www-form-urlencoded;charset=UTF-8',
				'Accept-Encoding'	=> 'gzip'
			),
			'body'		=> array('grant_type' => 'client_credentials'),
			'cookies'	=> array()
		);
		
		$response = wp_remote_post('https://api.twitter.com/oauth2/token', $args);
		
		if(is_wp_error($response) || 200 != $response['response']['code'])
			return $this->bail(__( 'Can\'t get the bearer token, check your credentials', 'revslider'), $response);
		
		$result = json_decode($this->get_val($response, 'body'));
		
		update_option('twitter_bearer_token', $this->get_val($result, 'access_token'));
		
		return $this->get_val($result, 'access_token');
	}
	
	/**
	* Query twitter's API
	*
	* @uses $this->get_bearer_token() to retrieve token if not working
	*
	* @param string $query Insert the query in the format "count=1&include_entities=true&include_rts=true&screen_name=micc1983!
	* @param array $query_args Array of arguments: Resource type (string) and cache duration (int)
	* @param bool $stop Stop the query to avoid infinite loop
	*
	* @return bool|object Return an object containing the result
	*/
	public function query($query, $query_args = array(), $stop = false){
		if($this->has_error)
			return false;
		
		if(is_array($query_args) && !empty($query_args)){
			$this->query_args = array_merge($this->query_args, $query_args);
		}
		
		$transient_name = 'wta_' . md5($query);

		if($this->get_val($this->query_args, 'cache', 0) > 0 && false !== ($data = get_transient($transient_name)))
			return json_decode($data);
		
		$args = array(
			'method'		=> 'GET',
			'timeout'		=> 5,
			'redirection'	=> 5,
			'httpversion'	=> '1.0',
			'blocking'		=> true,
			'headers'		=> array(
				'Authorization'		=> 'Bearer ' . $this->bearer_token,
				'Accept-Encoding'	=> 'gzip'
			),
			'body'		=> null,
			'cookies'	=> array()
		);
		
		$response = wp_remote_get('https://api.twitter.com/1.1/'. $this->get_val($this->query_args, 'type') . '.json?' . $query, $args);
		if(is_wp_error($response) || 200 != $response['response']['code']){
			if(!$stop){
				$this->bearer_token = $this->get_bearer_token();
				return $this->query($query, $this->query_args, true);
			}else{
				return $this->bail(__('Bearer Token is good, check your query', 'revslider'), $response);
			}
		}
		set_transient($transient_name, $response['body'], $this->query_args['cache']);
		
		return json_decode($response['body']);
	}
	
	/**
	* Let's manage errors
	*
	* WP_DEBUG has to be set to true to show errors
	*
	* @param string $error_text Error message
	* @param string $error_object Server response or wp_error
	*/
	private function bail($error_text, $error_object = ''){
		
		$this->has_error = true;
		
		if(is_wp_error($error_object)){
			$error_text .= ' - Wp Error: ' . $error_object->get_error_message();
		}elseif(!empty($error_object) && isset($error_object['response']['message'])){
			$error_text .= ' ( Response: ' . $error_object['response']['message'] . ')';
		}
		
		trigger_error($error_text , E_USER_NOTICE);
	}
}


/**
 * Instagram
 *
 * with help of the API this class delivers all kind of Images from instagram
 *
 * @package    socialstreams
 * @subpackage socialstreams/instagram
 * @author     ThemePunch <info@themepunch.com>
 */


if(!function_exists('rev_instagram_autoloader')){

	function rev_instagram_autoloader($class)
	{
		if(strpos($class, 'InstagramScraper') !== false || strpos($class, 'Unirest') !== false) {
			$filename = realpath(dirname(__FILE__)) .'/'. str_replace('\\', '/', $class) . '.php';
			include_once ($filename);
		}
	} 
}

class RevSliderInstagram  extends RevSliderFunctions {

	/**
	 * API key
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $api_key    Instagram API key
	 */
	private $api_key;

	/**
	 * Stream Array
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      array    $stream    Stream Data Array
	 */
	private $stream;

	/**
	 * Transient seconds
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      number    $transient Transient time in seconds
	*/
	private $transient_sec;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 * @param      string    $api_key	Instagram API key.
	 */
	public function __construct($transient_sec = 1200){
		spl_autoload_register('rev_instagram_autoloader');
		$this->transient_sec = $transient_sec;
	}

	/**
	 * Get Instagram Users Pictures CSV list
	 *
	 * @since    3.0
	 * @param    string    $user_id 	Instagram User id (not name)
	 */
	public function get_users_photos($search_user_id, $count, $orig_image = ''){
		$search_user_array = explode(',', $search_user_id);
		if(is_array($search_user_array)){
			foreach($search_user_array as $search_user){
				$this->get_public_photos(trim($search_user), $count, $orig_image);
			}
		}else{
			$this->get_public_photos(trim($search_user_id), $count, $orig_image);
		}
		
		return $this->stream;
	}

	/**
	 * Get Instagram User Pictures
	 *
	 * @since    3.0
	 * @param    string    $user_id 	Instagram User id (not name)
	 */
	public function get_public_photos($search_user_id, $count, $orig_image = ''){
		
		//Loads autoloader for Instragram scrapper requirements

		if(!empty($search_user_id)){
			$cacheKey = 'instagram' . '-' . $search_user_id . '-' . $count;
			
			$transient_name = 'revslider_'. md5($cacheKey);
			if($this->transient_sec > 0 && false !== ($data = get_transient($transient_name))){
				$this->stream = $data;
				
				return $this->stream;
			}
			else
				delete_transient($transient_name);
			
				//Getting instragram images
				$instagram = new Instagram();
				$medias = $instagram->getMedias($search_user_id, $count);
				
				
				if($medias != null){
					$rsp = json_decode(json_encode($medias));
				}else{
					//Fallback function 12 photos
					$rsp = json_decode(json_encode($this->getFallbackImages($search_user_id)));
				}

				

				if(isset($rsp->edge_owner_to_timeline_media))
					$count = $this->instagram_output_array($rsp->edge_owner_to_timeline_media->edges, $count, $search_user_id, $orig_image);
						
					if(!empty($this->stream)){
						set_transient($transient_name, $this->stream, $this->transient_sec);
						return $this->stream;
					}else{
						_e('Instagram reports: Please check the settings','revslider');
						return false;
					}
		}else{
			_e('Instagram reports: Please check the settings','revslider');
			return false;
		}

	}
	
	function input($name, $default = null){
		return isset($_REQUEST[$name]) ? $_REQUEST[$name] : $default;
	}
	
	public function http_request($url, $post = '', $cookies = '', $headers = '', $show_header = true){
		$ch = @curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_HEADER, $show_header);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		if ($post) {
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
		}
		if ($cookies) {
			curl_setopt($ch, CURLOPT_COOKIE, $cookies);
		}
		if ($headers) {
			curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		}
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($ch, CURLOPT_TIMEOUT, 30);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
		$page = curl_exec($ch);
		curl_close($ch);
		return $page;
	}



	/**
	 * Get Instagram Tags Pictures CSV list
	 *
	 * @since    3.0
	 * @param    string    $user_id 	Instagram User id (not name)
	 */
	public function get_tags_photos($search_user_id, $count, $orig_image){
		$search_user_array = explode(',', $search_user_id);
		if(is_array($search_user_array)){
			foreach($search_user_array as $search_user){
				$this->get_tag_photos(trim($search_user), $count, $orig_image);
			}
		}
		else{
			$this->get_tag_photos(trim($search_user_id), $count, $orig_image);
		}
		return $this->stream;
	}

	/**
	 * Get Instagram Tag Pictures
	 *
	 * @since    3.0
	 * @param    string    $user_id 	Instagram User id (not name)
	 */
	public function get_tag_photos($search_user_id,$count,$orig_image){
		if(!empty($search_user_id)){

			$search_user_id = str_replace("#", "", $search_user_id);

			$url = 'https://www.instagram.com/explore/tags/'.$search_user_id.'/?__a=1';

			$transient_name = 'revslider_'. md5($url."count=".$count);
			
			if($this->transient_sec > 0 && false !== ($data = get_transient( $transient_name))){
				$this->stream = $data;
				return $this->stream;
			}
			else
				delete_transient( $transient_name );
				
				$rsp = json_decode(wp_remote_fopen($url));

				$count = $this->instagram_output_array($rsp->graphql->hashtag->edge_hashtag_to_media->edges,$count,$search_user_id,$orig_image);

				if(!$rsp->graphql->hashtag->edge_hashtag_to_media->count){
					_e('Instagram reports: Please check the settings','revslider');
					return false;
				}

				while($count){
					$url = 'https://www.instagram.com/explore/tags/'.$search_user_id.'/?__a=1&max_id='.$rsp->graphql->hashtag->edge_hashtag_to_media->page_info->end_cursor;
					$rsp = json_decode(wp_remote_fopen($url));
					$count = $this->instagram_output_array($rsp->tag->media->nodes,$count,$search_user_id,$orig_image);
				}

				if(!empty($this->stream)){
					set_transient( $transient_name, $this->stream, $this->transient_sec );
					return $this->stream;
				}else{
					_e('Instagram reports: Please check the settings','revslider');
					return false;
				}
		}else{
			_e('Instagram reports: Please check the settings','revslider');
			return false;
		}

	}

	/**
	 * Get Instagram Locations Pictures CSV list
	 *
	 * @since    3.0
	 * @param    string    $user_id 	Instagram User id (not name)
	 */
	public function get_places_photos($search_user_id,$count,$orig_image){
		$search_user_array = explode(",", $search_user_id);
		if(is_array($search_user_array)){
			foreach($search_user_array as $search_user){
				$this->get_place_photos(trim($search_user),$count,$orig_image);
			}
		}
		else {
			$this->get_place_photos(trim($search_user_id),$count,$orig_image);
		}
		return $this->stream;
	}

	/**
	 * Get Instagram Location Pictures
	 *
	 * @since    3.0
	 * @param    string    $user_id 	Instagram User id (not name)
	 */
	public function get_place_photos($search_user_id,$count,$orig_image){
		if(!empty($search_user_id)){

			$url = 'https://www.instagram.com/explore/locations/'.$search_user_id.'/?__a=1';

			$transient_name = 'revslider_'. md5($url."count=".$count);
			if ($this->transient_sec > 0 && false !== ($data = get_transient( $transient_name))){
				$this->stream = $data;
				return $this->stream;
			}
			else
				delete_transient( $transient_name );
					
				$rsp = json_decode(wp_remote_fopen($url));

				$count = $this->instagram_output_array($rsp->graphql->location->edge_location_to_media->edges,$count,$search_user_id,$orig_image);

				if(!$rsp->graphql->location->edge_location_to_media->count){
					_e('Instagram reports: Please check the settings','revslider');
					return false;
				}
				
				while($count){
					$url = 'https://www.instagram.com/explore/locations/'.$search_user_id.'/?__a=1&max_id='.$rsp->graphql->location->edge_location_to_media->page_info->end_cursor;
					$rsp = json_decode(wp_remote_fopen($url));
					$count = $this->instagram_output_array($rsp->graphql->location->edge_location_to_media->edges,$count,$search_user_id,$orig_image);
				}
					
				if(!empty($this->stream)){
					set_transient( $transient_name, $this->stream, $this->transient_sec );
					return $this->stream;
				}
				else {
					_e('Instagram reports: Please check the settings','revslider');
					return false;
				}
		}
		else {
			_e('Instagram reports: Please check the settings','revslider');
			return false;
		}

	}


	/**
	 * Prepare output array $stream
	 *
	 * @since    3.0
	 * @param    string    $photos 	Instagram Output Data
	 */
	private function instagram_output_array($photos,$count,$search_user_id,$orig_image=""){
		$this->stream = $photos;

		foreach ($photos as $photo) {
			if($count > 0){
				$count--;
				$this->stream[] = $photo;
			}
		}

		return $count;
	}

	/**
	 * Prepare output array $stream
	 *
	 * @since    3.0
	 * @param    string    $photos 	Instagram Output Data
	 */
	private function instagram_output_array_places($photos,$count,$search_user_id,$orig_image=""){
		foreach ($photos as $photo) {
			if($count > 0){
				$count--;
				$stream = array();

				if($orig_image){
					$url = 'https://www.instagram.com/p/'.$photo->code.'/?__a=1';
					$rsp = json_decode(wp_remote_fopen($url));
					$images = end($rsp->graphql->shortcode_media->display_resources);
					$orig_image = array( $images->src, $images->config_width, $images->config_height );
				}
				else {
					$orig_image = array('',0,0);
				}

				$thumbnail_resources = $photo->thumbnail_resources;

				$image_url = array(
						'Low Resolution' => array(
							$thumbnail_resources[2]->src,
							320,
							320
						),
						'Thumbnail' => array(
							$thumbnail_resources[0]->src,
							150,
							150
						),
						'Standard Resolution' => array(
							$photo->thumbnail_src,
							640,
							640
						),
						'Original Resolution' => $orig_image
				);

				$text = empty($photo->caption) ? '' : $photo->caption;

				$stream['id'] = $photo->id;
				$stream['custom-image-url'] = $image_url; //image for entry

				if($photo->is_video != "true"){
					$stream['custom-type'] = 'image'; //image, vimeo, youtube, soundcloud, html
				}
				else{
					$url = 'https://www.instagram.com/p/'.$photo->code.'/?__a=1';
					$rsp = json_decode(wp_remote_fopen($url));
					$stream['custom-type'] = 'html5'; //image, vimeo, youtube, soundcloud, html
					$stream['custom-html5-mp4'] = $rsp->graphql->shortcode_media->video_url;
				}

				$stream['post-link'] = 'https://www.instagram.com/p/' . $photo->code;
				$url = '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i';
				$text = preg_replace($url, '<a href="$0" target="_blank" title="$0">$0</a>', $text);
				$stream['title'] = $text;
				$stream['content'] = $text;
				$stream['date'] = date_i18n( get_option( 'date_format' ), ( $photo->date ) ) ;
				$stream['date_modified'] = date_i18n( get_option( 'date_format' ), ( $photo->date ) ) ;
				$stream['author_name'] = $search_user_id;

				if(isset($photo->tags))	$stream['tags'] = implode(',', $photo->tags);

				$stream['likes'] = $photo->likes->count;
				$stream['likes_short'] = Essential_Grid_Base::thousandsViewFormat($photo->likes->count);
				$stream['num_comments'] = $photo->comments->count;


				$this->stream[] = $stream;
			}
		}
		return $count;
	}

	/**
	 * Fallback method to get 12 latest photos
	 * @param String $search_user_id (name of instagram user)
	 */
	private function getFallbackImages($search_user_id) {
		//FALLBACK 12 ELEMENTS
		$page_res = $this->client_request('get', '/' . $search_user_id . '/');
		switch ($page_res['http_code']) {
			default:
			break;
			case 404:
			break;
			case 200:
				$page_data_matches = array();
		
				if(!preg_match('#window\._sharedData\s*=\s*(.*?)\s*;\s*</script>#', $page_res['body'], $page_data_matches)){
					_e('Instagram reports: Parse script error','revslider');
				}else{
					$page_data = json_decode($page_data_matches[1], true);
		
					if (!$page_data || empty($page_data['entry_data']['ProfilePage'][0]['graphql']['user'])) {
						_e('Instagram reports: Content did not match expected','revslider');
					}else{
						$user_data = $page_data['entry_data']['ProfilePage'][0]['graphql']['user'];
		
						if($user_data['is_private']){
							_e('Instagram reports: Content is private','revslider');
						}
					}
				}
			break;
		}
		$user_data = $page_data['entry_data']['ProfilePage'][0]['graphql']['user'];
		return $user_data;
	}
	
	/**
	 * Cliente request to get 12 instagram photos fallback
	 * @param unknown $type
	 * @param unknown $url
	 * @param unknown $options
	 * @return number[]|string[]|NULL|number[]|string[]|number[]|unknown[]|string[]|number[]|unknown[]|unknown[][]|string[][]|number[][]|NULL[][]
	 */
	private function client_request($type, $url, $options = null) {

		$this->index('client', array(
			'base_url' => 'https://www.instagram.com/',
			'cookie_jar' => array(),
			'headers' => array(
				// 'Accept-Encoding' => supports_gz () ? 'gzip' : null,
				'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36',
				'Origin' => 'https://www.instagram.com',
				'Referer' => 'https://www.instagram.com',
				'Connection' => 'close'
			)
		));
		$client = $this->index('client');
		$type = strtoupper($type);
		$options = is_array($options) ? $options : array();

		$url = (!empty($client['base_url']) ? rtrim($client['base_url'], '/') : '') . $url;
		$url_info = parse_url($url);

		$scheme = !empty($url_info['scheme']) ? $url_info['scheme'] : '';
		$host = !empty($url_info['host']) ? $url_info['host'] : '';
		$port = !empty($url_info['port']) ? $url_info['port'] : '';
		$path = !empty($url_info['path']) ? $url_info['path'] : '';
		$query_str = !empty($url_info['query']) ? $url_info['query'] : '';

		if (!empty($options['query'])) {
			$query_str = http_build_query($options['query']);
		}

		$headers = !empty($client['headers']) ? $client['headers'] : array();

		if (!empty($options['headers'])) {
			$headers = $this->array_merge_assoc($headers, $options['headers']);
		}

		$headers['Host'] = $host;

		$client_cookies = $this->client_get_cookies_list($host);
		$cookies = $client_cookies;

		if (!empty($options['cookies'])) {
			$cookies = $this->array_merge_assoc($cookies, $options['cookies']);
		}

		if ($cookies) {
			$request_cookies_raw = array();

			foreach ($cookies as $cookie_name => $cookie_value) {
				$request_cookies_raw[] = $cookie_name . '=' . $cookie_value;
			}
			unset($cookie_name, $cookie_data);

			$headers['Cookie'] = implode('; ', $request_cookies_raw);
		}

		if ($type === 'POST' && !empty($options['data'])) {
			$data_str = http_build_query($options['data']);
			$headers['Content-Type'] = 'application/x-www-form-urlencoded';
			$headers['Content-Length'] = strlen($data_str);

		} else {
			$data_str = '';
		}

		$headers_raw_list = array();

		foreach ($headers as $header_key => $header_value) {
			$headers_raw_list[] = $header_key . ': ' . $header_value;
		}
		unset($header_key, $header_value);

		$transport_error = null;
		$curl_support = function_exists('curl_init');
		$sockets_support = function_exists('fsockopen');

		if (!$curl_support && !$sockets_support) {
			log_error('Curl and sockets are not supported on this server');

			return array(
				'status' => 0,
				'transport_error' => 'php on web-server does not support curl and sockets'
			);
		}

		if ($curl_support) {


			$curl = curl_init();
			$curl_options = array(
				CURLOPT_RETURNTRANSFER => true,
				CURLOPT_HEADER => true,
				CURLOPT_URL => $scheme . '://' . $host . $path . (!empty($query_str) ? '?' . $query_str : ''),
				CURLOPT_HTTPHEADER => $headers_raw_list,
				CURLOPT_SSL_VERIFYPEER => false,
				CURLOPT_CONNECTTIMEOUT => 15,
				CURLOPT_TIMEOUT => 60,
			);
			if ($type === 'POST') {
				$curl_options[CURLOPT_POST] = true;
				$curl_options[CURLOPT_POSTFIELDS] = $data_str;
			}

			curl_setopt_array($curl, $curl_options);

			$response_str = curl_exec($curl);
			$curl_info = curl_getinfo($curl);
			$curl_error = curl_error($curl);

			curl_close($curl);


			if ($curl_info['http_code'] === 0) {
				log_error('An error occurred while loading data. curl_error: ' . $curl_error);

				$transport_error = array('status' => 0, 'transport_error' => 'curl');

				if (!$sockets_support) {
					return $transport_error;
				}

			}
		}

		if (!$curl_support || $transport_error) {
			log_error('Trying to load data using sockets');

			$headers_str = implode("\r\n", $headers_raw_list);

			$out = sprintf("%s %s HTTP/1.1\r\n%s\r\n\r\n%s", $type, $path . (!empty($query_str) ? '?' . $query_str : ''), $headers_str, $data_str);

			if ($scheme === 'https') {
				$scheme = 'ssl';
				$port = !empty($port) ? $port : 443;
			}

			$scheme = !empty($scheme) ? $scheme . '://' : '';
			$port = !empty($port) ? $port : 80;

			$sock = @fsockopen($scheme . $host, $port, $err_num, $err_str, 15);

			if (!$sock) {
				log_error('An error occurred while loading data error_number: ' . $err_num . ', error_number: ' . $err_str);

				return array(
					'status' => 0,
					'error_number' => $err_num,
					'error_message' => $err_str,
					'transport_error' => $transport_error ? 'curl and sockets' : 'sockets'
				);
			}

			fwrite($sock, $out);

			$response_str = '';

			while ($line = fgets($sock, 128)) {
				$response_str .= $line;
			}

			fclose($sock);
		}


		@list ($response_headers_str, $response_body_encoded, $alt_body_encoded) = explode("\r\n\r\n", $response_str);

		if ($alt_body_encoded) {
			$response_headers_str = $response_body_encoded;
			$response_body_encoded = $alt_body_encoded;
		}


		$response_body = $response_body_encoded;
		$response_headers_raw_list = explode("\r\n", $response_headers_str);
		$response_http = array_shift($response_headers_raw_list);

		preg_match('#^([^\s]+)\s(\d+)\s([^$]+)$#', $response_http, $response_http_matches);
		array_shift($response_http_matches);
		list ($response_http_protocol, $response_http_code, $response_http_message) = $response_http_matches;

		$response_headers = array();
		$response_cookies = array();
		foreach ($response_headers_raw_list as $header_row) {
			list ($header_key, $header_value) = explode(': ', $header_row, 2);

			if (strtolower($header_key) === 'set-cookie') {
				$cookie_params = explode('; ', $header_value);

				if (empty($cookie_params[0])) {
					continue;
				}

				list ($cookie_name, $cookie_value) = explode('=', $cookie_params[0]);
				$response_cookies[$cookie_name] = $cookie_value;

			} else {
				$response_headers[$header_key] = $header_value;
			}
		}
		unset($header_row, $header_key, $header_value, $cookie_name, $cookie_value);

		if ($response_cookies) {
			$response_cookies['ig_or'] = 'landscape-primary';
			$response_cookies['ig_pr'] = '1';
			$response_cookies['ig_vh'] = rand(500, 1000);
			$response_cookies['ig_vw'] = rand(1100, 2000);

			$client['cookie_jar'][$host] = $this->array_merge_assoc($client_cookies, $response_cookies);
			$this->index('client', $client);
		}
		return array(
			'status' => 1,
			'http_protocol' => $response_http_protocol,
			'http_code' => $response_http_code,
			'http_message' => $response_http_message,
			'headers' => $response_headers,
			'cookies' => $response_cookies,
			'body' => $response_body
		);
	}
	/**
	 * Helper function for fallback photos function
	 * @param unknown $domain
	 * @return unknown
	 */
	private function client_get_cookies_list($domain) {
		$client = $this->index('client');
		$cookie_jar = $client['cookie_jar'];

		return !empty($cookie_jar[$domain]) ? $cookie_jar[$domain] : array();
	}
	/**
	 * Helper function for fallback photos function
	 * @param unknown $key
	 * @param unknown $value
	 * @param string $f
	 * @return NULL|string
	 */
	private function index($key, $value = null, $f = false) {
		static $index = array();

		if ($value || $f) {
			$index[$key] = $value;
		}

		return !empty($index[$key]) ? $index[$key] : null;
	}
	/**
	 * Helper function for fallback photos function
	 * @return NULL
	 */
	private function array_merge_assoc() {
		$mixed = null;
		$arrays = func_get_args();
	
		foreach ($arrays as $k => $arr) {
			if ($k === 0) {
				$mixed = $arr;
				continue;
			}
	
			$mixed = array_combine(
				array_merge(array_keys($mixed), array_keys($arr)),
				array_merge(array_values($mixed), array_values($arr))
			);
		}
	
		return $mixed;
	}
	
}	// End Class

/**
 * Flickr
 *
 * with help of the API this class delivers all kind of Images from flickr
 *
 * @package    socialstreams
 * @subpackage socialstreams/flickr
 * @author     ThemePunch <info@themepunch.com>
 */

class RevSliderFlickr extends RevSliderFunctions {

	/**
	 * API key
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $api_key    flickr API key
	 */
	private $api_key;

	/**
	 * API params
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      array    $api_param_defaults    Basic params to call with API
	 */
	private $api_param_defaults;

	/**
	 * Stream Array
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      array    $stream    Stream Data Array
	 */
	private $stream;

	/**
	 * Basic URL
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $url    Url to fetch user from
	 */
	private $flickr_url;

	/**
	* Transient seconds
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      number    $transient Transient time in seconds
	*/
	private $transient_sec;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 * @param      string    $api_key	flickr API key.
	 */
	public function __construct($api_key, $transient_sec = 1200){
		$this->api_key = $api_key;
		$this->api_param_defaults = array(
			'api_key' => $this->api_key,
			'format' => 'json',
			'nojsoncallback' => 1,
		);

		$this->transient_sec = $transient_sec;
	}

	/**
	 * Calls Flicker API with set of params, returns json
	 *
	 * @since    1.0.0
	 * @param    array    $params 	Parameter build for API request
	 */
	private function call_flickr_api($params){
		//build url
		$encoded_params = array();
		foreach($params as $k => $v){
			$encoded_params[] = urlencode($k).'='.urlencode($v);
		}

		//call the API and decode the response
		$url = 'https://api.flickr.com/services/rest/?'.implode('&', $encoded_params);
		$transient_name = 'revslider_' . md5($url);

		if($this->transient_sec > 0 && false !== ($data = get_transient($transient_name)))
			return ($data);

		$rsp = json_decode(file_get_contents($url));
		if(isset($rsp)){
			set_transient($transient_name, $rsp, $this->transient_sec);
			return $rsp;
		}else{
			return '';
		}
	}

	/**
	 * Get User ID from its URL
	 *
	 * @since    1.0.0
	 * @param    string    $user_url URL of the Gallery
	 */
	public function get_user_from_url($user_url){
		//gallery params
		$user_params = $this->api_param_defaults + array(
			'method'  => 'flickr.urls.lookupUser',
			'url' => $user_url,
		);
		
		//set User Url
		$this->flickr_url = $user_url;

		//get gallery info
		$user_info = $this->call_flickr_api($user_params);
		
		return $this->get_val($user_info, array('user', 'id'), '');
	}

	/**
	 * Get Group ID from its URL
	 *
	 * @since    1.0.0
	 * @param    string    $group_url URL of the Gallery
	*/
	public function get_group_from_url($group_url){
		//gallery params
		$group_params = $this->api_param_defaults + array(
			'method'  => 'flickr.urls.lookupGroup',
			'url' => $group_url,
		);
		
		//set User Url
		$this->flickr_url = $group_url;

		//get gallery info
		$group_info = $this->call_flickr_api($group_params);
		
		return $this->get_val($group_info, array('group', 'id'), '');
	}

	/**
	 * Get Public Photos
	 *
	 * @since    1.0.0
	 * @param    string    $user_id 	flicker User id (not name)
	 * @param    int       $item_count 	number of photos to pull
	 */
	public function get_public_photos($user_id, $item_count = 10){
		//public photos params
		$public_photo_params = $this->api_param_defaults + array(
			'method'  => 'flickr.people.getPublicPhotos',
			'user_id' => $user_id,
			'extras'  => 'description, license, date_upload, date_taken, owner_name, icon_server, original_format, last_update, geo, tags, machine_tags, o_dims, views, media, path_alias, url_sq, url_t, url_s, url_q, url_m, url_n, url_z, url_c, url_l, url_o',
			'per_page'=> $item_count,
			'page' => 1
		);
		
		//get photo list
		$public_photos_list = $this->call_flickr_api($public_photo_params);
		
		return $this->get_val($public_photos_list, array('photos', 'photo'), '');
	}

	/**
	 * Get Photosets List from User
	 *
	 * @since    1.0.0
	 * @param    string    $user_id 	flicker User id (not name)
	 * @param    int       $item_count 	number of photos to pull
	*/
	public function get_photo_sets($user_id, $item_count = 10, $current_photoset){
		//photoset params
		$photo_set_params = $this->api_param_defaults + array(
			'method'  => 'flickr.photosets.getList',
			'user_id' => $user_id,
			'per_page'=> $item_count,
			'page'    => 1
		);
		
		//get photoset list
		$photo_sets_list = $this->call_flickr_api($photo_set_params);
		
		$return = array();
		foreach($photo_sets_list->photosets->photoset as $photo_set){
			if(empty($photo_set->title->_content)) $photo_set->title->_content = "";
			if(empty($photo_set->photos))  $photo_set->photos = 0;
			$return[] = '<option title="'.$photo_set->description->_content.'" '.selected($photo_set->id , $current_photoset , false).' value="'.$photo_set->id.'">'.$photo_set->title->_content.' ('.$photo_set->photos.' photos)</option>"';
		}
		return $return;
	}

	/**
	 * Get Photoset Photos
	 *
	 * @since    1.0.0
	 * @param    string    $photo_set_id 	Photoset ID
	 * @param    int       $item_count 	number of photos to pull
	 */
	public function get_photo_set_photos($photo_set_id,$item_count=10){
		//photoset photos params
		$this->stream = array();
		$photo_set_params = $this->api_param_defaults + array(
			'method'  		=> 'flickr.photosets.getPhotos',
			'photoset_id' 	=> $photo_set_id,
			'per_page'		=> $item_count,
			'page'    		=> 1,
			'extras'		=> 'license, date_upload, date_taken, owner_name, icon_server, original_format, last_update, geo, tags, machine_tags, o_dims, views, media, path_alias, url_sq, url_t, url_s, url_q, url_m, url_n, url_z, url_c, url_l, url_o'
		);
		
		//get photo list
		$photo_set_photos = $this->call_flickr_api($photo_set_params);
		
		return $this->get_val($photo_set_photos, array('photoset', 'photo'), '');
	}

	/**
	 * Get Groop Pool Photos
	 *
	 * @since    1.0.0
	 * @param    string    $group_id 	Photoset ID
	 * @param    int       $item_count 	number of photos to pull
	 */
	public function get_group_photos($group_id,$item_count=10){
		//photoset photos params
		$group_pool_params = $this->api_param_defaults + array(
			'method'  		=> 'flickr.groups.pools.getPhotos',
			'group_id' 	=> $group_id,
			'per_page'		=> $item_count,
			'page'    		=> 1,
			'extras'		=> 'license, date_upload, date_taken, owner_name, icon_server, original_format, last_update, geo, tags, machine_tags, o_dims, views, media, path_alias, url_sq, url_t, url_s, url_q, url_m, url_n, url_z, url_c, url_l, url_o'
		);
		
		//get photo list
		$group_pool_photos = $this->call_flickr_api($group_pool_params);
		
		return $this->get_val($group_pool_photos, array('photos', 'photo'), '');
	}

	/**
	 * Get Gallery ID from its URL
	 *
	 * @since    1.0.0
	 * @param    string    $gallery_url URL of the Gallery
	 * @param    int       $item_count 	number of photos to pull
	 */
	public function get_gallery_from_url($gallery_url){
		//gallery params
		$gallery_params = $this->api_param_defaults + array(
			'method'  => 'flickr.urls.lookupGallery',
			'url' => $gallery_url,
		);
		
		//get gallery info
		$gallery_info = $this->call_flickr_api($gallery_params);
		
		return $this->get_val($gallery_info, array('gallery', 'id'), '');
	}

	/**
	 * Get Gallery Photos
	 *
	 * @since    1.0.0
	 * @param    string    $gallery_id 	flicker Gallery id (not name)
	 * @param    int       $item_count 	number of photos to pull
	 */
	public function get_gallery_photos($gallery_id,$item_count=10){
		//gallery photos params
		$gallery_photo_params = $this->api_param_defaults + array(
			'method'  => 'flickr.galleries.getPhotos',
			'gallery_id' => $gallery_id,
			'extras'  => 'description, license, date_upload, date_taken, owner_name, icon_server, original_format, last_update, geo, tags, machine_tags, o_dims, views, media, path_alias, url_sq, url_t, url_s, url_q, url_m, url_n, url_z, url_c, url_l, url_o',
			'per_page'=> $item_count,
			'page' => 1
		);
		
		//get photo list
		$gallery_photos_list = $this->call_flickr_api($gallery_photo_params);
		
		return $this->get_val($gallery_photos_list, array('photos', 'photo'), '');
	}
}	// End Class


/**
 * Youtube
 *
 * with help of the API this class delivers all kind of Images/Videos from youtube
 *
 * @package    socialstreams
 * @subpackage socialstreams/youtube
 * @author     ThemePunch <info@themepunch.com>
 */

class RevSliderYoutube extends RevSliderFunctions {

	/**
	 * API key
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $api_key    Youtube API key
	 */
	private $api_key;

	/**
	 * Channel ID
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $channel_id    Youtube Channel ID
	 */
	private $channel_id;

	/**
	 * Stream Array
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      array    $stream    Stream Data Array
	 */
	private $stream;

	/**
	* Transient seconds
	*
	* @since    1.0.0
	* @access   private
	* @var      number    $transient Transient time in seconds
	*/
	private $transient_sec;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 * @param      string    $api_key	Youtube API key.
	 */
	public function __construct($api_key, $channel_id, $transient_sec = 1200){
		$this->api_key = $api_key;
		$this->channel_id = $channel_id;
		$this->transient_sec = $transient_sec;
	}


	/**
	 * Get Youtube Playlists
	 *
	 * @since    1.0.0
	 */
	public function get_playlists(){
		//call the API and decode the response
		$url = "https://www.googleapis.com/youtube/v3/playlists?part=snippet&maxResults=50&channelId=".$this->channel_id."&key=".$this->api_key;
		$rsp = json_decode(wp_remote_fopen($url));
		
		return $this->get_val($rsp, 'items', false);
	}

	/**
	 * Get Youtube Playlist Items
	 *
	 * @since    1.0.0
	 * @param    string    $playlist_id 	Youtube Playlist ID
	 * @param    integer    $count 	Max videos count
	 */
	public function show_playlist_videos($playlist_id, $count = 50){
		//call the API and decode the response
		if(empty($count)) $count = 50;
	
		$url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=".$playlist_id."&maxResults=".$count."&fields=items%2Fsnippet&key=".$this->api_key;
		
		$transient_name = 'revslider_' . md5($url);

		if($this->transient_sec > 0 && false !== ($data = get_transient($transient_name)))
			return($data);

		$rsp = json_decode(wp_remote_fopen($url));
		
		if(!isset($rsp->items)) return array();
		
		set_transient($transient_name, $rsp->items, $this->transient_sec);
		
		return $rsp->items;
	}

	/**
	 * Get Youtube Channel Items
	 *
	 * @since    1.0.0
	 * @param    integer    $count 	Max videos count
	 */
	public function show_channel_videos($count = 50){
		if(empty($count)) $count = 50;
		//call the API and decode the response
		$url = 'https://www.googleapis.com/youtube/v3/search?part=snippet&channelId='.$this->channel_id.'&maxResults='.$count.'&key='.$this->api_key.'&order=date';
		
		$transient_name = 'revslider_' . md5($url);
		if($this->transient_sec > 0 && false !== ($data = get_transient($transient_name)))
			return ($data);

		$rsp = json_decode(wp_remote_fopen($url));
		
		if(!isset($rsp->items)) return array();
		
		set_transient($transient_name, $rsp->items, $this->transient_sec);
		
		return $rsp->items;
	}

	/**
	 * Get Playlists from Channel as Options for Selectbox
	 *
	 * @since    1.0.0
	 */
	public function get_playlist_options($current_playlist){
		$return = array();
		$playlists = $this->get_playlists();
		if(!empty($playlists)){
			foreach($playlists as $playlist){
				$return[] = '<option title="'.$playlist->snippet->description.'" '.selected($playlist->id , $current_playlist , false).' value="'.$playlist->id.'">'.$playlist->snippet->title.'</option>"';
			}
		}
		return $return;
	}
}	// End Class

/**
 * Vimeo
 *
 * with help of the API this class delivers all kind of Images/Videos from Vimeo
 *
 * @package    socialstreams
 * @subpackage socialstreams/vimeo
 * @author     ThemePunch <info@themepunch.com>
 */

class RevSliderVimeo extends RevSliderFunctions {
	/**
	 * Stream Array
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      array    $stream    Stream Data Array
	 */
	private $stream;

	/**
	* Transient seconds
	*
	* @since    1.0.0
	* @access   private
	* @var      number    $transient Transient time in seconds
	*/
	private $transient_sec;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 * @param      string    $api_key	Youtube API key.
	 */
	public function __construct($transient_sec = 1200){
		$this->transient_sec = $transient_sec;
	}

	/**
	 * Get Vimeo User Videos
	 *
	 * @since    1.0.0
	 */
	public function get_vimeo_videos($type, $value){
		//call the API and decode the response
		$url = 'https://vimeo.com/api/v2/';
		$url .= ($type == 'user') ? $value.'/videos.json' : $type.'/'.$value.'/videos.json';
		
		$transient_name = 'revslider_' . md5($url);
		
		if($this->transient_sec > 0 && false !== ($data = get_transient($transient_name)))
			return ($data);

		$rsp = json_decode(wp_remote_fopen($url));
		set_transient($transient_name, $rsp, $this->transient_sec);
		
		return $rsp;
	}
}	// End Class
?>