From 926ecb2cb7f38e3aa44b248437ded500890ccde5 Mon Sep 17 00:00:00 2001 From: Nitish Khagwal Date: Fri, 22 Feb 2019 20:34:35 +0530 Subject: [PATCH] Sketch App 53 Support --- README.md | 2 +- appcast.xml | 4 +++ ... => 3ff137287832113452bf2ab1649999f2.html} | 2 +- .../aa5bcfacdda6e5b5e7a75cf12bfe0448.html | 33 ++++++++++++++++++ .../Contents/Resources/icon-transparent.png | Bin 8684 -> 0 bytes .../Contents/Sketch/coolhue.js | 6 ++-- .../Contents/Sketch/coolhue.js.map | 2 +- .../Contents/Sketch/manifest.json | 6 ++-- 8 files changed, 46 insertions(+), 9 deletions(-) rename distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/{f26f00243c3832631637c6f76c717088.html => 3ff137287832113452bf2ab1649999f2.html} (93%) create mode 100644 distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/aa5bcfacdda6e5b5e7a75cf12bfe0448.html delete mode 100644 distro/CoolHue.sketchplugin/Contents/Resources/icon-transparent.png diff --git a/README.md b/README.md index 84bc900..a730154 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ CoolHue is also available as a node module. You can read [How it works](https:// `npm install --save-dev coolhue` ## Sketch App Plugin -1. Download [`Coolhue.sketchplugin.zip`](https://github.com/webkul/coolhue/releases/download/v2.0.6/CoolHue.sketchplugin.zip) +1. Download [`Coolhue.sketchplugin.zip`](https://github.com/webkul/coolhue/releases/download/v2.0.7/CoolHue.sketchplugin.zip) 2. Extract the archive 3. Install `Coolhue.sketchplugin` for Sketch App 4. Access it from Sketch's Menu Bar. Go to `Plugins` ➡️ `Coolhue` ➡️ `Palette` diff --git a/appcast.xml b/appcast.xml index 77824f1..9bab720 100644 --- a/appcast.xml +++ b/appcast.xml @@ -21,5 +21,9 @@ Version 2.0.6 + + Version 2.0.7 + + \ No newline at end of file diff --git a/distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/f26f00243c3832631637c6f76c717088.html b/distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/3ff137287832113452bf2ab1649999f2.html similarity index 93% rename from distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/f26f00243c3832631637c6f76c717088.html rename to distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/3ff137287832113452bf2ab1649999f2.html index 9357d81..595c168 100644 --- a/distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/f26f00243c3832631637c6f76c717088.html +++ b/distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/3ff137287832113452bf2ab1649999f2.html @@ -19,7 +19,7 @@
-

CoolHue v2.0.5

+

CoolHue v2.0.7

diff --git a/distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/aa5bcfacdda6e5b5e7a75cf12bfe0448.html b/distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/aa5bcfacdda6e5b5e7a75cf12bfe0448.html new file mode 100644 index 0000000..6cadea6 --- /dev/null +++ b/distro/CoolHue.sketchplugin/Contents/Resources/_webpack_resources/aa5bcfacdda6e5b5e7a75cf12bfe0448.html @@ -0,0 +1,33 @@ + + + + + + + + View + + + + + + +
+ + + +
+
+
+

CoolHue v2.0.7

+
+
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/distro/CoolHue.sketchplugin/Contents/Resources/icon-transparent.png b/distro/CoolHue.sketchplugin/Contents/Resources/icon-transparent.png deleted file mode 100644 index d286a7f6588ca46e235277ca2e5e260b0e625eaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8684 zcmaKSWmFv7wsj-H-JuB{9J+CLw?J@*1{!y50)!@baF?LLJwTA)gh0@sL4ySg?hQdd z&b{Z{@BO&%)fiQK?^SEAHJAOVQPEm2m2k1BumAu6u8Oj}_S35M*NuVp^o%Dwt9e=| zy%h|-b=+*d{UDxDfQ*fs6_ifJ1!4!)hC*!oJ%*s-004@+gRY^sp@zDswVMk!N zPSzqe3{sMG;xN%C11?Z+2p!DD+0{!FCc*G8yP{9~zr-L0x__y7J4rD7o0Or37M+}% zCzMWrTae3|hhKnBNQ9e5kdI$Pgp-aJ%p(i}3xjz0xOfCb`N5*RymWtG3{T!XZEQug zmV8u=nq&#l%iq--0^@S^V*JN~ zJk-nD)4|=_!OfNKFN+W>Hy>{ah9{=~4#CA;L*qY&UA_KJ)KkhpFo-*dhZ_uXarrB* ze`$MpYeWA(jsL3crR(nw1!+UQ+KD05iTn$0VtOc#72aN-^N-T;! zo&SdCDDd)v`4waog#{G;!K%1=c|%;Sq5t@Hc=G)> zR`CDCipqIHA>MADx^8aH|8#+ty_>h2m%W=iot)gis!qqM0kL*){Y%L9SE2qLw>;F- z!53q^7G2b2=OcM$;ivf3&;sD{EfBw zFWLJWEA+o&K~H2rf3?Z~Xq$gTPrdlp_CG`LbokF0L0z9_$Mb1OI>ff$001;ZD)KVA zu*CyY%uF-ApvQc#qfWP6p5EtjUsX$Pj7(~7^i-V` zI0#5}EA>oxNQ_A^(#G%!z*NMe3}Ku$?}wNgyR!V3%w9e|dL7-^CTB5mP9+Taov*YX zuiSpWUw%Bh1?_;@UUZ!L-38y_Vypm8Z~+$M!2?d0eQC*IQ&A+#w?9eIeFNOS%=LGg zt$diIcUvF)IA_czv*J}4GD(L^@qKe%xiIN+>-}{+!XYr=oBHXO3;$oAD;lp$z2iSu z@CRrdg?47YwDC5S9e?9D+l-6of1g+0vDLrhNPck%(}?JoadE(7=!f&6%1y1EFj3P6 zZMIez1oqusp&E^lND8|}!>mp#wu`VcfREw%?F0vp769L4pJ|iXxmws>?=X6PP`P*4 zCmDJsLmQ>A9)r-3kEodN;wXezr`z1m3I6k;40B#&1^J zM`$~bzprZ^2T!^VEX@^QK9dC)+9ku5CreO-_abIQ zF2ESAS|vuP?ANPJ8XNaJ9er)Pu`R|e(6efU82;KczJbBRnnjGCb3pT=$_F~FE&C#1 zNu`Dq_>Q9o*@FD!L~1JC6ic|2W8e)G8geoqX*ETYXwzV2ER-tETERRk38vylo- zER~i)dsvI%BHBo!zrM|iWzUDIKr>A}3Vm)Bg41upvaCv0DFMOl3q}`B-IN_WLgVQf zn58e`PnFqW&!a983H`-94?(63KTbE3o@+k0ZZ7T3PM#%-z5Ugkc&>bwjIX-1l9g+< zPa7y4G?Xf0b?bypm)GWD=6{JUscZTkSSzrd^mdIaKB@WjE&s|D(gdan#Uo8!_4ktJ zwP;iJV0r-w6mc$+D9&pangDlkWY7cnY^?ga)`>TROLX~q*NG@vd8Rzn57&G*sO2g| zN29&IYP4|gLvO;Xn6DhM%e0HVr#+z**K~3LXkFHX7}=a6mdC(nM!xW}FtnH-DiX0i z{GZZd8r+W!M(~{jXC8X0Kq0W~^I2je8tx&sIX1271-z^%_!MJD=6iDhK_Z zX)#)T{R8mx{JwVtZ^h(}ezJ}C^&kRgMK~U@jf<1FtC(OQolp@P&Ep$2r^4)SpkvSP z%)h@yi2pNNUxze&f=9BOamms68V;Ts+@>@n>y3FF&O>GwkV>G-zFzo&NbSG2#pzfR zBa@K7axo}b^*dAbI^@8!oNG(c3+P(t##=SsL>&^*r$*E9dY9Kr9y|mgpPJqMQ|yIN z{tn}YyfCNfdYV+U7p)XZ?RY9xVG;Ux z8aiOddNY0w3`aW@_szJ5O?EeN8aU^CzPEPM)t%4w;kf}tLZ=k~&$WX4=Fl!+b^}*{ z{Up%~maPI%`E|jGEROZjmRL!P=jE9F3UE=RLL@t!E)GZe_u*x#akJ+7#An%_p&gTt zCmLv<)cNRE-x8%Mm?-7ok9)Bb4P#iIehljiaE5tw;)>-}$c+1vvojK%VZcnpBuTK4 zc7%}StVb(r$1y|Q6WAQ^MimJ@yRQZ?j#0MVO=t0$*qt4M#NcV>Lbva`5C4SE?Q=Gg zzOYsu!H~}2|NetWIk~kkveyh$KvI$z5ItyHG7V^A7tIfbtU5L|~n7Du$0ZWl7Q6o#TriPr;!Iy>@w3t?PM|-Gdf7IQk_WR$TH}XQOP>frjLPW^8PJ~=0gFh zW{?-EYNz0+csHSTuE8SOMAT6hS{yI;S`OO6OK}iBViWHWdzIr`Yh1yp;SpqGDvr&lOX@}=(fjaxc@UNSUkz<0Wny(^=z$481zS4D=`zL@~f-f^3@PQ6X2 zVe9#sqMoMDmH}mTfCz3WhuRQtU0qzE7F!}aLg9AZe1NOqdK{cX$cS^To)L{m9mTxt zQLvB;{c6Vz{J+w70LK_!eJh_HOyF7!O`#Bp%aQLjSRx&iPU1ml;yc`kRKj^6E$g(NfXR>BV}R{6v4YJ`kA zHi`r^m%SC&mF3?1nE0~_zD~!Vf6sS&a}Lr7TF-pp4(m=?xU0zPbe(jnYNaaXLDbTy zSLD0S=>yY06t!+P+XiOS=yDuYq0!JMzH}JzUUdu+Gj1=zKCfSx~;4xQvW0f>UFhgdki>`=Uw(ZClVSh56*Vf~HjJTkVBmB+3 zc)*h8;!uW9B5x4|EoQb~mRvbmf0Tbfj}0wzArpHiVO@we*yh4;Vu;g`UtPbxF7`ZA z)WXsx^p+_yp1F39L(0DmRq9OxP9#sI!>Cv0EPFvkh;sqjIQSD&GS`8~@8-kXnt(q% zB80$=$wyvO`XHq2cJnSFseC zrSSJ@Q%A`S(n`EbY_uJ;brrpBV$PZI$r)~nLw!6=g1i)8Z*L|Uq4ReiP{wenZ9jRH zd>8c_yt9cI=M#~@iR~mD#Z6c+SRxhi2gC#%EEI`V?fmFqGV<*d{c-7y`fEaC9iMjP z@XHwo-^aC_*oFZ1PI04?;x0nu*yhxVar&j*3M&$wDFsXIK+Y1{#A|-$v?f?v>Xb(MxLm216Hgp79I1A5OGZZdW)ZZ@#kX+f4m55xq{` z<+^I0FXpcGJuip2SLXSOZUFwNda@+un{u*7FY{P&v93M51EpbJjUJJ?%^wO;)Qv;w zc5HYWDJ1T!h=7k<4&;dLHJM=iY&g~m!6N57pR!S_34f}{KO^C7kQ>|vCpK>a8oV>f z)Qjlsnuk7f_Z90`m!d7lN&4&p7gv)X6b7`jX46-9WbW&CHuvjOI0SbXX8C> z&F$oVqgyTN7zJ^tEsvjv#pLStrjhIL#Dx%@UwiQ{>7aiMX%@G$x-Jw<_w9XSaD*#X zSXBp${1#3QMA2VgsVF$>u#sf}H0_)lt^-9iNk8tXqHJ>!@3GiFhPD{2?>J3v7cOpV zwdGK;2H5_3F8R40EfUSt-i>hYHOVd7T9zV_xVF(Vy16|yB9)c~yQ=eesGFcGkM_ZD zfd0EYp4QISG}y`w=o@FoE` zS|Hyf(Q{D^EZKl8fhS?#dEQB%p~jehrm;8)y23l|aKr>9A>Wn*5XTLgmzBIgMe@Xp z=6BeylT?WvxM`BX!A;L}L^V+-4PrX;27+}&A!$(cn z{nfptMyJB%Xxlu$k(=y9wx6&kkLI_;p?s4gs<}V#JBE0qCp9w3W{S6w)AlcHyIL(Uiu52fx%?xX2xKPiP601?0Z*3*j^G z0P5IXu1qt$qC&E_7%gV(t7 zbixVc4YW?Vo=fsnUDOj5Nu^mgR0oI2;wGvg6Dd<1S+9csO>JDyLA1kY)EslC=oIz5 z9Br$#Y_w!6h9aa?EA*mR2y&phkU$tKb>-T3o?Wy?JMe0ON3ZGQuuyy)j#`mAX@;U= z33Bus&^lO|h%3Jo)qJ)kc-@Y6REy|-+*P4j6NAoN$ikPAg-GE!PL3#z@&XP!=az~8 zM6MuYO_LV?FbzDzk~WRmi_!K;wr*qq8U2k!OYQd&D>y>d@;mcw#MRAW``M-fM>AXoOjW^lQr%bmSkOj3V1Eh*u{6noFPz{xzG>% zq%FSCOHgjr877nJnh;N^iCk0(RB5J!EqN$=0#+#AlPAc_kAAiva?S*kDY`qJGRc^_ zEHes|`^U1eX~tVz)VBCL#|qKpuY3hY&IDi&Bi=9+CTX7`Z2`c2HSCU!S&a8~6 zq+lG<7mvk0C?FIeh7#kR5aSGY#j9gj{sj50|hYAXfB2C3-9|%=x>Q=uIKZsFLPU^N1YybQ-yGsrzJ0ht zW=2bdUKd;(ngfg(lBmMGXX>ikhu2Qb4e$ezPk!50AeLggoYBzkOCXf{)Ry$&DuT52 zHgoI=LYVb7$B>DHP%&)Qt@J{+ILZyrkT3-%k@=ltyROa{k@p3`ENRw}EU4gVdOR&~ zX^&S*^Y@C4$W-NmuOq!?G@=pFy!uq8Wu+x2o7g_ShT#^HFme52-FuEVyfTDNc=gs7 zejz*C^>KgNe!}CqGE`JEw<4jA*l++rzo`dzeUCs_b?;~3YeyzE#U@opwnfGE~b zllyP6&EEJO$9JfNgmGm*ziou1BFfN;{DS9oD|usc5`WFXG0xk}CC$IxMpa^1Ty{G4 z5HsqPc}$J@@netekeEd$*;t$*pHag(0*CnS2d=|*29Bq=oX^7mzMNp8A9rn`&jCs+ z`ikHCFjvGbbcN}5BkgF)+1W~Hv(+zSd-6MVd!YIJq;R>&;>s=NHuZhM^{TdERvnY& zs3YTsk)dlN6?(h|w()|Yj4!P$cq!!`XVjtzhRHIhD@IFSoPo~S1U(Khqj9yCC3FsZ zGN}We)(9}pE~`Lzo=YF2!0#2PX5|vR$~~s`#rj1I&h^H4CVQ>qCzHyr$X~_O{kmM(g?(Vi|h2XOG0`tUQkE0`QSI5l~rJ@uo$|eixhy@b~1xP>Z8)PmQuM(WRLpG zfjrB7tcK0dyG<)7R8B(sg?fdwg~Bhb=l!@PH8c2F<+@~RU#ip%ed3-?lX)5XH(~N+ zc>Z3kD-)-P(04ey#x+9YdL}{RftpM`BNY}^towD3$wuE(XI@7!dx1E@)8VdHq^yia z_{7x5ht;2;YB-#p2HS;RgMg{sW4wjkee(8vVm`wBXIjd;m%3u_6Tw9~J^2qQ@aI6& z`9B=wc%7TQ_EJAgJ`vMR7?<*8dL+YN>|pEhC$m46AD$=(6|WW6=~_OziT}<7>3-=s zUwWI$_v*7}{_yo=^vRFusFIe{X~GbGMW2*Abp%}t^Fr3gpdcSaOP%N)kpTY!&*HDJ zEJv~tY_w%zfwICsqlL2ZUFK6w^=wm=&(*VoJD1Cmqk0+1=9eI8g0N!$w<2VDG!eb=M95EZ187%^Te$6LbKHAN9oZq zb!Y&K9(i8<;LoMDo;!c>o2YAA;PeXQwke4$bwxlZ{!2)%Al@MSv}p4b$f6e;s~NS( zRz9olvoK3(-?!~$pI?N%=`G-i*PMGWs=W>%YPs2910Fiaov&96i9e>90l0U7S8eTI9h795cUfSDC>!-XhfgXulT^_ z%u`Uc8vg!4wb5~eNGYw0$AzW~Mf>neGuki$2zH3sPTOX?zl+e1rg_}HD^?MRY|$_QZwwe7i(KKi8BXZ61E9>q=9*?zy(_y`U#!HsJr9?|-CYa?sCq4+gB z)=%kO-|C|o;q0=&Tg@N3m4rS;4F<)091FCprvoC@H-=c-dDi8&NX(42@Y5voaA7@;Wf zgT+w3Cx($?Rn3jAF)`@UJ_Rj)@t0V@X94f^7g<0jB>#x|n$F7_nh+fa$AZt!IBz_I zXb(ENqXhfm{9{OB-?wn$pNZ%GlC29Yz%uFP`(P_cnblUU2|oR%DVzA(U?K!J18_q) zn)e2sH)cVKN(1cuQ)22OwCaH=c>j}#6`w}VX-B=~kE@Xh>2fv)3iSJzo4(lD6n9JL zx9g`Md^&pOKIh6IKDzaCp7T>cb)T@A;jV=gmgedNcDtZE7+cm~hpet!nqm zyf!Oo;Cy6A?<%sskp27|XJ^U@C@FhoavJcGh|A4qN_q9FsBLr@C1>_X2CFF5R4h`d z3yk4+|3^l+wM4caYl=j!W(Mitt6qk5Q5-!((+70W8#h4S^)w1tOG9RT6DOOv!rA-- zYR|@t5SwOTiS|n=wLp2pwGL-ums!)ftEMI=j=2(?v7?+DJUxTQYiT`$<62V&h<<2T zZ{-n5L2l3>J|8ai_l`CsebY&RhF47@MatNj_}DV@hO_iCEB-zP-eOH3aQNfpKFY-H z1cA-CYsAH#uYei+LkN@Q>1N+NO-@DGySnk97}y`?#q#vkjGP0d)u8K)_NxFjuhM+y zxEF>F1kgws{Kdp8&Wp95yMUlK>0xTQ{(_T@ao%F!#SQ5tWa9KL7WA0aq{!wM%xL@K zMnD{9^aMUyrdR8IPM5CLJx2i%g*y(Zu7Os#Wt$3bcExun;kjv$ca&k_R=CBP}$_cFUt*pL%&=)m$pTU&Jd} zxF|2nUJ>7bFDG#U`y+^?V_*n&gOZhUYREyF;p$adYPqp0p@ppm=n|~7o)DV^T=d{q z5pv_{5Lio%y=s??0`6Llo3u|t`Qcc z2fx!@oN%(f8(~vY?hau$-t{V&I+T638{{(aEV@$Vl|pH#cn89K<-L}R-OfbJf}?Nw zn#u{hpDL4R!MU8PYaSLb9r!S;;fMQh)a7t;run$>JJ{B~gc;RCDXF*PZJ1NK+8{-7 z8}Fvksh-%tsPQN<_)vW-s)WwElIKm%NN%jK<~Mh@3*d7xaY#g4kRx zZw3e4f^^NQN>h@A3M^CLo((0gIiTOECZUz2If*wx4jml|e$Y7`7IOvuX&E6?EuwTW zvFIPinj`Or99R)38IPgt%}CJKhiszm6c94gZGK?ZT@rWC#@+ItT*T?9t)j;(=f)NG zGN3Z>>xh25^*A3VHbR6sFAp4(8n|6QoGcd=nakihQV*%A^GQsJ@?NgZ_|Tphc82nH zP^++wQ?dGEtfb<6tSoy0;>o?lSes-J_t($4()aK`mwo7Fkzccj5BJM^bZ|K3Tczl* zyGXnZP(r~UFcOQPb>Ydow$npbJcq}>)!&0R;|!K)^k6ZAKLvBnuDrkKu=Y3a^KSN8 zaop%!Knw*e8IVZ-FzFm0lJq$588ZX2&kdO9A^U_eijYv)<&vATl#nc0Nq^^1Hc-bQ zCL>90)cRJy)ZnrG@YbR~biNPFnRux7=g>=^Dt|3y)4z@i9-``YBjfR-IY7x3bk&}F z+N$%ho?UdHf{E(ICD6DqYT8DD;m32z6EYzrHx0Hm)J1XIuWgiXBN_SiLgrD})a^ju zg-uMCI@adxhpVtGDVoGB8k<)n?k1NL(j`NMCcauDxVk0`C(c={q*a@yfR&D8I+c|# zIq017^U*~Z%Tj7yD2+*zKNR=yFp1cn^Kv=6@3GwtAfUel8F9OBM^^hE+urCotbBI8 zxXGa5FpCtLe&x1LRO9qXkgSH%{uY6wmnM*jVN4b}U2VLm5@c}MS>0W1E}?=a`q`7~ zK}T3XvTgFsBJY&2h(i9pa=)*0=gf3deu)9U^G{M!^d3=(7YSl65> zQ<4=r7OV2w*j7RnN)?lj#VNh<6M+@V4NDDhsTE(MM^^}1JInG{^Hnu?d{*exVNVZY zF(=PLpZjRZH0aj8#Y>XUDB{%z0XINdQymqdxUq6^a7SRIDj%`!LQbnjtx+ z(q*ZaVz{bbtQ0s#Uh5dmCplOxz2dSMY-;3M&~JWKoXMpQ(|DK%I_>7quL3!;x{=m^ hfUerd2TeE {\n Object.defineProperty(self, name, {\n get() {\n return getIvar(self, name);\n },\n set(v) {\n (0, _runtime.object_setInstanceVariable)(self, name, v);\n }\n });\n self[name] = defn[name];\n });\n // If there is a passsed-in init funciton, call it now.\n if (typeof defn.init == 'function') defn.init.call(this);\n return self;\n });\n\n return cls.registerClass();\n};\n\nfunction getIvar(obj, name) {\n const retPtr = MOPointer.new();\n (0, _runtime.object_getInstanceVariable)(obj, name, retPtr);\n return retPtr.value().retain().autorelease();\n}","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.SuperCall = SuperCall;\nexports.CFunc = CFunc;\nconst objc_super_typeEncoding = '{objc_super=\"receiver\"@\"super_class\"#}';\n\n// You can store this to call your function. this must be bound to the current instance.\nfunction SuperCall(selector, argTypes, returnType) {\n const func = CFunc(\"objc_msgSendSuper\", [{ type: '^' + objc_super_typeEncoding }, { type: \":\" }, ...argTypes], returnType);\n return function (...args) {\n const struct = make_objc_super(this, this.superclass());\n const structPtr = MOPointer.alloc().initWithValue_(struct);\n return func(structPtr, selector, ...args);\n };\n}\n\n// Recursively create a MOStruct\nfunction makeStruct(def) {\n if (typeof def !== 'object' || Object.keys(def).length == 0) {\n return def;\n }\n const name = Object.keys(def)[0];\n const values = def[name];\n\n const structure = MOStruct.structureWithName_memberNames_runtime(name, Object.keys(values), Mocha.sharedRuntime());\n\n Object.keys(values).map(member => {\n structure[member] = makeStruct(values[member]);\n });\n\n return structure;\n}\n\nfunction make_objc_super(self, cls) {\n return makeStruct({\n objc_super: {\n receiver: self,\n super_class: cls\n }\n });\n}\n\n// Due to particularities of the JS bridge, we can't call into MOBridgeSupport objects directly\n// But, we can ask key value coding to do the dirty work for us ;)\nfunction setKeys(o, d) {\n const funcDict = NSMutableDictionary.dictionary();\n funcDict.o = o;\n Object.keys(d).map(k => funcDict.setValue_forKeyPath(d[k], \"o.\" + k));\n}\n\n// Use any C function, not just ones with BridgeSupport\nfunction CFunc(name, args, retVal) {\n function makeArgument(a) {\n if (!a) return null;\n const arg = MOBridgeSupportArgument.alloc().init();\n setKeys(arg, {\n type64: a.type\n });\n return arg;\n }\n const func = MOBridgeSupportFunction.alloc().init();\n setKeys(func, {\n name: name,\n arguments: args.map(makeArgument),\n returnValue: makeArgument(retVal)\n });\n return func;\n}\n\n/*\n@encode(char*) = \"*\"\n@encode(id) = \"@\"\n@encode(Class) = \"#\"\n@encode(void*) = \"^v\"\n@encode(CGRect) = \"{CGRect={CGPoint=dd}{CGSize=dd}}\"\n@encode(SEL) = \":\"\n*/\n\nfunction addStructToBridgeSupport(key, structDef) {\n // OK, so this is probably the nastiest hack in this file.\n // We go modify MOBridgeSupportController behind its back and use kvc to add our own definition\n // There isn't another API for this though. So the only other way would be to make a real bridgesupport file.\n const symbols = MOBridgeSupportController.sharedController().valueForKey('symbols');\n if (!symbols) throw Error(\"Something has changed within bridge support so we can't add our definitions\");\n // If someone already added this definition, don't re-register it.\n if (symbols[key] !== null) return;\n const def = MOBridgeSupportStruct.alloc().init();\n setKeys(def, {\n name: key,\n type: structDef.type\n });\n symbols[key] = def;\n};\n\n// This assumes the ivar is an object type. Return value is pretty useless.\nconst object_getInstanceVariable = exports.object_getInstanceVariable = CFunc(\"object_getInstanceVariable\", [{ type: \"@\" }, { type: '*' }, { type: \"^@\" }], { type: \"^{objc_ivar=}\" });\n// Again, ivar is of object type\nconst object_setInstanceVariable = exports.object_setInstanceVariable = CFunc(\"object_setInstanceVariable\", [{ type: \"@\" }, { type: '*' }, { type: \"@\" }], { type: \"^{objc_ivar=}\" });\n\n// We need Mocha to understand what an objc_super is so we can use it as a function argument\naddStructToBridgeSupport('objc_super', { type: objc_super_typeEncoding });","'use strict';\n\n/**\n * @this {Promise}\n */\nfunction finallyConstructor(callback) {\n var constructor = this.constructor;\n return this.then(\n function(value) {\n return constructor.resolve(callback()).then(function() {\n return value;\n });\n },\n function(reason) {\n return constructor.resolve(callback()).then(function() {\n return constructor.reject(reason);\n });\n }\n );\n}\n\n// Store setTimeout reference so promise-polyfill will be unaffected by\n// other code modifying setTimeout (like sinon.useFakeTimers())\nvar setTimeoutFunc = setTimeout;\n\nfunction noop() {}\n\n// Polyfill for Function.prototype.bind\nfunction bind(fn, thisArg) {\n return function() {\n fn.apply(thisArg, arguments);\n };\n}\n\n/**\n * @constructor\n * @param {Function} fn\n */\nfunction Promise(fn) {\n if (!(this instanceof Promise))\n throw new TypeError('Promises must be constructed via new');\n if (typeof fn !== 'function') throw new TypeError('not a function');\n /** @type {!number} */\n this._state = 0;\n /** @type {!boolean} */\n this._handled = false;\n /** @type {Promise|undefined} */\n this._value = undefined;\n /** @type {!Array} */\n this._deferreds = [];\n\n doResolve(fn, this);\n}\n\nfunction handle(self, deferred) {\n while (self._state === 3) {\n self = self._value;\n }\n if (self._state === 0) {\n self._deferreds.push(deferred);\n return;\n }\n self._handled = true;\n Promise._immediateFn(function() {\n var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;\n if (cb === null) {\n (self._state === 1 ? resolve : reject)(deferred.promise, self._value);\n return;\n }\n var ret;\n try {\n ret = cb(self._value);\n } catch (e) {\n reject(deferred.promise, e);\n return;\n }\n resolve(deferred.promise, ret);\n });\n}\n\nfunction resolve(self, newValue) {\n try {\n // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure\n if (newValue === self)\n throw new TypeError('A promise cannot be resolved with itself.');\n if (\n newValue &&\n (typeof newValue === 'object' || typeof newValue === 'function')\n ) {\n var then = newValue.then;\n if (newValue instanceof Promise) {\n self._state = 3;\n self._value = newValue;\n finale(self);\n return;\n } else if (typeof then === 'function') {\n doResolve(bind(then, newValue), self);\n return;\n }\n }\n self._state = 1;\n self._value = newValue;\n finale(self);\n } catch (e) {\n reject(self, e);\n }\n}\n\nfunction reject(self, newValue) {\n self._state = 2;\n self._value = newValue;\n finale(self);\n}\n\nfunction finale(self) {\n if (self._state === 2 && self._deferreds.length === 0) {\n Promise._immediateFn(function() {\n if (!self._handled) {\n Promise._unhandledRejectionFn(self._value);\n }\n });\n }\n\n for (var i = 0, len = self._deferreds.length; i < len; i++) {\n handle(self, self._deferreds[i]);\n }\n self._deferreds = null;\n}\n\n/**\n * @constructor\n */\nfunction Handler(onFulfilled, onRejected, promise) {\n this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n this.promise = promise;\n}\n\n/**\n * Take a potentially misbehaving resolver function and make sure\n * onFulfilled and onRejected are only called once.\n *\n * Makes no guarantees about asynchrony.\n */\nfunction doResolve(fn, self) {\n var done = false;\n try {\n fn(\n function(value) {\n if (done) return;\n done = true;\n resolve(self, value);\n },\n function(reason) {\n if (done) return;\n done = true;\n reject(self, reason);\n }\n );\n } catch (ex) {\n if (done) return;\n done = true;\n reject(self, ex);\n }\n}\n\nPromise.prototype['catch'] = function(onRejected) {\n return this.then(null, onRejected);\n};\n\nPromise.prototype.then = function(onFulfilled, onRejected) {\n // @ts-ignore\n var prom = new this.constructor(noop);\n\n handle(this, new Handler(onFulfilled, onRejected, prom));\n return prom;\n};\n\nPromise.prototype['finally'] = finallyConstructor;\n\nPromise.all = function(arr) {\n return new Promise(function(resolve, reject) {\n if (!arr || typeof arr.length === 'undefined')\n throw new TypeError('Promise.all accepts an array');\n var args = Array.prototype.slice.call(arr);\n if (args.length === 0) return resolve([]);\n var remaining = args.length;\n\n function res(i, val) {\n try {\n if (val && (typeof val === 'object' || typeof val === 'function')) {\n var then = val.then;\n if (typeof then === 'function') {\n then.call(\n val,\n function(val) {\n res(i, val);\n },\n reject\n );\n return;\n }\n }\n args[i] = val;\n if (--remaining === 0) {\n resolve(args);\n }\n } catch (ex) {\n reject(ex);\n }\n }\n\n for (var i = 0; i < args.length; i++) {\n res(i, args[i]);\n }\n });\n};\n\nPromise.resolve = function(value) {\n if (value && typeof value === 'object' && value.constructor === Promise) {\n return value;\n }\n\n return new Promise(function(resolve) {\n resolve(value);\n });\n};\n\nPromise.reject = function(value) {\n return new Promise(function(resolve, reject) {\n reject(value);\n });\n};\n\nPromise.race = function(values) {\n return new Promise(function(resolve, reject) {\n for (var i = 0, len = values.length; i < len; i++) {\n values[i].then(resolve, reject);\n }\n });\n};\n\n// Use polyfill for setImmediate for performance gains\nPromise._immediateFn =\n (typeof setImmediate === 'function' &&\n function(fn) {\n setImmediate(fn);\n }) ||\n function(fn) {\n setTimeoutFunc(fn, 0);\n };\n\nPromise._unhandledRejectionFn = function _unhandledRejectionFn(err) {\n if (typeof console !== 'undefined' && console) {\n console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console\n }\n};\n\nmodule.exports = Promise;\n","var COLOR_CLASSES = [\n 'NSColor',\n 'NSCachedWhiteColor',\n 'NSColorSpaceColor',\n 'NSDynamicSystemColor',\n 'NSCachedColorSpaceColor',\n]\nfunction parseHexColor(color) {\n // Check the string for incorrect formatting.\n if (!color || color[0] !== '#') {\n if (\n color &&\n color.class &&\n COLOR_CLASSES.indexOf(String(color.class())) !== -1\n ) {\n return color\n }\n throw new Error(\n 'Incorrect color formating. It should be an hex color: #RRGGBBAA'\n )\n }\n\n // append FF if alpha channel is not specified.\n var source = color.substr(1)\n if (source.length === 3) {\n source += 'F'\n } else if (source.length === 6) {\n source += 'FF'\n }\n // Convert the string from #FFF format to #FFFFFF format.\n var hex\n if (source.length === 4) {\n for (var i = 0; i < 4; i += 1) {\n hex += source[i]\n hex += source[i]\n }\n } else if (source.length === 8) {\n hex = source\n } else {\n return NSColor.whiteColor()\n }\n\n var r = parseInt(hex.slice(0, 2), 16)\n var g = parseInt(hex.slice(2, 4), 16)\n var b = parseInt(hex.slice(4, 6), 16)\n var a = parseInt(hex.slice(6, 8), 16)\n\n return NSColor.colorWithSRGBRed_green_blue_alpha(r, g, b, a)\n}\n\nmodule.exports = function(browserWindow, panel, webview) {\n // keep reference to the subviews\n browserWindow._panel = panel\n browserWindow._webview = webview\n browserWindow._destroyed = false\n\n browserWindow.destroy = function() {\n return panel.close()\n }\n\n browserWindow.close = function() {\n if (panel.delegate().utils.parentWindow) {\n var shouldClose = true\n browserWindow.emit('close', {\n get defaultPrevented() {\n return !shouldClose\n },\n preventDefault: function() {\n shouldClose = false\n },\n })\n if (shouldClose) {\n panel.delegate().utils.parentWindow.endSheet(panel)\n }\n return\n }\n\n if (!browserWindow.isClosable()) {\n return\n }\n\n panel.performClose(null)\n }\n\n function focus(focused) {\n if (browserWindow.isVisible()) {\n return\n }\n if (focused) {\n NSApplication.sharedApplication().activateIgnoringOtherApps(true)\n panel.makeKeyAndOrderFront(null)\n } else {\n panel.orderBack(null)\n }\n }\n\n browserWindow.focus = focus.bind(this, true)\n browserWindow.blur = focus.bind(this, false)\n\n browserWindow.isFocused = function() {\n return panel.isKeyWindow()\n }\n\n browserWindow.isDestroyed = function() {\n return browserWindow._destroyed\n }\n\n browserWindow.show = function() {\n // This method is supposed to put focus on window, however if the app does not\n // have focus then \"makeKeyAndOrderFront\" will only show the window.\n NSApp.activateIgnoringOtherApps(true)\n\n if (panel.delegate().utils.parentWindow) {\n return panel.delegate().utils.parentWindow.beginSheet_completionHandler(\n panel,\n __mocha__.createBlock_function('v16@?0q8', function() {\n browserWindow.emit('closed')\n })\n )\n }\n\n return panel.makeKeyAndOrderFront(null)\n }\n\n browserWindow.showInactive = function() {\n return panel.orderFrontRegardless()\n }\n\n browserWindow.hide = function() {\n return panel.orderOut(null)\n }\n\n browserWindow.isVisible = function() {\n return panel.isVisible()\n }\n\n browserWindow.isModal = function() {\n return false\n }\n\n browserWindow.maximize = function() {\n if (!browserWindow.isMaximized()) {\n panel.zoom(null)\n }\n }\n browserWindow.unmaximize = function() {\n if (browserWindow.isMaximized()) {\n panel.zoom(null)\n }\n }\n\n browserWindow.isMaximized = function() {\n if ((panel.styleMask() & NSResizableWindowMask) !== 0) {\n return panel.isZoomed()\n }\n var rectScreen = NSScreen.mainScreen().visibleFrame()\n var rectWindow = panel.frame()\n return (\n rectScreen.origin.x == rectWindow.origin.x &&\n rectScreen.origin.y == rectWindow.origin.y &&\n rectScreen.size.width == rectWindow.size.width &&\n rectScreen.size.height == rectWindow.size.height\n )\n }\n\n browserWindow.minimize = function() {\n return panel.miniaturize(null)\n }\n\n browserWindow.restore = function() {\n return panel.deminiaturize(null)\n }\n\n browserWindow.isMinimized = function() {\n return panel.isMiniaturized()\n }\n\n browserWindow.setFullScreen = function(fullscreen) {\n if (fullscreen !== browserWindow.isFullscreen()) {\n panel.toggleFullScreen(null)\n }\n }\n\n browserWindow.isFullscreen = function() {\n return panel.styleMask() & NSFullScreenWindowMask\n }\n\n browserWindow.setAspectRatio = function(aspectRatio /* , extraSize */) {\n // Reset the behaviour to default if aspect_ratio is set to 0 or less.\n if (aspectRatio > 0.0) {\n panel.setAspectRatio(NSMakeSize(aspectRatio, 1.0))\n } else {\n panel.setResizeIncrements(NSMakeSize(1.0, 1.0))\n }\n }\n\n browserWindow.setBounds = function(bounds, animate) {\n // Do nothing if in fullscreen mode.\n if (browserWindow.isFullscreen()) {\n return\n }\n\n // TODO: Check size constraints since setFrame does not check it.\n var size = bounds.size\n // size.SetToMax(GetMinimumSize());\n // gfx::Size max_size = GetMaximumSize();\n // if (!max_size.IsEmpty())\n // size.SetToMin(max_size);\n\n var cocoaBounds = NSMakeRect(bounds.origin.x, 0, size.width, size.height)\n // Flip coordinates based on the primary screen.\n var screen = NSScreen.screens().firstObject()\n cocoaBounds.origin.y =\n NSHeight(screen.frame()) - size.height - bounds.origin.y\n\n panel.setFrame_display_animate(cocoaBounds, true, animate)\n }\n\n browserWindow.getBounds = function() {\n return panel.frame()\n }\n\n browserWindow.setContentBounds = function(/* bounds, animate */) {\n // TODO:\n }\n\n browserWindow.getContentBounds = function() {\n // TODO:\n }\n\n browserWindow.setSize = function(width, height, animate) {\n var bounds = browserWindow.getBounds()\n bounds.size.height = height\n bounds.size.width = width\n\n // TODO: handle resizing around center\n\n return browserWindow.setBounds(bounds, animate)\n }\n\n browserWindow.getSize = function() {\n var bounds = browserWindow.getBounds()\n return [bounds.size.width, bounds.size.height]\n }\n\n browserWindow.setContentSize = function(width, height, animate) {\n var bounds = browserWindow.getContentBounds()\n bounds.size.height = height\n bounds.size.width = width\n\n // TODO: handle resizing around center\n\n return browserWindow.setContentBounds(bounds, animate)\n }\n\n browserWindow.getContentSize = function() {\n var bounds = browserWindow.getContentBounds()\n return [bounds.size.width, bounds.size.height]\n }\n\n browserWindow.setMinimumSize = function(width, height) {\n const minSize = { width: width, height: height }\n panel.setContentMinSize(minSize)\n }\n\n browserWindow.getMinimumSize = function() {\n const size = panel.contentMinSize()\n return [size.width, size.height]\n }\n\n browserWindow.setMaximumSize = function(width, height) {\n const minSize = { width: width, height: height }\n panel.setContentMaxSize(minSize)\n }\n\n browserWindow.getMaximumSize = function() {\n const size = panel.contentMaxSize()\n return [size.width, size.height]\n }\n\n browserWindow.setResizable = function(resizable) {\n return browserWindow._setStyleMask(resizable, NSResizableWindowMask)\n }\n\n browserWindow.isResizable = function() {\n return panel.styleMask() & NSResizableWindowMask\n }\n\n browserWindow.setMovable = function(movable) {\n return panel.setMovable(movable)\n }\n browserWindow.isMovable = function() {\n return panel.isMovable()\n }\n\n browserWindow.setMinimizable = function(minimizable) {\n return browserWindow._setStyleMask(minimizable, NSMiniaturizableWindowMask)\n }\n\n browserWindow.isMinimizable = function() {\n return panel.styleMask() & NSMiniaturizableWindowMask\n }\n\n browserWindow.setMaximizable = function(maximizable) {\n if (panel.standardWindowButton(NSWindowZoomButton)) {\n panel.standardWindowButton(NSWindowZoomButton).setEnabled(maximizable)\n }\n }\n\n browserWindow.isMaximizable = function() {\n return (\n panel.standardWindowButton(NSWindowZoomButton) &&\n panel.standardWindowButton(NSWindowZoomButton).isEnabled()\n )\n }\n\n browserWindow.setFullScreenable = function(fullscreenable) {\n browserWindow._setCollectionBehavior(\n fullscreenable,\n NSWindowCollectionBehaviorFullScreenPrimary\n )\n // On EL Capitan this flag is required to hide fullscreen button.\n browserWindow._setCollectionBehavior(\n !fullscreenable,\n NSWindowCollectionBehaviorFullScreenAuxiliary\n )\n }\n\n browserWindow.isFullScreenable = function() {\n var collectionBehavior = panel.collectionBehavior()\n return collectionBehavior & NSWindowCollectionBehaviorFullScreenPrimary\n }\n\n browserWindow.setClosable = function(closable) {\n browserWindow._setStyleMask(closable, NSClosableWindowMask)\n }\n\n browserWindow.isClosable = function() {\n return panel.styleMask() & NSClosableWindowMask\n }\n\n browserWindow.setAlwaysOnTop = function(top, level, relativeLevel) {\n var windowLevel = NSNormalWindowLevel\n var maxWindowLevel = CGWindowLevelForKey(kCGMaximumWindowLevelKey)\n var minWindowLevel = CGWindowLevelForKey(kCGMinimumWindowLevelKey)\n\n if (top) {\n if (level === 'normal') {\n windowLevel = NSNormalWindowLevel\n } else if (level === 'torn-off-menu') {\n windowLevel = NSTornOffMenuWindowLevel\n } else if (level === 'modal-panel') {\n windowLevel = NSModalPanelWindowLevel\n } else if (level === 'main-menu') {\n windowLevel = NSMainMenuWindowLevel\n } else if (level === 'status') {\n windowLevel = NSStatusWindowLevel\n } else if (level === 'pop-up-menu') {\n windowLevel = NSPopUpMenuWindowLevel\n } else if (level === 'screen-saver') {\n windowLevel = NSScreenSaverWindowLevel\n } else if (level === 'dock') {\n // Deprecated by macOS, but kept for backwards compatibility\n windowLevel = NSDockWindowLevel\n } else {\n windowLevel = NSFloatingWindowLevel\n }\n }\n\n var newLevel = windowLevel + (relativeLevel || 0)\n if (newLevel >= minWindowLevel && newLevel <= maxWindowLevel) {\n panel.setLevel(newLevel)\n } else {\n throw new Error(\n 'relativeLevel must be between ' +\n minWindowLevel +\n ' and ' +\n maxWindowLevel\n )\n }\n }\n\n browserWindow.isAlwaysOnTop = function() {\n return panel.level() !== NSNormalWindowLevel\n }\n\n browserWindow.moveTop = function() {\n return panel.orderFrontRegardless()\n }\n\n browserWindow.center = function() {\n panel.center()\n }\n\n browserWindow.setPosition = function(x, y, animate) {\n var bounds = browserWindow.getBounds()\n var mainScreenRect = NSScreen.screens()\n .firstObject()\n .frame()\n bounds.origin.x = x\n bounds.origin.y = Math.round(NSHeight(mainScreenRect) - y)\n\n return browserWindow.setBounds(bounds, animate)\n }\n\n browserWindow.getPosition = function() {\n var bounds = browserWindow.getBounds()\n var mainScreenRect = NSScreen.screens()\n .firstObject()\n .frame()\n return [\n bounds.origin.x,\n Math.round(NSHeight(mainScreenRect) - bounds.origin.y),\n ]\n }\n\n browserWindow.setTitle = function(title) {\n panel.setTitle(title)\n }\n\n browserWindow.getTitle = function() {\n return String(panel.title())\n }\n\n var attentionRequestId = 0\n browserWindow.flashFrame = function(flash) {\n if (flash) {\n attentionRequestId = NSApp.requestUserAttention(NSInformationalRequest)\n } else {\n NSApp.cancelUserAttentionRequest(attentionRequestId)\n attentionRequestId = 0\n }\n }\n\n browserWindow.getNativeWindowHandle = function() {\n return panel\n }\n\n browserWindow.getNativeWebViewHandle = function() {\n return webview\n }\n\n browserWindow.loadURL = function(url) {\n // When frameLocation is a file, prefix it with the Sketch Resources path\n if (/^(?!http|localhost|www|file).*\\.html?$/.test(url)) {\n if (typeof __command !== 'undefined' && __command.pluginBundle()) {\n url =\n 'file://' +\n __command\n .pluginBundle()\n .urlForResourceNamed(url)\n .path()\n }\n }\n\n if (/^file:\\/\\/.*\\.html?$/.test(url)) {\n webview.loadFileURL_allowingReadAccessToURL(\n NSURL.fileURLWithPath(url),\n NSURL.fileURLWithPath('file:///')\n )\n return\n }\n\n webview.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(url)))\n }\n\n browserWindow.reload = function() {\n webview.reload()\n }\n\n browserWindow.setHasShadow = function(hasShadow) {\n return panel.setHasShadow(hasShadow)\n }\n\n browserWindow.hasShadow = function() {\n return panel.hasShadow()\n }\n\n browserWindow.setOpacity = function(opacity) {\n return panel.setAlphaValue(opacity)\n }\n\n browserWindow.getOpacity = function() {\n return panel.alphaValue()\n }\n\n browserWindow.setVisibleOnAllWorkspaces = function(visible) {\n return browserWindow._setCollectionBehavior(\n visible,\n NSWindowCollectionBehaviorCanJoinAllSpaces\n )\n }\n\n browserWindow.isVisibleOnAllWorkspaces = function() {\n var collectionBehavior = panel.collectionBehavior()\n return collectionBehavior & NSWindowCollectionBehaviorCanJoinAllSpaces\n }\n\n browserWindow.setIgnoreMouseEvents = function(ignore) {\n return panel.setIgnoresMouseEvents(ignore)\n }\n\n browserWindow.setContentProtection = function(enable) {\n panel.setSharingType(enable ? NSWindowSharingNone : NSWindowSharingReadOnly)\n }\n\n browserWindow.setAutoHideCursor = function(autoHide) {\n panel.setDisableAutoHideCursor(autoHide)\n }\n\n browserWindow.setVibrancy = function(type) {\n var effectView = browserWindow._vibrantView\n\n if (!type) {\n if (effectView == null) {\n return\n }\n\n effectView.removeFromSuperview()\n panel.setVibrantView(null)\n return\n }\n\n if (effectView == null) {\n var contentView = panel.contentView()\n effectView = NSVisualEffectView.alloc().initWithFrame(\n contentView.bounds()\n )\n browserWindow._vibrantView = effectView\n\n effectView.setAutoresizingMask(NSViewWidthSizable | NSViewHeightSizable)\n effectView.setBlendingMode(NSVisualEffectBlendingModeBehindWindow)\n effectView.setState(NSVisualEffectStateActive)\n effectView.setFrame(contentView.bounds())\n contentView.addSubview_positioned_relativeTo(\n effectView,\n NSWindowBelow,\n null\n )\n }\n\n var vibrancyType = NSVisualEffectMaterialLight\n\n if (type === 'appearance-based') {\n vibrancyType = NSVisualEffectMaterialAppearanceBased\n } else if (type === 'light') {\n vibrancyType = NSVisualEffectMaterialLight\n } else if (type === 'dark') {\n vibrancyType = NSVisualEffectMaterialDark\n } else if (type === 'titlebar') {\n vibrancyType = NSVisualEffectMaterialTitlebar\n } else if (type === 'selection') {\n vibrancyType = NSVisualEffectMaterialSelection\n } else if (type === 'menu') {\n vibrancyType = NSVisualEffectMaterialMenu\n } else if (type === 'popover') {\n vibrancyType = NSVisualEffectMaterialPopover\n } else if (type === 'sidebar') {\n vibrancyType = NSVisualEffectMaterialSidebar\n } else if (type === 'medium-light') {\n vibrancyType = NSVisualEffectMaterialMediumLight\n } else if (type === 'ultra-dark') {\n vibrancyType = NSVisualEffectMaterialUltraDark\n }\n\n effectView.setMaterial(vibrancyType)\n }\n\n browserWindow._setBackgroundColor = function(colorName) {\n var color = parseHexColor(colorName)\n webview.isOpaque = false\n webview.setBackgroundColor(NSColor.clearColor())\n panel.backgroundColor = color\n }\n\n browserWindow._invalidate = function() {\n panel.flushWindow()\n panel.contentView().setNeedsDisplay(true)\n }\n\n browserWindow._setStyleMask = function(on, flag) {\n var wasMaximizable = browserWindow.isMaximizable()\n if (on) {\n panel.setStyleMask(panel.styleMask() | flag)\n } else {\n panel.setStyleMask(panel.styleMask() & ~flag)\n }\n // Change style mask will make the zoom button revert to default, probably\n // a bug of Cocoa or macOS.\n browserWindow.setMaximizable(wasMaximizable)\n }\n\n browserWindow._setCollectionBehavior = function(on, flag) {\n var wasMaximizable = browserWindow.isMaximizable()\n if (on) {\n panel.setCollectionBehavior(panel.collectionBehavior() | flag)\n } else {\n panel.setCollectionBehavior(panel.collectionBehavior() & ~flag)\n }\n // Change collectionBehavior will make the zoom button revert to default,\n // probably a bug of Cocoa or macOS.\n browserWindow.setMaximizable(wasMaximizable)\n }\n\n browserWindow._showWindowButton = function(button) {\n var view = panel.standardWindowButton(button)\n view.superview().addSubview_positioned_relative(view, NSWindowAbove, null)\n }\n}\n","module.exports = {\n JS_BRIDGE: '__skpm_sketchBridge',\n}\n","var tagsToFocus =\n '[\"text\", \"textarea\", \"date\", \"datetime-local\", \"email\", \"number\", \"month\", \"password\", \"search\", \"tel\", \"time\", \"url\", \"week\" ]'\n\nmodule.exports = function(webView, event) {\n var point = webView.convertPoint_fromView(event.locationInWindow(), null)\n var x = point.x\n var y = webView.frame().size.height - point.y // the coord start from the bottom instead of the top\n return (\n 'var el = document.elementFromPoint(' + // get the DOM element that match the event\n x +\n ', ' +\n y +\n '); ' +\n 'if (el && ' + // some tags need to be focused instead of clicked\n tagsToFocus +\n '.indexOf(el.type) >= 0 && ' +\n 'el.focus' +\n ') {' +\n 'el.focus();' + // so focus them\n '} else if (el) {' +\n 'el.dispatchEvent(new Event(\"click\", {bubbles: true}))' + // click the others\n '}'\n )\n}\n","function addEdgeConstraint(edge, subview, view, constant) {\n view.addConstraint(\n NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant(\n subview,\n edge,\n NSLayoutRelationEqual,\n view,\n edge,\n 1,\n constant\n )\n )\n}\nmodule.exports = function fitSubviewToView(subview, view, constants) {\n constants = constants || []\n subview.setTranslatesAutoresizingMaskIntoConstraints(false)\n\n addEdgeConstraint(NSLayoutAttributeLeft, subview, view, constants[0] || 0)\n addEdgeConstraint(NSLayoutAttributeTop, subview, view, constants[1] || 0)\n addEdgeConstraint(NSLayoutAttributeRight, subview, view, constants[2] || 0)\n addEdgeConstraint(NSLayoutAttributeBottom, subview, view, constants[3] || 0)\n}\n","/* let's try to match the API from Electron's Browser window\n(https://github.com/electron/electron/blob/master/docs/api/browser-window.md) */\nvar EventEmitter = require('events')\nvar buildBrowserAPI = require('./browser-api')\nvar buildWebAPI = require('./webview-api')\nvar fitSubviewToView = require('./fitSubview')\nvar dispatchFirstClick = require('./dispatch-first-click')\nvar injectClientMessaging = require('./inject-client-messaging')\nvar setDelegates = require('./set-delegates')\n\nfunction BrowserWindow(options) {\n options = options || {}\n\n var identifier = options.identifier || NSUUID.UUID().UUIDString()\n var threadDictionary = NSThread.mainThread().threadDictionary()\n\n var existingBrowserWindow = BrowserWindow.fromId(identifier)\n\n // if we already have a window opened, reuse it\n if (existingBrowserWindow) {\n return existingBrowserWindow\n }\n\n var browserWindow = new EventEmitter()\n browserWindow.id = identifier\n\n if (options.modal && !options.parent) {\n throw new Error('A modal needs to have a parent.')\n }\n\n // Long-running script\n var fiber = coscript.createFiber()\n\n // Window size\n var width = options.width || 800\n var height = options.height || 600\n var mainScreenRect = NSScreen.screens()\n .firstObject()\n .frame()\n var cocoaBounds = NSMakeRect(\n typeof options.x !== 'undefined'\n ? options.x\n : Math.round((NSWidth(mainScreenRect) - width) / 2),\n typeof options.y !== 'undefined'\n ? options.y\n : Math.round((NSHeight(mainScreenRect) - height) / 2),\n width,\n height\n )\n\n if (options.titleBarStyle && options.titleBarStyle !== 'default') {\n options.frame = false\n }\n\n var useStandardWindow = options.windowType !== 'textured'\n var styleMask = NSTitledWindowMask\n\n // this is commented out because the toolbar doesn't appear otherwise :thinking-face:\n // if (!useStandardWindow || options.frame === false) {\n // styleMask = NSFullSizeContentViewWindowMask\n // }\n if (options.minimizable !== false) {\n styleMask |= NSMiniaturizableWindowMask\n }\n if (options.closable !== false) {\n styleMask |= NSClosableWindowMask\n }\n if (options.resizable !== false) {\n styleMask |= NSResizableWindowMask\n }\n if (!useStandardWindow || options.transparent || options.frame === false) {\n styleMask |= NSTexturedBackgroundWindowMask\n }\n\n var panel = NSPanel.alloc().initWithContentRect_styleMask_backing_defer(\n cocoaBounds,\n styleMask,\n NSBackingStoreBuffered,\n true\n )\n\n var wkwebviewConfig = WKWebViewConfiguration.alloc().init()\n var webView = WKWebView.alloc().initWithFrame_configuration(\n CGRectMake(0, 0, options.width || 800, options.height || 600),\n wkwebviewConfig\n )\n injectClientMessaging(webView)\n webView.setAutoresizingMask(NSViewWidthSizable | NSViewHeightSizable)\n\n buildBrowserAPI(browserWindow, panel, webView)\n buildWebAPI(browserWindow, panel, webView)\n setDelegates(browserWindow, panel, webView, options)\n\n if (options.windowType === 'desktop') {\n panel.setLevel(kCGDesktopWindowLevel - 1)\n // panel.setCanBecomeKeyWindow(false)\n panel.setCollectionBehavior(\n NSWindowCollectionBehaviorCanJoinAllSpaces |\n NSWindowCollectionBehaviorStationary |\n NSWindowCollectionBehaviorIgnoresCycle\n )\n }\n\n if (\n typeof options.minWidth !== 'undefined' ||\n typeof options.minHeight !== 'undefined'\n ) {\n browserWindow.setMinimumSize(options.minWidth || 0, options.minHeight || 0)\n }\n\n if (\n typeof options.maxWidth !== 'undefined' ||\n typeof options.maxHeight !== 'undefined'\n ) {\n browserWindow.setMaximumSize(\n options.maxWidth || 10000,\n options.maxHeight || 10000\n )\n }\n\n // if (options.focusable === false) {\n // panel.setCanBecomeKeyWindow(false)\n // }\n\n if (options.transparent || options.frame === false) {\n panel.titlebarAppearsTransparent = true\n panel.titleVisibility = NSWindowTitleHidden\n panel.setOpaque(0)\n panel.isMovableByWindowBackground = true\n var toolbar2 = NSToolbar.alloc().initWithIdentifier(\n 'titlebarStylingToolbar'\n )\n toolbar2.setShowsBaselineSeparator(false)\n panel.setToolbar(toolbar2)\n }\n\n if (options.titleBarStyle === 'hiddenInset') {\n var toolbar = NSToolbar.alloc().initWithIdentifier('titlebarStylingToolbar')\n toolbar.setShowsBaselineSeparator(false)\n panel.setToolbar(toolbar)\n }\n\n if (options.frame === false || !options.useContentSize) {\n browserWindow.setSize(width, height)\n }\n\n if (options.center) {\n browserWindow.center()\n }\n\n if (options.alwaysOnTop) {\n browserWindow.setAlwaysOnTop(true)\n }\n\n if (options.fullscreen) {\n browserWindow.setFullScreen(true)\n }\n browserWindow.setFullScreenable(!!options.fullscreenable)\n\n const title =\n options.title ||\n (typeof __command !== 'undefined' && __command.pluginBundle()\n ? __command.pluginBundle().name()\n : undefined)\n if (title) {\n browserWindow.setTitle(title)\n }\n\n var backgroundColor = options.backgroundColor\n if (options.transparent) {\n backgroundColor = NSColor.clearColor()\n }\n if (!backgroundColor && options.frame === false && options.vibrancy) {\n backgroundColor = NSColor.clearColor()\n }\n\n browserWindow._setBackgroundColor(\n backgroundColor || NSColor.windowBackgroundColor()\n )\n\n if (options.hasShadow === false) {\n browserWindow.setHasShadow(false)\n }\n\n if (typeof options.opacity !== 'undefined') {\n browserWindow.setOpacity(options.opacity)\n }\n\n options.webPreferences = options.webPreferences || {}\n\n webView\n .configuration()\n .preferences()\n .setValue_forKey(\n options.webPreferences.devTools !== false,\n 'developerExtrasEnabled'\n )\n webView\n .configuration()\n .preferences()\n .setValue_forKey(\n options.webPreferences.devTools !== false,\n 'javaScriptEnabled'\n )\n webView\n .configuration()\n .preferences()\n .setValue_forKey(!!options.webPreferences.plugins, 'plugInsEnabled')\n webView\n .configuration()\n .preferences()\n .setValue_forKey(\n options.webPreferences.minimumFontSize || 0,\n 'minimumFontSize'\n )\n\n if (options.webPreferences.zoomFactor) {\n webView.setMagnification(options.webPreferences.zoomFactor)\n }\n\n var contentView = panel.contentView()\n\n if (options.frame !== false) {\n webView.setFrame(contentView.bounds())\n contentView.addSubview(webView)\n } else {\n // In OSX 10.10, adding subviews to the root view for the NSView hierarchy\n // produces warnings. To eliminate the warnings, we resize the contentView\n // to fill the window, and add subviews to that.\n // http://crbug.com/380412\n contentView.setAutoresizingMask(NSViewWidthSizable | NSViewHeightSizable)\n fitSubviewToView(contentView, contentView.superview())\n\n webView.setFrame(contentView.bounds())\n contentView.addSubview(webView)\n\n // The fullscreen button should always be hidden for frameless window.\n if (panel.standardWindowButton(NSWindowFullScreenButton)) {\n panel.standardWindowButton(NSWindowFullScreenButton).setHidden(true)\n }\n\n if (!options.titleBarStyle || options.titleBarStyle === 'default') {\n // Hide the window buttons.\n panel.standardWindowButton(NSWindowZoomButton).setHidden(true)\n panel.standardWindowButton(NSWindowMiniaturizeButton).setHidden(true)\n panel.standardWindowButton(NSWindowCloseButton).setHidden(true)\n\n // Some third-party macOS utilities check the zoom button's enabled state to\n // determine whether to show custom UI on hover, so we disable it here to\n // prevent them from doing so in a frameless app window.\n panel.standardWindowButton(NSWindowZoomButton).setEnabled(false)\n }\n }\n\n if (options.vibrancy) {\n browserWindow.setVibrancy(options.vibrancy)\n }\n\n // Set maximizable state last to ensure zoom button does not get reset\n // by calls to other APIs.\n browserWindow.setMaximizable(options.maximizable !== false)\n\n if (options.acceptsFirstMouse) {\n browserWindow.on('focus', function(event) {\n if (event.type() === NSEventTypeLeftMouseDown) {\n browserWindow.webContents\n .executeJavaScript(dispatchFirstClick(webView, event))\n .catch(() => {})\n }\n })\n }\n\n if (options.show !== false) {\n browserWindow.show()\n }\n\n browserWindow.on('closed', function() {\n browserWindow._destroyed = true\n threadDictionary.removeObjectForKey(identifier)\n fiber.cleanup()\n })\n\n threadDictionary[identifier] = panel\n\n fiber.onCleanup(function() {\n if (!browserWindow._destroyed) {\n browserWindow.destroy()\n }\n })\n\n return browserWindow\n}\n\nBrowserWindow.fromId = function(identifier) {\n var threadDictionary = NSThread.mainThread().threadDictionary()\n\n if (threadDictionary[identifier]) {\n return BrowserWindow.fromPanel(threadDictionary[identifier], identifier)\n }\n\n return undefined\n}\n\nBrowserWindow.fromPanel = function(panel, identifier) {\n var browserWindow = new EventEmitter()\n browserWindow.id = identifier\n\n if (!panel || !panel.contentView) {\n throw new Error('needs to pass an NSPanel')\n }\n\n var webView = panel.contentView().subviews()[0]\n\n if (!webView) {\n throw new Error('The NSPanel needs to have a webview')\n }\n\n buildBrowserAPI(browserWindow, panel, webView)\n buildWebAPI(browserWindow, panel, webView)\n\n return browserWindow\n}\n\nmodule.exports = BrowserWindow\n","var CONSTANTS = require('./constants')\n\nmodule.exports = function(webView) {\n var source =\n 'window.originalPostMessage = window.postMessage;' +\n 'window.postMessage = function(actionName) {' +\n 'if (!actionName) {' +\n \"throw new Error('missing action name')\" +\n '}' +\n 'window.webkit.messageHandlers.' +\n CONSTANTS.JS_BRIDGE +\n '.postMessage(' +\n 'JSON.stringify([].slice.call(arguments))' +\n ');' +\n '}'\n var script = WKUserScript.alloc().initWithSource_injectionTime_forMainFrameOnly(\n source,\n 0,\n true\n )\n webView\n .configuration()\n .userContentController()\n .addUserScript(script)\n}\n","module.exports = function(webArguments) {\n var args = null\n try {\n args = JSON.parse(webArguments[0])\n } catch (e) {\n // malformed arguments\n }\n\n if (\n !args ||\n !args.constructor ||\n args.constructor !== Array ||\n args.length == 0\n ) {\n return null\n }\n\n return args\n}\n","var ObjCClass = require('cocoascript-class').default\nvar parseWebArguments = require('./parseWebArguments')\nvar CONSTANTS = require('./constants')\n\n// We create one ObjC class for ourselves here\nvar WindowDelegateClass\nvar NavigationDelegateClass\nvar WebScriptHandlerClass\n\n// TODO: events\n// - 'page-favicon-updated'\n// - 'new-window'\n// - 'did-navigate-in-page'\n// - 'will-prevent-unload'\n// - 'crashed'\n// - 'unresponsive'\n// - 'responsive'\n// - 'destroyed'\n// - 'before-input-event'\n// - 'certificate-error'\n// - 'found-in-page'\n// - 'media-started-playing'\n// - 'media-paused'\n// - 'did-change-theme-color'\n// - 'update-target-url'\n// - 'cursor-changed'\n// - 'context-menu'\n// - 'select-bluetooth-device'\n// - 'paint'\n// - 'console-message'\n\nmodule.exports = function(browserWindow, panel, webview, options) {\n if (!WindowDelegateClass) {\n WindowDelegateClass = ObjCClass({\n classname: 'WindowDelegateClass',\n utils: null,\n panel: null,\n\n 'windowDidResize:': function() {\n this.utils.emit('resize')\n },\n\n 'windowDidMiniaturize:': function() {\n this.utils.emit('minimize')\n },\n\n 'windowDidDeminiaturize:': function() {\n this.utils.emit('restore')\n },\n\n 'windowDidEnterFullScreen:': function() {\n this.utils.emit('enter-full-screen')\n },\n\n 'windowDidExitFullScreen:': function() {\n this.utils.emit('leave-full-screen')\n },\n\n 'windowDidMove:': function() {\n this.utils.emit('move')\n this.utils.emit('moved')\n },\n\n 'windowShouldClose:': function() {\n var shouldClose = true\n this.utils.emit('close', {\n get defaultPrevented() {\n return !shouldClose\n },\n preventDefault: function() {\n shouldClose = false\n },\n })\n return shouldClose\n },\n\n 'windowWillClose:': function() {\n this.utils.emit('closed')\n },\n\n 'windowDidBecomeKey:': function() {\n this.utils.emit('focus', this.panel.currentEvent())\n },\n\n 'windowDidResignKey:': function() {\n this.utils.emit('blur')\n },\n })\n }\n\n if (!NavigationDelegateClass) {\n NavigationDelegateClass = ObjCClass({\n classname: 'NavigationDelegateClass',\n state: NSMutableDictionary.dictionaryWithDictionary({\n wasReady: 0,\n }),\n utils: null,\n\n // // Called when the web view begins to receive web content.\n 'webView:didCommitNavigation:': function(webView) {\n this.utils.emit('will-navigate', {}, String(String(webView.url())))\n },\n\n // // Called when web content begins to load in a web view.\n 'webView:didStartProvisionalNavigation:': function() {\n this.utils.emit('did-start-navigation')\n this.utils.emit('did-start-loading')\n },\n\n // Called when a web view receives a server redirect.\n 'webView:didReceiveServerRedirectForProvisionalNavigation:': function() {\n this.utils.emit('did-get-redirect-request')\n },\n\n // // Called when the web view needs to respond to an authentication challenge.\n 'webView:didReceiveAuthenticationChallenge:completionHandler:': function(\n webView,\n challenge,\n completionHandler\n ) {\n function callback(username, password) {\n completionHandler(\n 0,\n NSURLCredential.credentialWithUser_password_persistence(\n username,\n password,\n 1\n )\n )\n }\n var protectionSpace = challenge.protectionSpace()\n this.utils.emit(\n 'login',\n {},\n {\n method: String(protectionSpace.authenticationMethod()),\n url: 'not implemented', // TODO:\n referrer: 'not implemented', // TODO:\n },\n {\n isProxy: !!protectionSpace.isProxy(),\n scheme: String(protectionSpace.protocol()),\n host: String(protectionSpace.host()),\n port: Number(protectionSpace.port()),\n realm: String(protectionSpace.realm()),\n },\n callback\n )\n },\n\n // Called when an error occurs during navigation.\n // 'webView:didFailNavigation:withError:': function(\n // webView,\n // navigation,\n // error\n // ) {},\n\n // Called when an error occurs while the web view is loading content.\n 'webView:didFailProvisionalNavigation:withError:': function(\n webView,\n navigation,\n error\n ) {\n this.utils.emit('did-fail-load', error)\n },\n\n // Called when the navigation is complete.\n 'webView:didFinishNavigation:': function() {\n if (this.state.wasReady == 0) {\n // eslint-disable-line\n this.utils.emitBrowserEvent('ready-to-show')\n this.state.setObject_forKey(1, 'wasReady')\n }\n this.utils.emit('did-navigate')\n this.utils.emit('did-frame-navigate')\n this.utils.emit('did-stop-loading')\n this.utils.emit('did-finish-load')\n this.utils.emit('did-frame-finish-load')\n },\n\n // Called when the web view’s web content process is terminated.\n 'webViewWebContentProcessDidTerminate:': function() {\n this.utils.emit('dom-ready')\n },\n\n // Decides whether to allow or cancel a navigation.\n // webView:decidePolicyForNavigationAction:decisionHandler:\n\n // Decides whether to allow or cancel a navigation after its response is known.\n // webView:decidePolicyForNavigationResponse:decisionHandler:\n })\n }\n\n if (!WebScriptHandlerClass) {\n WebScriptHandlerClass = ObjCClass({\n classname: 'WebScriptHandlerClass',\n utils: null,\n 'userContentController:didReceiveScriptMessage:': function(_, message) {\n var webArguments = JSON.parse(String(message.body()))\n var args = this.utils.parseWebArguments([JSON.stringify(webArguments)])\n if (!args) {\n return\n }\n\n this.utils.emit.apply(this, args)\n },\n })\n }\n\n var navigationDelegate = NavigationDelegateClass.new()\n navigationDelegate.utils = NSDictionary.dictionaryWithDictionary({\n setTitle: browserWindow.setTitle.bind(browserWindow),\n emitBrowserEvent: browserWindow.emit.bind(browserWindow),\n emit: browserWindow.webContents.emit.bind(browserWindow.webContents),\n })\n // reset state as well\n navigationDelegate.state = NSMutableDictionary.dictionaryWithDictionary({\n wasReady: 0,\n })\n\n webview.setNavigationDelegate(navigationDelegate)\n\n var webScriptHandler = WebScriptHandlerClass.new()\n webScriptHandler.utils = NSDictionary.dictionaryWithDictionary({\n emit: browserWindow.webContents.emit.bind(browserWindow.webContents),\n parseWebArguments: parseWebArguments,\n })\n\n webview\n .configuration()\n .userContentController()\n .addScriptMessageHandler_name(webScriptHandler, CONSTANTS.JS_BRIDGE)\n\n var windowDelegate = WindowDelegateClass.new()\n var utils = {\n emit: browserWindow.emit.bind(browserWindow),\n }\n if (options.modal) {\n // find the window of the document\n var msdocument\n if (options.parent.type === 'Document') {\n msdocument = options.parent.sketchObject\n if (msdocument && String(msdocument.class()) === 'MSDocumentData') {\n // we only have an MSDocumentData instead of a MSDocument\n // let's try to get back to the MSDocument\n msdocument = msdocument.delegate()\n }\n } else {\n msdocument = options.parent\n }\n if (msdocument && String(msdocument.class()) === 'MSDocumentData') {\n // we only have an MSDocumentData instead of a MSDocument\n // let's try to get back to the MSDocument\n msdocument = msdocument.delegate()\n }\n utils.parentWindow = msdocument.windowForSheet()\n }\n\n windowDelegate.utils = NSDictionary.dictionaryWithDictionary(utils)\n windowDelegate.panel = panel\n\n panel.setDelegate(windowDelegate)\n}\n","var EventEmitter = require('events')\n\n// let's try to match https://github.com/electron/electron/blob/master/docs/api/web-contents.md\nmodule.exports = function buildAPI(browserWindow, panel, webview) {\n var webContents = new EventEmitter()\n\n webContents.loadURL = browserWindow.loadURL\n\n webContents.loadFile = function(/* filePath */) {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n\n webContents.downloadURL = function(/* filePath */) {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n\n webContents.getURL = function() {\n return String(webview.url())\n }\n\n webContents.getTitle = function() {\n return String(webview.title())\n }\n\n webContents.isDestroyed = function() {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n\n webContents.focus = browserWindow.focus\n webContents.isFocused = browserWindow.isFocused\n\n webContents.isLoading = function() {\n return !!webview.loading()\n }\n\n webContents.isLoadingMainFrame = function() {\n // TODO:\n return !!webview.loading()\n }\n\n webContents.isWaitingForResponse = function() {\n return !webview.loading()\n }\n\n webContents.stop = function() {\n webview.stopLoading()\n }\n webContents.reload = function() {\n webview.reload()\n }\n webContents.reloadIgnoringCache = function() {\n webview.reloadFromOrigin()\n }\n webContents.canGoBack = function() {\n return !!webview.canGoBack()\n }\n webContents.canGoForward = function() {\n return !!webview.canGoForward()\n }\n webContents.canGoToOffset = function(offset) {\n return !!webview.backForwardList().itemAtIndex(offset)\n }\n webContents.clearHistory = function() {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.goBack = function() {\n webview.goBack()\n }\n webContents.goForward = function() {\n webview.goForward()\n }\n webContents.goToIndex = function(index) {\n var backForwardList = webview.backForwardList()\n var backList = backForwardList.backList()\n var backListLength = backList.count()\n if (backListLength > index) {\n webview.loadRequest(NSURLRequest.requestWithURL(backList[index]))\n return\n }\n var forwardList = backForwardList.forwardList()\n if (forwardList.count() > index - backListLength) {\n webview.loadRequest(\n NSURLRequest.requestWithURL(forwardList[index - backListLength])\n )\n return\n }\n throw new Error('Cannot go to index ' + index)\n }\n webContents.goToOffset = function(offset) {\n if (!webContents.canGoToOffset(offset)) {\n throw new Error('Cannot go to offset ' + offset)\n }\n webview.loadRequest(\n NSURLRequest.requestWithURL(webview.backForwardList().itemAtIndex(offset))\n )\n }\n webContents.isCrashed = function() {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.setUserAgent = function(/* userAgent */) {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.getUserAgent = function() {\n const userAgent = webview.customUserAgent()\n return userAgent ? String(userAgent) : undefined\n }\n webContents.insertCSS = function(css) {\n var source =\n \"var style = document.createElement('style'); style.innerHTML = \" +\n css.replace(/\"/, '\\\\\"') +\n '; document.head.appendChild(style);'\n var script = WKUserScript.alloc().initWithSource_injectionTime_forMainFrameOnly(\n source,\n 0,\n true\n )\n webview\n .configuration()\n .userContentController()\n .addUserScript(script)\n }\n webContents.insertJS = function(source) {\n var script = WKUserScript.alloc().initWithSource_injectionTime_forMainFrameOnly(\n source,\n 0,\n true\n )\n webview\n .configuration()\n .userContentController()\n .addUserScript(script)\n }\n webContents.executeJavaScript = function(script, userGesture, callback) {\n if (typeof userGesture === 'function') {\n callback = userGesture\n userGesture = false\n }\n var fiber = coscript.createFiber()\n return new Promise(function(resolve, reject) {\n webview.evaluateJavaScript_completionHandler(\n script,\n __mocha__.createBlock_function('v28@?0@8c16@\"NSError\"20', function(\n result,\n err\n ) {\n var isError =\n err &&\n err.class &&\n (String(err.class()) === 'NSException' ||\n String(err.class()) === 'NSError')\n if (callback) {\n try {\n callback(isError ? err : null, result)\n } catch (error) {\n // /shrug\n }\n resolve()\n } else if (isError) {\n reject(err)\n } else {\n resolve(result)\n }\n fiber.cleanup()\n })\n )\n })\n }\n webContents.setIgnoreMenuShortcuts = function() {\n // TODO:??\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.setAudioMuted = function(/* muted */) {\n // TODO:??\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.isAudioMuted = function() {\n // TODO:??\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.setZoomFactor = function(factor) {\n webview.setMagnification_centeredAtPoint(factor, CGPointMake(0, 0))\n }\n webContents.getZoomFactor = function(callback) {\n callback(Number(webview.magnification()))\n }\n webContents.setZoomLevel = function(level) {\n // eslint-disable-next-line no-restricted-properties\n webContents.setZoomFactor(Math.pow(1.2, level))\n }\n webContents.getZoomLevel = function(callback) {\n // eslint-disable-next-line no-restricted-properties\n callback(Math.log(Number(webview.magnification())) / Math.log(1.2))\n }\n webContents.setVisualZoomLevelLimits = function(/* minimumLevel, maximumLevel */) {\n // TODO:??\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.setLayoutZoomLevelLimits = function(/* minimumLevel, maximumLevel */) {\n // TODO:??\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n\n // TODO:\n // webContents.undo = function() {\n // webview.undoManager().undo()\n // }\n // webContents.redo = function() {\n // webview.undoManager().redo()\n // }\n // webContents.cut = webview.cut\n // webContents.copy = webview.copy\n // webContents.paste = webview.paste\n // webContents.pasteAndMatchStyle = webview.pasteAsRichText\n // webContents.delete = webview.delete\n // webContents.replace = webview.replaceSelectionWithText\n\n webContents.send = function() {\n const script =\n 'window.postMessage({' +\n 'isSketchMessage: true,' +\n \"origin: '\" +\n String(__command.identifier()) +\n \"',\" +\n 'args: ' +\n JSON.stringify([].slice.call(arguments)) +\n '}, \"*\")'\n webview.evaluateJavaScript_completionHandler(script, null)\n }\n\n webContents.getNativeWebview = function() {\n return webview\n }\n\n browserWindow.webContents = webContents\n}\n","import BrowserWindow from 'sketch-module-web-view'\nimport {GradientMaker} from './gradient'\n\nexport default function () {\n \n //Global Setup\n const options = {\n backgroundColor: '#FFFFFF',\n identifier: 'coolhue.id',\n width: 215,\n height: 450,\n resizable: false,\n movable: true,\n alwaysOnTop: true,\n minimizable: true,\n maximizable: false,\n title: \"CoolHue 2.0\",\n vibrancy: \"appearance-based\",\n }\n\n const browserWindow = new BrowserWindow(options)\n browserWindow.isAlwaysOnTop()\n browserWindow.loadURL(require('./view.html'))\n browserWindow.webContents.on('nativeGradientApplier', function (fetchedData) {\n GradientMaker(fetchedData.firstColor,fetchedData.secondColor);\n })\n}","import sketch from 'sketch'\nimport UI from 'sketch/ui'\nvar Style = require('sketch/dom').Style\n\nexport function GradientMaker(firstStop, secondStop) {\n var doc = sketch.getSelectedDocument()\n var selectedLayers = doc.selectedLayers\n if (selectedLayers.length != null && selectedLayers.length != 0) {\n selectedLayers.forEach(layer => {\n if (layer.type === \"Shape\" || layer.type === \"ShapePath\") {\n var layerFrame = layer.frame;\n layer.style.fills = [{\n fillType: Style.FillType.Gradient,\n gradient: {\n gradientType: Style.GradientType.Linear,\n from: {\n x: -.01,\n y: 0,\n },\n to: {\n x: 1,\n y: 1,\n },\n stops: [{\n position: 0,\n color: firstStop,\n },\n {\n position: 1,\n color: secondStop,\n },\n ],\n },\n }, ]\n } else {\n UI.message(`🔔 CoolHue can apply gradients on Shape Layer(s) only`)\n }\n })\n } else {\n UI.message(`🛑 Select Shape Layer(s) to apply CoolHue Gradients`)\n }\n}","module.exports = \"file://\" + context.plugin.urlForResourceNamed(\"_webpack_resources/f26f00243c3832631637c6f76c717088.html\").path();","module.exports = require(\"events\");","module.exports = require(\"sketch\");","module.exports = require(\"sketch/dom\");","module.exports = require(\"sketch/ui\");"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://exports/webpack/bootstrap","webpack://exports/./node_modules/@skpm/timers/immediate.js","webpack://exports/./node_modules/@skpm/timers/test-if-fiber.js","webpack://exports/./node_modules/@skpm/timers/timeout.js","webpack://exports/./node_modules/cocoascript-class/lib/index.js","webpack://exports/./node_modules/cocoascript-class/lib/runtime.js","webpack://exports/./node_modules/promise-polyfill/lib/index.js","webpack://exports/./node_modules/sketch-module-web-view/lib/browser-api.js","webpack://exports/./node_modules/sketch-module-web-view/lib/constants.js","webpack://exports/./node_modules/sketch-module-web-view/lib/dispatch-first-click.js","webpack://exports/./node_modules/sketch-module-web-view/lib/fitSubview.js","webpack://exports/./node_modules/sketch-module-web-view/lib/index.js","webpack://exports/./node_modules/sketch-module-web-view/lib/inject-client-messaging.js","webpack://exports/./node_modules/sketch-module-web-view/lib/parseWebArguments.js","webpack://exports/./node_modules/sketch-module-web-view/lib/set-delegates.js","webpack://exports/./node_modules/sketch-module-web-view/lib/webview-api.js","webpack://exports/./src/coolhue.js","webpack://exports/./src/gradient.js","webpack://exports/./src/view.html","webpack://exports/external \"events\"","webpack://exports/external \"sketch\"","webpack://exports/external \"sketch/dom\"","webpack://exports/external \"sketch/ui\""],"names":["options","backgroundColor","identifier","width","height","resizable","movable","alwaysOnTop","minimizable","maximizable","title","vibrancy","browserWindow","BrowserWindow","isAlwaysOnTop","loadURL","require","webContents","on","fetchedData","GradientMaker","firstColor","secondColor","Style","firstStop","secondStop","doc","sketch","getSelectedDocument","selectedLayers","length","forEach","layer","type","style","fills","fillType","FillType","Gradient","fill","gradient","gradientType","GradientType","Linear","from","x","y","to","stops","position","color","UI","message"],"mappings":";;;;;;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;AClFA;AACA,cAAc,mBAAO,CAAC,yDAAW;;AAEjC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;ACdA;AACA;AACA;;;;;;;;;;;;ACFA;AACA,qBAAqB,mBAAO,CAAC,qEAAiB;;AAE9C;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,yCAAyC,cAAc,IAAI;AAC3D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;AC1Da;;AAEb;AACA;AACA,CAAC;AACD;AACA;;AAEA,eAAe,mBAAO,CAAC,qEAAc;;AAErC;;AAEA;AACA;;AAEA,6EAA6E,YAAY;;AAEzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;AACL;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA,C;;;;;;;;;;;;AC7Da;;AAEb;AACA;AACA,CAAC;AACD;AACA;AACA,kCAAkC,qCAAqC;;AAEvE;AACA;AACA,4CAA4C,sCAAsC,GAAG,YAAY;AACjG;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA,iEAAiE;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ,YAAY,WAAW;AACnD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA,8GAA8G,YAAY,GAAG,YAAY,GAAG,aAAa,IAAI,UAAU,WAAW,GAAG;AACrL;AACA,8GAA8G,YAAY,GAAG,YAAY,GAAG,YAAY,IAAI,UAAU,WAAW,GAAG;;AAEpL;AACA,wCAAwC,gCAAgC,E;;;;;;;;;;;;ACvGxE,gEAAa;;AAEb;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB;AACA,aAAa,kBAAkB;AAC/B;AACA,aAAa,kBAAkB;AAC/B;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA,+CAA+C,SAAS;AACxD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA,mBAAmB,iBAAiB;AACpC;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA,wCAAwC,SAAS;AACjD;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA,+DAA+D;AAC/D;AACA;;AAEA;;;;;;;;;;;;;AClQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB;AACrB;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB;AACrB;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AChmBA;AACA;AACA;;;;;;;;;;;;ACFA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,QAAQ;AACR,gBAAgB;AAChB,MAAM,eAAe;AACrB,0CAA0C,cAAc;AACxD,MAAM;AACN;AACA;;;;;;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrBA;AACA;AACA,mBAAmB,mBAAO,CAAC,sBAAQ;AACnC,sBAAsB,mBAAO,CAAC,+EAAe;AAC7C,kBAAkB,mBAAO,CAAC,+EAAe;AACzC,uBAAuB,mBAAO,CAAC,6EAAc;AAC7C,yBAAyB,mBAAO,CAAC,iGAAwB;AACzD,4BAA4B,mBAAO,CAAC,uGAA2B;AAC/D,mBAAmB,mBAAO,CAAC,mFAAiB;;AAE5C;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,KAAK;AACL;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;;;;;;;;;;ACnUA,gBAAgB,mBAAO,CAAC,2EAAa;;AAErC;AACA;AACA,qDAAqD;AACrD,gDAAgD;AAChD,uBAAuB;AACvB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,OAAO;AACP,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;AClBA,gBAAgB,mBAAO,CAAC,wEAAmB;AAC3C,wBAAwB,mBAAO,CAAC,2FAAqB;AACrD,gBAAgB,mBAAO,CAAC,2EAAa;;AAErC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;AACP,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA,2CAA2C;AAC3C,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO;AACP,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;;;;;;ACtQA,kEAAmB,mBAAO,CAAC,sBAAQ;;AAEnC;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA,QAAQ,kCAAkC;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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","file":"coolhue.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/coolhue.js\");\n","/* globals coscript, sketch */\nvar timeout = require('./timeout')\n\nfunction setImmediate(func, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) {\n return timeout.setTimeout(func, 0, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10)\n}\n\nfunction clearImmediate(id) {\n return timeout.clearTimeout(id)\n}\n\nmodule.exports = {\n setImmediate: setImmediate,\n clearImmediate: clearImmediate\n}\n","module.exports = function () {\n return typeof coscript !== 'undefined' && coscript.createFiber\n}\n","/* globals coscript, sketch */\nvar fiberAvailable = require('./test-if-fiber')\n\nvar setTimeout\nvar clearTimeout\n\nvar fibers = []\n\nif (fiberAvailable()) {\n var fibers = []\n\n setTimeout = function (func, delay, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) {\n // fibers takes care of keeping coscript around\n var id = fibers.length\n fibers.push(coscript.scheduleWithInterval_jsFunction(\n (delay || 0) / 1000,\n function () {\n func(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10)\n }\n ))\n return id\n }\n\n clearTimeout = function (id) {\n var timeout = fibers[id]\n if (timeout) {\n timeout.cancel() // fibers takes care of keeping coscript around\n fibers[id] = undefined // garbage collect the fiber\n }\n }\n} else {\n setTimeout = function (func, delay, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) {\n coscript.shouldKeepAround = true\n var id = fibers.length\n fibers.push(true)\n coscript.scheduleWithInterval_jsFunction(\n (delay || 0) / 1000,\n function () {\n if (fibers[id]) { // if not cleared\n func(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10)\n }\n clearTimeout(id)\n if (fibers.every(function (_id) { return !_id })) { // if everything is cleared\n coscript.shouldKeepAround = false\n }\n }\n )\n return id\n }\n\n clearTimeout = function (id) {\n fibers[id] = false\n }\n}\n\nmodule.exports = {\n setTimeout: setTimeout,\n clearTimeout: clearTimeout\n}\n","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.SuperCall = undefined;\nexports.default = ObjCClass;\n\nvar _runtime = require(\"./runtime.js\");\n\nexports.SuperCall = _runtime.SuperCall;\n\n// super when returnType is id and args are void\n// id objc_msgSendSuper(struct objc_super *super, SEL op, void)\n\nconst SuperInit = (0, _runtime.SuperCall)(NSStringFromSelector(\"init\"), [], { type: \"@\" });\n\n// Returns a real ObjC class. No need to use new.\nfunction ObjCClass(defn) {\n const superclass = defn.superclass || NSObject;\n const className = (defn.className || defn.classname || \"ObjCClass\") + NSUUID.UUID().UUIDString();\n const reserved = new Set(['className', 'classname', 'superclass']);\n var cls = MOClassDescription.allocateDescriptionForClassWithName_superclass_(className, superclass);\n // Add each handler to the class description\n const ivars = [];\n for (var key in defn) {\n const v = defn[key];\n if (typeof v == 'function' && key !== 'init') {\n var selector = NSSelectorFromString(key);\n cls.addInstanceMethodWithSelector_function_(selector, v);\n } else if (!reserved.has(key)) {\n ivars.push(key);\n cls.addInstanceVariableWithName_typeEncoding(key, \"@\");\n }\n }\n\n cls.addInstanceMethodWithSelector_function_(NSSelectorFromString('init'), function () {\n const self = SuperInit.call(this);\n ivars.map(name => {\n Object.defineProperty(self, name, {\n get() {\n return getIvar(self, name);\n },\n set(v) {\n (0, _runtime.object_setInstanceVariable)(self, name, v);\n }\n });\n self[name] = defn[name];\n });\n // If there is a passsed-in init funciton, call it now.\n if (typeof defn.init == 'function') defn.init.call(this);\n return self;\n });\n\n return cls.registerClass();\n};\n\nfunction getIvar(obj, name) {\n const retPtr = MOPointer.new();\n (0, _runtime.object_getInstanceVariable)(obj, name, retPtr);\n return retPtr.value().retain().autorelease();\n}","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.SuperCall = SuperCall;\nexports.CFunc = CFunc;\nconst objc_super_typeEncoding = '{objc_super=\"receiver\"@\"super_class\"#}';\n\n// You can store this to call your function. this must be bound to the current instance.\nfunction SuperCall(selector, argTypes, returnType) {\n const func = CFunc(\"objc_msgSendSuper\", [{ type: '^' + objc_super_typeEncoding }, { type: \":\" }, ...argTypes], returnType);\n return function (...args) {\n const struct = make_objc_super(this, this.superclass());\n const structPtr = MOPointer.alloc().initWithValue_(struct);\n return func(structPtr, selector, ...args);\n };\n}\n\n// Recursively create a MOStruct\nfunction makeStruct(def) {\n if (typeof def !== 'object' || Object.keys(def).length == 0) {\n return def;\n }\n const name = Object.keys(def)[0];\n const values = def[name];\n\n const structure = MOStruct.structureWithName_memberNames_runtime(name, Object.keys(values), Mocha.sharedRuntime());\n\n Object.keys(values).map(member => {\n structure[member] = makeStruct(values[member]);\n });\n\n return structure;\n}\n\nfunction make_objc_super(self, cls) {\n return makeStruct({\n objc_super: {\n receiver: self,\n super_class: cls\n }\n });\n}\n\n// Due to particularities of the JS bridge, we can't call into MOBridgeSupport objects directly\n// But, we can ask key value coding to do the dirty work for us ;)\nfunction setKeys(o, d) {\n const funcDict = NSMutableDictionary.dictionary();\n funcDict.o = o;\n Object.keys(d).map(k => funcDict.setValue_forKeyPath(d[k], \"o.\" + k));\n}\n\n// Use any C function, not just ones with BridgeSupport\nfunction CFunc(name, args, retVal) {\n function makeArgument(a) {\n if (!a) return null;\n const arg = MOBridgeSupportArgument.alloc().init();\n setKeys(arg, {\n type64: a.type\n });\n return arg;\n }\n const func = MOBridgeSupportFunction.alloc().init();\n setKeys(func, {\n name: name,\n arguments: args.map(makeArgument),\n returnValue: makeArgument(retVal)\n });\n return func;\n}\n\n/*\n@encode(char*) = \"*\"\n@encode(id) = \"@\"\n@encode(Class) = \"#\"\n@encode(void*) = \"^v\"\n@encode(CGRect) = \"{CGRect={CGPoint=dd}{CGSize=dd}}\"\n@encode(SEL) = \":\"\n*/\n\nfunction addStructToBridgeSupport(key, structDef) {\n // OK, so this is probably the nastiest hack in this file.\n // We go modify MOBridgeSupportController behind its back and use kvc to add our own definition\n // There isn't another API for this though. So the only other way would be to make a real bridgesupport file.\n const symbols = MOBridgeSupportController.sharedController().valueForKey('symbols');\n if (!symbols) throw Error(\"Something has changed within bridge support so we can't add our definitions\");\n // If someone already added this definition, don't re-register it.\n if (symbols[key] !== null) return;\n const def = MOBridgeSupportStruct.alloc().init();\n setKeys(def, {\n name: key,\n type: structDef.type\n });\n symbols[key] = def;\n};\n\n// This assumes the ivar is an object type. Return value is pretty useless.\nconst object_getInstanceVariable = exports.object_getInstanceVariable = CFunc(\"object_getInstanceVariable\", [{ type: \"@\" }, { type: '*' }, { type: \"^@\" }], { type: \"^{objc_ivar=}\" });\n// Again, ivar is of object type\nconst object_setInstanceVariable = exports.object_setInstanceVariable = CFunc(\"object_setInstanceVariable\", [{ type: \"@\" }, { type: '*' }, { type: \"@\" }], { type: \"^{objc_ivar=}\" });\n\n// We need Mocha to understand what an objc_super is so we can use it as a function argument\naddStructToBridgeSupport('objc_super', { type: objc_super_typeEncoding });","'use strict';\n\n/**\n * @this {Promise}\n */\nfunction finallyConstructor(callback) {\n var constructor = this.constructor;\n return this.then(\n function(value) {\n return constructor.resolve(callback()).then(function() {\n return value;\n });\n },\n function(reason) {\n return constructor.resolve(callback()).then(function() {\n return constructor.reject(reason);\n });\n }\n );\n}\n\n// Store setTimeout reference so promise-polyfill will be unaffected by\n// other code modifying setTimeout (like sinon.useFakeTimers())\nvar setTimeoutFunc = setTimeout;\n\nfunction noop() {}\n\n// Polyfill for Function.prototype.bind\nfunction bind(fn, thisArg) {\n return function() {\n fn.apply(thisArg, arguments);\n };\n}\n\n/**\n * @constructor\n * @param {Function} fn\n */\nfunction Promise(fn) {\n if (!(this instanceof Promise))\n throw new TypeError('Promises must be constructed via new');\n if (typeof fn !== 'function') throw new TypeError('not a function');\n /** @type {!number} */\n this._state = 0;\n /** @type {!boolean} */\n this._handled = false;\n /** @type {Promise|undefined} */\n this._value = undefined;\n /** @type {!Array} */\n this._deferreds = [];\n\n doResolve(fn, this);\n}\n\nfunction handle(self, deferred) {\n while (self._state === 3) {\n self = self._value;\n }\n if (self._state === 0) {\n self._deferreds.push(deferred);\n return;\n }\n self._handled = true;\n Promise._immediateFn(function() {\n var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;\n if (cb === null) {\n (self._state === 1 ? resolve : reject)(deferred.promise, self._value);\n return;\n }\n var ret;\n try {\n ret = cb(self._value);\n } catch (e) {\n reject(deferred.promise, e);\n return;\n }\n resolve(deferred.promise, ret);\n });\n}\n\nfunction resolve(self, newValue) {\n try {\n // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure\n if (newValue === self)\n throw new TypeError('A promise cannot be resolved with itself.');\n if (\n newValue &&\n (typeof newValue === 'object' || typeof newValue === 'function')\n ) {\n var then = newValue.then;\n if (newValue instanceof Promise) {\n self._state = 3;\n self._value = newValue;\n finale(self);\n return;\n } else if (typeof then === 'function') {\n doResolve(bind(then, newValue), self);\n return;\n }\n }\n self._state = 1;\n self._value = newValue;\n finale(self);\n } catch (e) {\n reject(self, e);\n }\n}\n\nfunction reject(self, newValue) {\n self._state = 2;\n self._value = newValue;\n finale(self);\n}\n\nfunction finale(self) {\n if (self._state === 2 && self._deferreds.length === 0) {\n Promise._immediateFn(function() {\n if (!self._handled) {\n Promise._unhandledRejectionFn(self._value);\n }\n });\n }\n\n for (var i = 0, len = self._deferreds.length; i < len; i++) {\n handle(self, self._deferreds[i]);\n }\n self._deferreds = null;\n}\n\n/**\n * @constructor\n */\nfunction Handler(onFulfilled, onRejected, promise) {\n this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n this.promise = promise;\n}\n\n/**\n * Take a potentially misbehaving resolver function and make sure\n * onFulfilled and onRejected are only called once.\n *\n * Makes no guarantees about asynchrony.\n */\nfunction doResolve(fn, self) {\n var done = false;\n try {\n fn(\n function(value) {\n if (done) return;\n done = true;\n resolve(self, value);\n },\n function(reason) {\n if (done) return;\n done = true;\n reject(self, reason);\n }\n );\n } catch (ex) {\n if (done) return;\n done = true;\n reject(self, ex);\n }\n}\n\nPromise.prototype['catch'] = function(onRejected) {\n return this.then(null, onRejected);\n};\n\nPromise.prototype.then = function(onFulfilled, onRejected) {\n // @ts-ignore\n var prom = new this.constructor(noop);\n\n handle(this, new Handler(onFulfilled, onRejected, prom));\n return prom;\n};\n\nPromise.prototype['finally'] = finallyConstructor;\n\nPromise.all = function(arr) {\n return new Promise(function(resolve, reject) {\n if (!arr || typeof arr.length === 'undefined')\n throw new TypeError('Promise.all accepts an array');\n var args = Array.prototype.slice.call(arr);\n if (args.length === 0) return resolve([]);\n var remaining = args.length;\n\n function res(i, val) {\n try {\n if (val && (typeof val === 'object' || typeof val === 'function')) {\n var then = val.then;\n if (typeof then === 'function') {\n then.call(\n val,\n function(val) {\n res(i, val);\n },\n reject\n );\n return;\n }\n }\n args[i] = val;\n if (--remaining === 0) {\n resolve(args);\n }\n } catch (ex) {\n reject(ex);\n }\n }\n\n for (var i = 0; i < args.length; i++) {\n res(i, args[i]);\n }\n });\n};\n\nPromise.resolve = function(value) {\n if (value && typeof value === 'object' && value.constructor === Promise) {\n return value;\n }\n\n return new Promise(function(resolve) {\n resolve(value);\n });\n};\n\nPromise.reject = function(value) {\n return new Promise(function(resolve, reject) {\n reject(value);\n });\n};\n\nPromise.race = function(values) {\n return new Promise(function(resolve, reject) {\n for (var i = 0, len = values.length; i < len; i++) {\n values[i].then(resolve, reject);\n }\n });\n};\n\n// Use polyfill for setImmediate for performance gains\nPromise._immediateFn =\n (typeof setImmediate === 'function' &&\n function(fn) {\n setImmediate(fn);\n }) ||\n function(fn) {\n setTimeoutFunc(fn, 0);\n };\n\nPromise._unhandledRejectionFn = function _unhandledRejectionFn(err) {\n if (typeof console !== 'undefined' && console) {\n console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console\n }\n};\n\nmodule.exports = Promise;\n","var COLOR_CLASSES = [\n 'NSColor',\n 'NSCachedWhiteColor',\n 'NSColorSpaceColor',\n 'NSDynamicSystemColor',\n 'NSCachedColorSpaceColor',\n]\nfunction parseHexColor(color) {\n // Check the string for incorrect formatting.\n if (!color || color[0] !== '#') {\n if (\n color &&\n color.class &&\n COLOR_CLASSES.indexOf(String(color.class())) !== -1\n ) {\n return color\n }\n throw new Error(\n 'Incorrect color formating. It should be an hex color: #RRGGBBAA'\n )\n }\n\n // append FF if alpha channel is not specified.\n var source = color.substr(1)\n if (source.length === 3) {\n source += 'F'\n } else if (source.length === 6) {\n source += 'FF'\n }\n // Convert the string from #FFF format to #FFFFFF format.\n var hex\n if (source.length === 4) {\n for (var i = 0; i < 4; i += 1) {\n hex += source[i]\n hex += source[i]\n }\n } else if (source.length === 8) {\n hex = source\n } else {\n return NSColor.whiteColor()\n }\n\n var r = parseInt(hex.slice(0, 2), 16)\n var g = parseInt(hex.slice(2, 4), 16)\n var b = parseInt(hex.slice(4, 6), 16)\n var a = parseInt(hex.slice(6, 8), 16)\n\n return NSColor.colorWithSRGBRed_green_blue_alpha(r, g, b, a)\n}\n\nmodule.exports = function(browserWindow, panel, webview) {\n // keep reference to the subviews\n browserWindow._panel = panel\n browserWindow._webview = webview\n browserWindow._destroyed = false\n\n browserWindow.destroy = function() {\n return panel.close()\n }\n\n browserWindow.close = function() {\n if (panel.delegate().utils.parentWindow) {\n var shouldClose = true\n browserWindow.emit('close', {\n get defaultPrevented() {\n return !shouldClose\n },\n preventDefault: function() {\n shouldClose = false\n },\n })\n if (shouldClose) {\n panel.delegate().utils.parentWindow.endSheet(panel)\n }\n return\n }\n\n if (!browserWindow.isClosable()) {\n return\n }\n\n panel.performClose(null)\n }\n\n function focus(focused) {\n if (browserWindow.isVisible()) {\n return\n }\n if (focused) {\n NSApplication.sharedApplication().activateIgnoringOtherApps(true)\n panel.makeKeyAndOrderFront(null)\n } else {\n panel.orderBack(null)\n }\n }\n\n browserWindow.focus = focus.bind(this, true)\n browserWindow.blur = focus.bind(this, false)\n\n browserWindow.isFocused = function() {\n return panel.isKeyWindow()\n }\n\n browserWindow.isDestroyed = function() {\n return browserWindow._destroyed\n }\n\n browserWindow.show = function() {\n // This method is supposed to put focus on window, however if the app does not\n // have focus then \"makeKeyAndOrderFront\" will only show the window.\n NSApp.activateIgnoringOtherApps(true)\n\n if (panel.delegate().utils.parentWindow) {\n return panel.delegate().utils.parentWindow.beginSheet_completionHandler(\n panel,\n __mocha__.createBlock_function('v16@?0q8', function() {\n browserWindow.emit('closed')\n })\n )\n }\n\n return panel.makeKeyAndOrderFront(null)\n }\n\n browserWindow.showInactive = function() {\n return panel.orderFrontRegardless()\n }\n\n browserWindow.hide = function() {\n return panel.orderOut(null)\n }\n\n browserWindow.isVisible = function() {\n return panel.isVisible()\n }\n\n browserWindow.isModal = function() {\n return false\n }\n\n browserWindow.maximize = function() {\n if (!browserWindow.isMaximized()) {\n panel.zoom(null)\n }\n }\n browserWindow.unmaximize = function() {\n if (browserWindow.isMaximized()) {\n panel.zoom(null)\n }\n }\n\n browserWindow.isMaximized = function() {\n if ((panel.styleMask() & NSResizableWindowMask) !== 0) {\n return panel.isZoomed()\n }\n var rectScreen = NSScreen.mainScreen().visibleFrame()\n var rectWindow = panel.frame()\n return (\n rectScreen.origin.x == rectWindow.origin.x &&\n rectScreen.origin.y == rectWindow.origin.y &&\n rectScreen.size.width == rectWindow.size.width &&\n rectScreen.size.height == rectWindow.size.height\n )\n }\n\n browserWindow.minimize = function() {\n return panel.miniaturize(null)\n }\n\n browserWindow.restore = function() {\n return panel.deminiaturize(null)\n }\n\n browserWindow.isMinimized = function() {\n return panel.isMiniaturized()\n }\n\n browserWindow.setFullScreen = function(fullscreen) {\n if (fullscreen !== browserWindow.isFullscreen()) {\n panel.toggleFullScreen(null)\n }\n }\n\n browserWindow.isFullscreen = function() {\n return panel.styleMask() & NSFullScreenWindowMask\n }\n\n browserWindow.setAspectRatio = function(aspectRatio /* , extraSize */) {\n // Reset the behaviour to default if aspect_ratio is set to 0 or less.\n if (aspectRatio > 0.0) {\n panel.setAspectRatio(NSMakeSize(aspectRatio, 1.0))\n } else {\n panel.setResizeIncrements(NSMakeSize(1.0, 1.0))\n }\n }\n\n browserWindow.setBounds = function(bounds, animate) {\n // Do nothing if in fullscreen mode.\n if (browserWindow.isFullscreen()) {\n return\n }\n\n // TODO: Check size constraints since setFrame does not check it.\n var size = bounds.size\n // size.SetToMax(GetMinimumSize());\n // gfx::Size max_size = GetMaximumSize();\n // if (!max_size.IsEmpty())\n // size.SetToMin(max_size);\n\n var cocoaBounds = NSMakeRect(bounds.origin.x, 0, size.width, size.height)\n // Flip coordinates based on the primary screen.\n var screen = NSScreen.screens().firstObject()\n cocoaBounds.origin.y =\n NSHeight(screen.frame()) - size.height - bounds.origin.y\n\n panel.setFrame_display_animate(cocoaBounds, true, animate)\n }\n\n browserWindow.getBounds = function() {\n return panel.frame()\n }\n\n browserWindow.setContentBounds = function(/* bounds, animate */) {\n // TODO:\n }\n\n browserWindow.getContentBounds = function() {\n // TODO:\n }\n\n browserWindow.setSize = function(width, height, animate) {\n var bounds = browserWindow.getBounds()\n bounds.size.height = height\n bounds.size.width = width\n\n // TODO: handle resizing around center\n\n return browserWindow.setBounds(bounds, animate)\n }\n\n browserWindow.getSize = function() {\n var bounds = browserWindow.getBounds()\n return [bounds.size.width, bounds.size.height]\n }\n\n browserWindow.setContentSize = function(width, height, animate) {\n var bounds = browserWindow.getContentBounds()\n bounds.size.height = height\n bounds.size.width = width\n\n // TODO: handle resizing around center\n\n return browserWindow.setContentBounds(bounds, animate)\n }\n\n browserWindow.getContentSize = function() {\n var bounds = browserWindow.getContentBounds()\n return [bounds.size.width, bounds.size.height]\n }\n\n browserWindow.setMinimumSize = function(width, height) {\n const minSize = { width: width, height: height }\n panel.setContentMinSize(minSize)\n }\n\n browserWindow.getMinimumSize = function() {\n const size = panel.contentMinSize()\n return [size.width, size.height]\n }\n\n browserWindow.setMaximumSize = function(width, height) {\n const minSize = { width: width, height: height }\n panel.setContentMaxSize(minSize)\n }\n\n browserWindow.getMaximumSize = function() {\n const size = panel.contentMaxSize()\n return [size.width, size.height]\n }\n\n browserWindow.setResizable = function(resizable) {\n return browserWindow._setStyleMask(resizable, NSResizableWindowMask)\n }\n\n browserWindow.isResizable = function() {\n return panel.styleMask() & NSResizableWindowMask\n }\n\n browserWindow.setMovable = function(movable) {\n return panel.setMovable(movable)\n }\n browserWindow.isMovable = function() {\n return panel.isMovable()\n }\n\n browserWindow.setMinimizable = function(minimizable) {\n return browserWindow._setStyleMask(minimizable, NSMiniaturizableWindowMask)\n }\n\n browserWindow.isMinimizable = function() {\n return panel.styleMask() & NSMiniaturizableWindowMask\n }\n\n browserWindow.setMaximizable = function(maximizable) {\n if (panel.standardWindowButton(NSWindowZoomButton)) {\n panel.standardWindowButton(NSWindowZoomButton).setEnabled(maximizable)\n }\n }\n\n browserWindow.isMaximizable = function() {\n return (\n panel.standardWindowButton(NSWindowZoomButton) &&\n panel.standardWindowButton(NSWindowZoomButton).isEnabled()\n )\n }\n\n browserWindow.setFullScreenable = function(fullscreenable) {\n browserWindow._setCollectionBehavior(\n fullscreenable,\n NSWindowCollectionBehaviorFullScreenPrimary\n )\n // On EL Capitan this flag is required to hide fullscreen button.\n browserWindow._setCollectionBehavior(\n !fullscreenable,\n NSWindowCollectionBehaviorFullScreenAuxiliary\n )\n }\n\n browserWindow.isFullScreenable = function() {\n var collectionBehavior = panel.collectionBehavior()\n return collectionBehavior & NSWindowCollectionBehaviorFullScreenPrimary\n }\n\n browserWindow.setClosable = function(closable) {\n browserWindow._setStyleMask(closable, NSClosableWindowMask)\n }\n\n browserWindow.isClosable = function() {\n return panel.styleMask() & NSClosableWindowMask\n }\n\n browserWindow.setAlwaysOnTop = function(top, level, relativeLevel) {\n var windowLevel = NSNormalWindowLevel\n var maxWindowLevel = CGWindowLevelForKey(kCGMaximumWindowLevelKey)\n var minWindowLevel = CGWindowLevelForKey(kCGMinimumWindowLevelKey)\n\n if (top) {\n if (level === 'normal') {\n windowLevel = NSNormalWindowLevel\n } else if (level === 'torn-off-menu') {\n windowLevel = NSTornOffMenuWindowLevel\n } else if (level === 'modal-panel') {\n windowLevel = NSModalPanelWindowLevel\n } else if (level === 'main-menu') {\n windowLevel = NSMainMenuWindowLevel\n } else if (level === 'status') {\n windowLevel = NSStatusWindowLevel\n } else if (level === 'pop-up-menu') {\n windowLevel = NSPopUpMenuWindowLevel\n } else if (level === 'screen-saver') {\n windowLevel = NSScreenSaverWindowLevel\n } else if (level === 'dock') {\n // Deprecated by macOS, but kept for backwards compatibility\n windowLevel = NSDockWindowLevel\n } else {\n windowLevel = NSFloatingWindowLevel\n }\n }\n\n var newLevel = windowLevel + (relativeLevel || 0)\n if (newLevel >= minWindowLevel && newLevel <= maxWindowLevel) {\n panel.setLevel(newLevel)\n } else {\n throw new Error(\n 'relativeLevel must be between ' +\n minWindowLevel +\n ' and ' +\n maxWindowLevel\n )\n }\n }\n\n browserWindow.isAlwaysOnTop = function() {\n return panel.level() !== NSNormalWindowLevel\n }\n\n browserWindow.moveTop = function() {\n return panel.orderFrontRegardless()\n }\n\n browserWindow.center = function() {\n panel.center()\n }\n\n browserWindow.setPosition = function(x, y, animate) {\n var bounds = browserWindow.getBounds()\n var mainScreenRect = NSScreen.screens()\n .firstObject()\n .frame()\n bounds.origin.x = x\n bounds.origin.y = Math.round(NSHeight(mainScreenRect) - y)\n\n return browserWindow.setBounds(bounds, animate)\n }\n\n browserWindow.getPosition = function() {\n var bounds = browserWindow.getBounds()\n var mainScreenRect = NSScreen.screens()\n .firstObject()\n .frame()\n return [\n bounds.origin.x,\n Math.round(NSHeight(mainScreenRect) - bounds.origin.y),\n ]\n }\n\n browserWindow.setTitle = function(title) {\n panel.setTitle(title)\n }\n\n browserWindow.getTitle = function() {\n return String(panel.title())\n }\n\n var attentionRequestId = 0\n browserWindow.flashFrame = function(flash) {\n if (flash) {\n attentionRequestId = NSApp.requestUserAttention(NSInformationalRequest)\n } else {\n NSApp.cancelUserAttentionRequest(attentionRequestId)\n attentionRequestId = 0\n }\n }\n\n browserWindow.getNativeWindowHandle = function() {\n return panel\n }\n\n browserWindow.getNativeWebViewHandle = function() {\n return webview\n }\n\n browserWindow.loadURL = function(url) {\n // When frameLocation is a file, prefix it with the Sketch Resources path\n if (/^(?!http|localhost|www|file).*\\.html?$/.test(url)) {\n if (typeof __command !== 'undefined' && __command.pluginBundle()) {\n url =\n 'file://' +\n __command\n .pluginBundle()\n .urlForResourceNamed(url)\n .path()\n }\n }\n\n if (/^file:\\/\\/.*\\.html?$/.test(url)) {\n webview.loadFileURL_allowingReadAccessToURL(\n NSURL.fileURLWithPath(url),\n NSURL.fileURLWithPath('file:///')\n )\n return\n }\n\n webview.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(url)))\n }\n\n browserWindow.reload = function() {\n webview.reload()\n }\n\n browserWindow.setHasShadow = function(hasShadow) {\n return panel.setHasShadow(hasShadow)\n }\n\n browserWindow.hasShadow = function() {\n return panel.hasShadow()\n }\n\n browserWindow.setOpacity = function(opacity) {\n return panel.setAlphaValue(opacity)\n }\n\n browserWindow.getOpacity = function() {\n return panel.alphaValue()\n }\n\n browserWindow.setVisibleOnAllWorkspaces = function(visible) {\n return browserWindow._setCollectionBehavior(\n visible,\n NSWindowCollectionBehaviorCanJoinAllSpaces\n )\n }\n\n browserWindow.isVisibleOnAllWorkspaces = function() {\n var collectionBehavior = panel.collectionBehavior()\n return collectionBehavior & NSWindowCollectionBehaviorCanJoinAllSpaces\n }\n\n browserWindow.setIgnoreMouseEvents = function(ignore) {\n return panel.setIgnoresMouseEvents(ignore)\n }\n\n browserWindow.setContentProtection = function(enable) {\n panel.setSharingType(enable ? NSWindowSharingNone : NSWindowSharingReadOnly)\n }\n\n browserWindow.setAutoHideCursor = function(autoHide) {\n panel.setDisableAutoHideCursor(autoHide)\n }\n\n browserWindow.setVibrancy = function(type) {\n var effectView = browserWindow._vibrantView\n\n if (!type) {\n if (effectView == null) {\n return\n }\n\n effectView.removeFromSuperview()\n panel.setVibrantView(null)\n return\n }\n\n if (effectView == null) {\n var contentView = panel.contentView()\n effectView = NSVisualEffectView.alloc().initWithFrame(\n contentView.bounds()\n )\n browserWindow._vibrantView = effectView\n\n effectView.setAutoresizingMask(NSViewWidthSizable | NSViewHeightSizable)\n effectView.setBlendingMode(NSVisualEffectBlendingModeBehindWindow)\n effectView.setState(NSVisualEffectStateActive)\n effectView.setFrame(contentView.bounds())\n contentView.addSubview_positioned_relativeTo(\n effectView,\n NSWindowBelow,\n null\n )\n }\n\n var vibrancyType = NSVisualEffectMaterialLight\n\n if (type === 'appearance-based') {\n vibrancyType = NSVisualEffectMaterialAppearanceBased\n } else if (type === 'light') {\n vibrancyType = NSVisualEffectMaterialLight\n } else if (type === 'dark') {\n vibrancyType = NSVisualEffectMaterialDark\n } else if (type === 'titlebar') {\n vibrancyType = NSVisualEffectMaterialTitlebar\n } else if (type === 'selection') {\n vibrancyType = NSVisualEffectMaterialSelection\n } else if (type === 'menu') {\n vibrancyType = NSVisualEffectMaterialMenu\n } else if (type === 'popover') {\n vibrancyType = NSVisualEffectMaterialPopover\n } else if (type === 'sidebar') {\n vibrancyType = NSVisualEffectMaterialSidebar\n } else if (type === 'medium-light') {\n vibrancyType = NSVisualEffectMaterialMediumLight\n } else if (type === 'ultra-dark') {\n vibrancyType = NSVisualEffectMaterialUltraDark\n }\n\n effectView.setMaterial(vibrancyType)\n }\n\n browserWindow._setBackgroundColor = function(colorName) {\n var color = parseHexColor(colorName)\n webview.isOpaque = false\n webview.setBackgroundColor(NSColor.clearColor())\n panel.backgroundColor = color\n }\n\n browserWindow._invalidate = function() {\n panel.flushWindow()\n panel.contentView().setNeedsDisplay(true)\n }\n\n browserWindow._setStyleMask = function(on, flag) {\n var wasMaximizable = browserWindow.isMaximizable()\n if (on) {\n panel.setStyleMask(panel.styleMask() | flag)\n } else {\n panel.setStyleMask(panel.styleMask() & ~flag)\n }\n // Change style mask will make the zoom button revert to default, probably\n // a bug of Cocoa or macOS.\n browserWindow.setMaximizable(wasMaximizable)\n }\n\n browserWindow._setCollectionBehavior = function(on, flag) {\n var wasMaximizable = browserWindow.isMaximizable()\n if (on) {\n panel.setCollectionBehavior(panel.collectionBehavior() | flag)\n } else {\n panel.setCollectionBehavior(panel.collectionBehavior() & ~flag)\n }\n // Change collectionBehavior will make the zoom button revert to default,\n // probably a bug of Cocoa or macOS.\n browserWindow.setMaximizable(wasMaximizable)\n }\n\n browserWindow._showWindowButton = function(button) {\n var view = panel.standardWindowButton(button)\n view.superview().addSubview_positioned_relative(view, NSWindowAbove, null)\n }\n}\n","module.exports = {\n JS_BRIDGE: '__skpm_sketchBridge',\n}\n","var tagsToFocus =\n '[\"text\", \"textarea\", \"date\", \"datetime-local\", \"email\", \"number\", \"month\", \"password\", \"search\", \"tel\", \"time\", \"url\", \"week\" ]'\n\nmodule.exports = function(webView, event) {\n var point = webView.convertPoint_fromView(event.locationInWindow(), null)\n var x = point.x\n var y = webView.frame().size.height - point.y // the coord start from the bottom instead of the top\n return (\n 'var el = document.elementFromPoint(' + // get the DOM element that match the event\n x +\n ', ' +\n y +\n '); ' +\n 'if (el && ' + // some tags need to be focused instead of clicked\n tagsToFocus +\n '.indexOf(el.type) >= 0 && ' +\n 'el.focus' +\n ') {' +\n 'el.focus();' + // so focus them\n '} else if (el) {' +\n 'el.dispatchEvent(new Event(\"click\", {bubbles: true}))' + // click the others\n '}'\n )\n}\n","function addEdgeConstraint(edge, subview, view, constant) {\n view.addConstraint(\n NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant(\n subview,\n edge,\n NSLayoutRelationEqual,\n view,\n edge,\n 1,\n constant\n )\n )\n}\nmodule.exports = function fitSubviewToView(subview, view, constants) {\n constants = constants || []\n subview.setTranslatesAutoresizingMaskIntoConstraints(false)\n\n addEdgeConstraint(NSLayoutAttributeLeft, subview, view, constants[0] || 0)\n addEdgeConstraint(NSLayoutAttributeTop, subview, view, constants[1] || 0)\n addEdgeConstraint(NSLayoutAttributeRight, subview, view, constants[2] || 0)\n addEdgeConstraint(NSLayoutAttributeBottom, subview, view, constants[3] || 0)\n}\n","/* let's try to match the API from Electron's Browser window\n(https://github.com/electron/electron/blob/master/docs/api/browser-window.md) */\nvar EventEmitter = require('events')\nvar buildBrowserAPI = require('./browser-api')\nvar buildWebAPI = require('./webview-api')\nvar fitSubviewToView = require('./fitSubview')\nvar dispatchFirstClick = require('./dispatch-first-click')\nvar injectClientMessaging = require('./inject-client-messaging')\nvar setDelegates = require('./set-delegates')\n\nfunction BrowserWindow(options) {\n options = options || {}\n\n var identifier = options.identifier || NSUUID.UUID().UUIDString()\n var threadDictionary = NSThread.mainThread().threadDictionary()\n\n var existingBrowserWindow = BrowserWindow.fromId(identifier)\n\n // if we already have a window opened, reuse it\n if (existingBrowserWindow) {\n return existingBrowserWindow\n }\n\n var browserWindow = new EventEmitter()\n browserWindow.id = identifier\n\n if (options.modal && !options.parent) {\n throw new Error('A modal needs to have a parent.')\n }\n\n // Long-running script\n var fiber = coscript.createFiber()\n\n // Window size\n var width = options.width || 800\n var height = options.height || 600\n var mainScreenRect = NSScreen.screens()\n .firstObject()\n .frame()\n var cocoaBounds = NSMakeRect(\n typeof options.x !== 'undefined'\n ? options.x\n : Math.round((NSWidth(mainScreenRect) - width) / 2),\n typeof options.y !== 'undefined'\n ? options.y\n : Math.round((NSHeight(mainScreenRect) - height) / 2),\n width,\n height\n )\n\n if (options.titleBarStyle && options.titleBarStyle !== 'default') {\n options.frame = false\n }\n\n var useStandardWindow = options.windowType !== 'textured'\n var styleMask = NSTitledWindowMask\n\n // this is commented out because the toolbar doesn't appear otherwise :thinking-face:\n // if (!useStandardWindow || options.frame === false) {\n // styleMask = NSFullSizeContentViewWindowMask\n // }\n if (options.minimizable !== false) {\n styleMask |= NSMiniaturizableWindowMask\n }\n if (options.closable !== false) {\n styleMask |= NSClosableWindowMask\n }\n if (options.resizable !== false) {\n styleMask |= NSResizableWindowMask\n }\n if (!useStandardWindow || options.transparent || options.frame === false) {\n styleMask |= NSTexturedBackgroundWindowMask\n }\n\n var panel = NSPanel.alloc().initWithContentRect_styleMask_backing_defer(\n cocoaBounds,\n styleMask,\n NSBackingStoreBuffered,\n true\n )\n\n var wkwebviewConfig = WKWebViewConfiguration.alloc().init()\n var webView = WKWebView.alloc().initWithFrame_configuration(\n CGRectMake(0, 0, options.width || 800, options.height || 600),\n wkwebviewConfig\n )\n injectClientMessaging(webView)\n webView.setAutoresizingMask(NSViewWidthSizable | NSViewHeightSizable)\n\n buildBrowserAPI(browserWindow, panel, webView)\n buildWebAPI(browserWindow, panel, webView)\n setDelegates(browserWindow, panel, webView, options)\n\n if (options.windowType === 'desktop') {\n panel.setLevel(kCGDesktopWindowLevel - 1)\n // panel.setCanBecomeKeyWindow(false)\n panel.setCollectionBehavior(\n NSWindowCollectionBehaviorCanJoinAllSpaces |\n NSWindowCollectionBehaviorStationary |\n NSWindowCollectionBehaviorIgnoresCycle\n )\n }\n\n if (\n typeof options.minWidth !== 'undefined' ||\n typeof options.minHeight !== 'undefined'\n ) {\n browserWindow.setMinimumSize(options.minWidth || 0, options.minHeight || 0)\n }\n\n if (\n typeof options.maxWidth !== 'undefined' ||\n typeof options.maxHeight !== 'undefined'\n ) {\n browserWindow.setMaximumSize(\n options.maxWidth || 10000,\n options.maxHeight || 10000\n )\n }\n\n // if (options.focusable === false) {\n // panel.setCanBecomeKeyWindow(false)\n // }\n\n if (options.transparent || options.frame === false) {\n panel.titlebarAppearsTransparent = true\n panel.titleVisibility = NSWindowTitleHidden\n panel.setOpaque(0)\n panel.isMovableByWindowBackground = true\n var toolbar2 = NSToolbar.alloc().initWithIdentifier(\n 'titlebarStylingToolbar'\n )\n toolbar2.setShowsBaselineSeparator(false)\n panel.setToolbar(toolbar2)\n }\n\n if (options.titleBarStyle === 'hiddenInset') {\n var toolbar = NSToolbar.alloc().initWithIdentifier('titlebarStylingToolbar')\n toolbar.setShowsBaselineSeparator(false)\n panel.setToolbar(toolbar)\n }\n\n if (options.frame === false || !options.useContentSize) {\n browserWindow.setSize(width, height)\n }\n\n if (options.center) {\n browserWindow.center()\n }\n\n if (options.alwaysOnTop) {\n browserWindow.setAlwaysOnTop(true)\n }\n\n if (options.fullscreen) {\n browserWindow.setFullScreen(true)\n }\n browserWindow.setFullScreenable(!!options.fullscreenable)\n\n const title =\n options.title ||\n (typeof __command !== 'undefined' && __command.pluginBundle()\n ? __command.pluginBundle().name()\n : undefined)\n if (title) {\n browserWindow.setTitle(title)\n }\n\n var backgroundColor = options.backgroundColor\n if (options.transparent) {\n backgroundColor = NSColor.clearColor()\n }\n if (!backgroundColor && options.frame === false && options.vibrancy) {\n backgroundColor = NSColor.clearColor()\n }\n\n browserWindow._setBackgroundColor(\n backgroundColor || NSColor.windowBackgroundColor()\n )\n\n if (options.hasShadow === false) {\n browserWindow.setHasShadow(false)\n }\n\n if (typeof options.opacity !== 'undefined') {\n browserWindow.setOpacity(options.opacity)\n }\n\n options.webPreferences = options.webPreferences || {}\n\n webView\n .configuration()\n .preferences()\n .setValue_forKey(\n options.webPreferences.devTools !== false,\n 'developerExtrasEnabled'\n )\n webView\n .configuration()\n .preferences()\n .setValue_forKey(\n options.webPreferences.devTools !== false,\n 'javaScriptEnabled'\n )\n webView\n .configuration()\n .preferences()\n .setValue_forKey(!!options.webPreferences.plugins, 'plugInsEnabled')\n webView\n .configuration()\n .preferences()\n .setValue_forKey(\n options.webPreferences.minimumFontSize || 0,\n 'minimumFontSize'\n )\n\n if (options.webPreferences.zoomFactor) {\n webView.setMagnification(options.webPreferences.zoomFactor)\n }\n\n var contentView = panel.contentView()\n\n if (options.frame !== false) {\n webView.setFrame(contentView.bounds())\n contentView.addSubview(webView)\n } else {\n // In OSX 10.10, adding subviews to the root view for the NSView hierarchy\n // produces warnings. To eliminate the warnings, we resize the contentView\n // to fill the window, and add subviews to that.\n // http://crbug.com/380412\n contentView.setAutoresizingMask(NSViewWidthSizable | NSViewHeightSizable)\n fitSubviewToView(contentView, contentView.superview())\n\n webView.setFrame(contentView.bounds())\n contentView.addSubview(webView)\n\n // The fullscreen button should always be hidden for frameless window.\n if (panel.standardWindowButton(NSWindowFullScreenButton)) {\n panel.standardWindowButton(NSWindowFullScreenButton).setHidden(true)\n }\n\n if (!options.titleBarStyle || options.titleBarStyle === 'default') {\n // Hide the window buttons.\n panel.standardWindowButton(NSWindowZoomButton).setHidden(true)\n panel.standardWindowButton(NSWindowMiniaturizeButton).setHidden(true)\n panel.standardWindowButton(NSWindowCloseButton).setHidden(true)\n\n // Some third-party macOS utilities check the zoom button's enabled state to\n // determine whether to show custom UI on hover, so we disable it here to\n // prevent them from doing so in a frameless app window.\n panel.standardWindowButton(NSWindowZoomButton).setEnabled(false)\n }\n }\n\n if (options.vibrancy) {\n browserWindow.setVibrancy(options.vibrancy)\n }\n\n // Set maximizable state last to ensure zoom button does not get reset\n // by calls to other APIs.\n browserWindow.setMaximizable(options.maximizable !== false)\n\n if (options.acceptsFirstMouse) {\n browserWindow.on('focus', function(event) {\n if (event.type() === NSEventTypeLeftMouseDown) {\n browserWindow.webContents\n .executeJavaScript(dispatchFirstClick(webView, event))\n .catch(() => {})\n }\n })\n }\n\n if (options.show !== false) {\n browserWindow.show()\n }\n\n browserWindow.on('closed', function() {\n browserWindow._destroyed = true\n threadDictionary.removeObjectForKey(identifier)\n fiber.cleanup()\n })\n\n threadDictionary[identifier] = panel\n\n fiber.onCleanup(function() {\n if (!browserWindow._destroyed) {\n browserWindow.destroy()\n }\n })\n\n return browserWindow\n}\n\nBrowserWindow.fromId = function(identifier) {\n var threadDictionary = NSThread.mainThread().threadDictionary()\n\n if (threadDictionary[identifier]) {\n return BrowserWindow.fromPanel(threadDictionary[identifier], identifier)\n }\n\n return undefined\n}\n\nBrowserWindow.fromPanel = function(panel, identifier) {\n var browserWindow = new EventEmitter()\n browserWindow.id = identifier\n\n if (!panel || !panel.contentView) {\n throw new Error('needs to pass an NSPanel')\n }\n\n var webView = panel.contentView().subviews()[0]\n\n if (!webView) {\n throw new Error('The NSPanel needs to have a webview')\n }\n\n buildBrowserAPI(browserWindow, panel, webView)\n buildWebAPI(browserWindow, panel, webView)\n\n return browserWindow\n}\n\nmodule.exports = BrowserWindow\n","var CONSTANTS = require('./constants')\n\nmodule.exports = function(webView) {\n var source =\n 'window.originalPostMessage = window.postMessage;' +\n 'window.postMessage = function(actionName) {' +\n 'if (!actionName) {' +\n \"throw new Error('missing action name')\" +\n '}' +\n 'window.webkit.messageHandlers.' +\n CONSTANTS.JS_BRIDGE +\n '.postMessage(' +\n 'JSON.stringify([].slice.call(arguments))' +\n ');' +\n '}'\n var script = WKUserScript.alloc().initWithSource_injectionTime_forMainFrameOnly(\n source,\n 0,\n true\n )\n webView\n .configuration()\n .userContentController()\n .addUserScript(script)\n}\n","module.exports = function(webArguments) {\n var args = null\n try {\n args = JSON.parse(webArguments[0])\n } catch (e) {\n // malformed arguments\n }\n\n if (\n !args ||\n !args.constructor ||\n args.constructor !== Array ||\n args.length == 0\n ) {\n return null\n }\n\n return args\n}\n","var ObjCClass = require('cocoascript-class').default\nvar parseWebArguments = require('./parseWebArguments')\nvar CONSTANTS = require('./constants')\n\n// We create one ObjC class for ourselves here\nvar WindowDelegateClass\nvar NavigationDelegateClass\nvar WebScriptHandlerClass\n\n// TODO: events\n// - 'page-favicon-updated'\n// - 'new-window'\n// - 'did-navigate-in-page'\n// - 'will-prevent-unload'\n// - 'crashed'\n// - 'unresponsive'\n// - 'responsive'\n// - 'destroyed'\n// - 'before-input-event'\n// - 'certificate-error'\n// - 'found-in-page'\n// - 'media-started-playing'\n// - 'media-paused'\n// - 'did-change-theme-color'\n// - 'update-target-url'\n// - 'cursor-changed'\n// - 'context-menu'\n// - 'select-bluetooth-device'\n// - 'paint'\n// - 'console-message'\n\nmodule.exports = function(browserWindow, panel, webview, options) {\n if (!WindowDelegateClass) {\n WindowDelegateClass = ObjCClass({\n classname: 'WindowDelegateClass',\n utils: null,\n panel: null,\n\n 'windowDidResize:': function() {\n this.utils.emit('resize')\n },\n\n 'windowDidMiniaturize:': function() {\n this.utils.emit('minimize')\n },\n\n 'windowDidDeminiaturize:': function() {\n this.utils.emit('restore')\n },\n\n 'windowDidEnterFullScreen:': function() {\n this.utils.emit('enter-full-screen')\n },\n\n 'windowDidExitFullScreen:': function() {\n this.utils.emit('leave-full-screen')\n },\n\n 'windowDidMove:': function() {\n this.utils.emit('move')\n this.utils.emit('moved')\n },\n\n 'windowShouldClose:': function() {\n var shouldClose = true\n this.utils.emit('close', {\n get defaultPrevented() {\n return !shouldClose\n },\n preventDefault: function() {\n shouldClose = false\n },\n })\n return shouldClose\n },\n\n 'windowWillClose:': function() {\n this.utils.emit('closed')\n },\n\n 'windowDidBecomeKey:': function() {\n this.utils.emit('focus', this.panel.currentEvent())\n },\n\n 'windowDidResignKey:': function() {\n this.utils.emit('blur')\n },\n })\n }\n\n if (!NavigationDelegateClass) {\n NavigationDelegateClass = ObjCClass({\n classname: 'NavigationDelegateClass',\n state: NSMutableDictionary.dictionaryWithDictionary({\n wasReady: 0,\n }),\n utils: null,\n\n // // Called when the web view begins to receive web content.\n 'webView:didCommitNavigation:': function(webView) {\n this.utils.emit('will-navigate', {}, String(String(webView.url())))\n },\n\n // // Called when web content begins to load in a web view.\n 'webView:didStartProvisionalNavigation:': function() {\n this.utils.emit('did-start-navigation')\n this.utils.emit('did-start-loading')\n },\n\n // Called when a web view receives a server redirect.\n 'webView:didReceiveServerRedirectForProvisionalNavigation:': function() {\n this.utils.emit('did-get-redirect-request')\n },\n\n // // Called when the web view needs to respond to an authentication challenge.\n 'webView:didReceiveAuthenticationChallenge:completionHandler:': function(\n webView,\n challenge,\n completionHandler\n ) {\n function callback(username, password) {\n completionHandler(\n 0,\n NSURLCredential.credentialWithUser_password_persistence(\n username,\n password,\n 1\n )\n )\n }\n var protectionSpace = challenge.protectionSpace()\n this.utils.emit(\n 'login',\n {},\n {\n method: String(protectionSpace.authenticationMethod()),\n url: 'not implemented', // TODO:\n referrer: 'not implemented', // TODO:\n },\n {\n isProxy: !!protectionSpace.isProxy(),\n scheme: String(protectionSpace.protocol()),\n host: String(protectionSpace.host()),\n port: Number(protectionSpace.port()),\n realm: String(protectionSpace.realm()),\n },\n callback\n )\n },\n\n // Called when an error occurs during navigation.\n // 'webView:didFailNavigation:withError:': function(\n // webView,\n // navigation,\n // error\n // ) {},\n\n // Called when an error occurs while the web view is loading content.\n 'webView:didFailProvisionalNavigation:withError:': function(\n webView,\n navigation,\n error\n ) {\n this.utils.emit('did-fail-load', error)\n },\n\n // Called when the navigation is complete.\n 'webView:didFinishNavigation:': function() {\n if (this.state.wasReady == 0) {\n // eslint-disable-line\n this.utils.emitBrowserEvent('ready-to-show')\n this.state.setObject_forKey(1, 'wasReady')\n }\n this.utils.emit('did-navigate')\n this.utils.emit('did-frame-navigate')\n this.utils.emit('did-stop-loading')\n this.utils.emit('did-finish-load')\n this.utils.emit('did-frame-finish-load')\n },\n\n // Called when the web view’s web content process is terminated.\n 'webViewWebContentProcessDidTerminate:': function() {\n this.utils.emit('dom-ready')\n },\n\n // Decides whether to allow or cancel a navigation.\n // webView:decidePolicyForNavigationAction:decisionHandler:\n\n // Decides whether to allow or cancel a navigation after its response is known.\n // webView:decidePolicyForNavigationResponse:decisionHandler:\n })\n }\n\n if (!WebScriptHandlerClass) {\n WebScriptHandlerClass = ObjCClass({\n classname: 'WebScriptHandlerClass',\n utils: null,\n 'userContentController:didReceiveScriptMessage:': function(_, message) {\n var webArguments = JSON.parse(String(message.body()))\n var args = this.utils.parseWebArguments([JSON.stringify(webArguments)])\n if (!args) {\n return\n }\n\n this.utils.emit.apply(this, args)\n },\n })\n }\n\n var navigationDelegate = NavigationDelegateClass.new()\n navigationDelegate.utils = NSDictionary.dictionaryWithDictionary({\n setTitle: browserWindow.setTitle.bind(browserWindow),\n emitBrowserEvent: browserWindow.emit.bind(browserWindow),\n emit: browserWindow.webContents.emit.bind(browserWindow.webContents),\n })\n // reset state as well\n navigationDelegate.state = NSMutableDictionary.dictionaryWithDictionary({\n wasReady: 0,\n })\n\n webview.setNavigationDelegate(navigationDelegate)\n\n var webScriptHandler = WebScriptHandlerClass.new()\n webScriptHandler.utils = NSDictionary.dictionaryWithDictionary({\n emit: browserWindow.webContents.emit.bind(browserWindow.webContents),\n parseWebArguments: parseWebArguments,\n })\n\n webview\n .configuration()\n .userContentController()\n .addScriptMessageHandler_name(webScriptHandler, CONSTANTS.JS_BRIDGE)\n\n var windowDelegate = WindowDelegateClass.new()\n var utils = {\n emit: browserWindow.emit.bind(browserWindow),\n }\n if (options.modal) {\n // find the window of the document\n var msdocument\n if (options.parent.type === 'Document') {\n msdocument = options.parent.sketchObject\n if (msdocument && String(msdocument.class()) === 'MSDocumentData') {\n // we only have an MSDocumentData instead of a MSDocument\n // let's try to get back to the MSDocument\n msdocument = msdocument.delegate()\n }\n } else {\n msdocument = options.parent\n }\n if (msdocument && String(msdocument.class()) === 'MSDocumentData') {\n // we only have an MSDocumentData instead of a MSDocument\n // let's try to get back to the MSDocument\n msdocument = msdocument.delegate()\n }\n utils.parentWindow = msdocument.windowForSheet()\n }\n\n windowDelegate.utils = NSDictionary.dictionaryWithDictionary(utils)\n windowDelegate.panel = panel\n\n panel.setDelegate(windowDelegate)\n}\n","var EventEmitter = require('events')\n\n// let's try to match https://github.com/electron/electron/blob/master/docs/api/web-contents.md\nmodule.exports = function buildAPI(browserWindow, panel, webview) {\n var webContents = new EventEmitter()\n\n webContents.loadURL = browserWindow.loadURL\n\n webContents.loadFile = function(/* filePath */) {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n\n webContents.downloadURL = function(/* filePath */) {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n\n webContents.getURL = function() {\n return String(webview.url())\n }\n\n webContents.getTitle = function() {\n return String(webview.title())\n }\n\n webContents.isDestroyed = function() {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n\n webContents.focus = browserWindow.focus\n webContents.isFocused = browserWindow.isFocused\n\n webContents.isLoading = function() {\n return !!webview.loading()\n }\n\n webContents.isLoadingMainFrame = function() {\n // TODO:\n return !!webview.loading()\n }\n\n webContents.isWaitingForResponse = function() {\n return !webview.loading()\n }\n\n webContents.stop = function() {\n webview.stopLoading()\n }\n webContents.reload = function() {\n webview.reload()\n }\n webContents.reloadIgnoringCache = function() {\n webview.reloadFromOrigin()\n }\n webContents.canGoBack = function() {\n return !!webview.canGoBack()\n }\n webContents.canGoForward = function() {\n return !!webview.canGoForward()\n }\n webContents.canGoToOffset = function(offset) {\n return !!webview.backForwardList().itemAtIndex(offset)\n }\n webContents.clearHistory = function() {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.goBack = function() {\n webview.goBack()\n }\n webContents.goForward = function() {\n webview.goForward()\n }\n webContents.goToIndex = function(index) {\n var backForwardList = webview.backForwardList()\n var backList = backForwardList.backList()\n var backListLength = backList.count()\n if (backListLength > index) {\n webview.loadRequest(NSURLRequest.requestWithURL(backList[index]))\n return\n }\n var forwardList = backForwardList.forwardList()\n if (forwardList.count() > index - backListLength) {\n webview.loadRequest(\n NSURLRequest.requestWithURL(forwardList[index - backListLength])\n )\n return\n }\n throw new Error('Cannot go to index ' + index)\n }\n webContents.goToOffset = function(offset) {\n if (!webContents.canGoToOffset(offset)) {\n throw new Error('Cannot go to offset ' + offset)\n }\n webview.loadRequest(\n NSURLRequest.requestWithURL(webview.backForwardList().itemAtIndex(offset))\n )\n }\n webContents.isCrashed = function() {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.setUserAgent = function(/* userAgent */) {\n // TODO:\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.getUserAgent = function() {\n const userAgent = webview.customUserAgent()\n return userAgent ? String(userAgent) : undefined\n }\n webContents.insertCSS = function(css) {\n var source =\n \"var style = document.createElement('style'); style.innerHTML = \" +\n css.replace(/\"/, '\\\\\"') +\n '; document.head.appendChild(style);'\n var script = WKUserScript.alloc().initWithSource_injectionTime_forMainFrameOnly(\n source,\n 0,\n true\n )\n webview\n .configuration()\n .userContentController()\n .addUserScript(script)\n }\n webContents.insertJS = function(source) {\n var script = WKUserScript.alloc().initWithSource_injectionTime_forMainFrameOnly(\n source,\n 0,\n true\n )\n webview\n .configuration()\n .userContentController()\n .addUserScript(script)\n }\n webContents.executeJavaScript = function(script, userGesture, callback) {\n if (typeof userGesture === 'function') {\n callback = userGesture\n userGesture = false\n }\n var fiber = coscript.createFiber()\n return new Promise(function(resolve, reject) {\n webview.evaluateJavaScript_completionHandler(\n script,\n __mocha__.createBlock_function('v28@?0@8c16@\"NSError\"20', function(\n result,\n err\n ) {\n var isError =\n err &&\n err.class &&\n (String(err.class()) === 'NSException' ||\n String(err.class()) === 'NSError')\n if (callback) {\n try {\n callback(isError ? err : null, result)\n } catch (error) {\n // /shrug\n }\n resolve()\n } else if (isError) {\n reject(err)\n } else {\n resolve(result)\n }\n fiber.cleanup()\n })\n )\n })\n }\n webContents.setIgnoreMenuShortcuts = function() {\n // TODO:??\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.setAudioMuted = function(/* muted */) {\n // TODO:??\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.isAudioMuted = function() {\n // TODO:??\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.setZoomFactor = function(factor) {\n webview.setMagnification_centeredAtPoint(factor, CGPointMake(0, 0))\n }\n webContents.getZoomFactor = function(callback) {\n callback(Number(webview.magnification()))\n }\n webContents.setZoomLevel = function(level) {\n // eslint-disable-next-line no-restricted-properties\n webContents.setZoomFactor(Math.pow(1.2, level))\n }\n webContents.getZoomLevel = function(callback) {\n // eslint-disable-next-line no-restricted-properties\n callback(Math.log(Number(webview.magnification())) / Math.log(1.2))\n }\n webContents.setVisualZoomLevelLimits = function(/* minimumLevel, maximumLevel */) {\n // TODO:??\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n webContents.setLayoutZoomLevelLimits = function(/* minimumLevel, maximumLevel */) {\n // TODO:??\n console.warn(\n 'Not implemented yet, please open a PR on https://github.com/skpm/sketch-module-web-view :)'\n )\n }\n\n // TODO:\n // webContents.undo = function() {\n // webview.undoManager().undo()\n // }\n // webContents.redo = function() {\n // webview.undoManager().redo()\n // }\n // webContents.cut = webview.cut\n // webContents.copy = webview.copy\n // webContents.paste = webview.paste\n // webContents.pasteAndMatchStyle = webview.pasteAsRichText\n // webContents.delete = webview.delete\n // webContents.replace = webview.replaceSelectionWithText\n\n webContents.send = function() {\n const script =\n 'window.postMessage({' +\n 'isSketchMessage: true,' +\n \"origin: '\" +\n String(__command.identifier()) +\n \"',\" +\n 'args: ' +\n JSON.stringify([].slice.call(arguments)) +\n '}, \"*\")'\n webview.evaluateJavaScript_completionHandler(script, null)\n }\n\n webContents.getNativeWebview = function() {\n return webview\n }\n\n browserWindow.webContents = webContents\n}\n","import BrowserWindow from 'sketch-module-web-view'\nimport {GradientMaker} from './gradient'\n\nexport default function () {\n \n //Global Setup\n const options = {\n backgroundColor: '#FFFFFF',\n identifier: 'coolhue.id',\n width: 215,\n height: 450,\n resizable: false,\n movable: true,\n alwaysOnTop: true,\n minimizable: true,\n maximizable: false,\n title: \"CoolHue 2.0\",\n vibrancy: \"appearance-based\",\n }\n const browserWindow = new BrowserWindow(options)\n browserWindow.isAlwaysOnTop()\n browserWindow.loadURL(require('./view.html'))\n browserWindow.webContents.on('nativeGradientApplier', function (fetchedData) {\n GradientMaker(fetchedData.firstColor,fetchedData.secondColor);\n })\n}","import sketch from 'sketch'\nimport UI from 'sketch/ui'\nvar Style = require('sketch/dom').Style\n\nexport function GradientMaker(firstStop, secondStop) {\n var doc = sketch.getSelectedDocument()\n var selectedLayers = doc.selectedLayers\n if (selectedLayers.length != null && selectedLayers.length != 0) {\n \n selectedLayers.forEach(layer => {\n if (layer.type === \"Shape\" || layer.type === \"ShapePath\") {\n layer.style.fills = [{\n fillType: Style.FillType.Gradient,\n fill: 'Gradient',\n gradient: {\n gradientType: Style.GradientType.Linear,\n from: {\n x: 0,\n y: 0,\n },\n to: {\n x: 1,\n y: 1,\n },\n stops: [{\n position: 0,\n color: firstStop,\n },\n {\n position: 1,\n color: secondStop,\n },\n ],\n }\n } ]\n } else {\n UI.message(`🔔 CoolHue can apply gradients on Shape Layer(s) only`)\n }\n })\n } else {\n UI.message(`🛑 Select Shape Layer(s) to apply CoolHue Gradients`)\n }\n}","module.exports = \"file://\" + context.plugin.urlForResourceNamed(\"_webpack_resources/3ff137287832113452bf2ab1649999f2.html\").path();","module.exports = require(\"events\");","module.exports = require(\"sketch\");","module.exports = require(\"sketch/dom\");","module.exports = require(\"sketch/ui\");"],"sourceRoot":""} \ No newline at end of file diff --git a/distro/CoolHue.sketchplugin/Contents/Sketch/manifest.json b/distro/CoolHue.sketchplugin/Contents/Sketch/manifest.json index 853140b..73e718f 100644 --- a/distro/CoolHue.sketchplugin/Contents/Sketch/manifest.json +++ b/distro/CoolHue.sketchplugin/Contents/Sketch/manifest.json @@ -4,7 +4,7 @@ "icon": "icon.png", "commands": [ { - "name": "Palette", + "name": "Gradient Palette", "identifier": "coolhue-palette-trigger", "script": "coolhue.js", "description": "Show CoolHue Bar", @@ -18,8 +18,8 @@ ] }, "appcast": "https://raw.githubusercontent.com/webkul/coolhue/master/appcast.xml", - "version": "2.0.6", - "description": "Coolest handpicked gradient hues and swatches", + "version": "2.0.7", + "description": "Coolest handpicked Gradient Hues and Swatches", "name": "CoolHue", "identifier": "CoolHue", "disableCocoaScriptPreprocessor": true,