From 1c3add1a36a7eba8fd8ade4b83d13c989c020830 Mon Sep 17 00:00:00 2001 From: Wessel T Date: Wed, 6 Feb 2019 21:31:12 +0100 Subject: [PATCH] Add webhook, avatar and guild cmd + some small fixes --- package.json | 1 + src/_application.yml | 7 + src/assets/config/colors.yml | 1 + src/assets/config/emotes.yml | 14 +- src/assets/i18n/en_us/logs_simple.yml | 6 + src/assets/i18n/en_us/strings.yml | 1 + src/assets/i18n/nl/logs_simple.yml | 6 + src/assets/i18n/nl/strings.yml | 1 + .../img/emoji/Audit logs/create_webhook.png | Bin 0 -> 10098 bytes .../img/emoji/Audit logs/remove_webhook.png | Bin 0 -> 9476 bytes .../img/emoji/Audit logs/update_webhook.png | Bin 0 -> 8594 bytes src/assets/img/emoji/ok_hand.png | Bin 0 -> 13944 bytes src/assets/img/logo/webhook.png | Bin 0 -> 17158 bytes src/commands/Discord/Image/fox.js | 2 +- src/commands/Discord/Image/lizard.js | 2 +- src/commands/Discord/Image/penguin.js | 2 +- src/commands/Discord/Information/avatar.js | 80 +++ src/commands/Discord/Information/guild.js | 2 +- src/core/clients/Discord.js | 11 +- src/core/clients/DiscordWebhook.js | 10 +- src/core/registry/Discord/Commands.js | 5 +- src/events/Discord/ready.js | 22 +- src/events/Discord/shardDisconnect.js | 28 + src/events/Discord/shardReady.js | 28 + src/events/Discord/shardResume.js | 28 + src/main.js | 8 +- src/util/sizeOf/detector.js | 13 + src/util/sizeOf/index.js | 126 +++++ src/util/sizeOf/readUInt.js | 11 + src/util/sizeOf/types.js | 19 + src/util/sizeOf/types/bmp.js | 17 + src/util/sizeOf/types/cur.js | 17 + src/util/sizeOf/types/dds.js | 18 + src/util/sizeOf/types/gif.js | 19 + src/util/sizeOf/types/icns.js | 122 +++++ src/util/sizeOf/types/ico.js | 81 +++ src/util/sizeOf/types/jpg.js | 145 +++++ src/util/sizeOf/types/png.js | 38 ++ src/util/sizeOf/types/psd.js | 17 + src/util/sizeOf/types/svg.js | 78 +++ src/util/sizeOf/types/tiff.js | 120 +++++ src/util/sizeOf/types/webp.js | 71 +++ yarn.lock | 497 +++++++++++++++++- 43 files changed, 1643 insertions(+), 31 deletions(-) create mode 100644 src/assets/i18n/en_us/logs_simple.yml create mode 100644 src/assets/i18n/nl/logs_simple.yml create mode 100644 src/assets/img/emoji/Audit logs/create_webhook.png create mode 100644 src/assets/img/emoji/Audit logs/remove_webhook.png create mode 100644 src/assets/img/emoji/Audit logs/update_webhook.png create mode 100644 src/assets/img/emoji/ok_hand.png create mode 100644 src/assets/img/logo/webhook.png create mode 100644 src/commands/Discord/Information/avatar.js create mode 100644 src/events/Discord/shardDisconnect.js create mode 100644 src/events/Discord/shardReady.js create mode 100644 src/events/Discord/shardResume.js create mode 100644 src/util/sizeOf/detector.js create mode 100644 src/util/sizeOf/index.js create mode 100644 src/util/sizeOf/readUInt.js create mode 100644 src/util/sizeOf/types.js create mode 100644 src/util/sizeOf/types/bmp.js create mode 100644 src/util/sizeOf/types/cur.js create mode 100644 src/util/sizeOf/types/dds.js create mode 100644 src/util/sizeOf/types/gif.js create mode 100644 src/util/sizeOf/types/icns.js create mode 100644 src/util/sizeOf/types/ico.js create mode 100644 src/util/sizeOf/types/jpg.js create mode 100644 src/util/sizeOf/types/png.js create mode 100644 src/util/sizeOf/types/psd.js create mode 100644 src/util/sizeOf/types/svg.js create mode 100644 src/util/sizeOf/types/tiff.js create mode 100644 src/util/sizeOf/types/webp.js diff --git a/package.json b/package.json index e846a07..715fe41 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "moment": "^2.22.2", "mongoose": "^5.2.17", "nabbit": "^0.0.2", + "sharp": "^0.21.3", "table": "^5.1.0", "vm2": "^3.6.3", "wumpfetch": "^0.0.5" diff --git a/src/_application.yml b/src/_application.yml index f19c4e4..e95ef37 100644 --- a/src/_application.yml +++ b/src/_application.yml @@ -37,8 +37,14 @@ discord : type : 1 # 0 - Playing / 1 - Streaming / 2 - Listening / 3 - Watching status: 'online' # online / idle / dnd / invisible + webhook: + token : '<--snip-->' + channel: '<--snip-->' events : ready : true + shardready : true + shardresume : true + sharddisconnect: true disconnect : true messagecreate: true messagedelete: true @@ -52,6 +58,7 @@ discord : # Category : INFORMATION stats : true guild : true + avatar : true commands : true # Category : IMAGE cat : true diff --git a/src/assets/config/colors.yml b/src/assets/config/colors.yml index 11f430e..5233d8e 100644 --- a/src/assets/config/colors.yml +++ b/src/assets/config/colors.yml @@ -15,6 +15,7 @@ util : info : stats : 0x02C2F33 # Dark but not black guild : 0x7289DA # Blurple + avatar : 0x02C2F33 # Dark but not black commands: 0x02C2F33 # Dark but not black image : diff --git a/src/assets/config/emotes.yml b/src/assets/config/emotes.yml index 37f73ec..884111f 100644 --- a/src/assets/config/emotes.yml +++ b/src/assets/config/emotes.yml @@ -1,6 +1,6 @@ -cooldown : <:sad:500719642403405824> # On cooldown -owner_only: <:sad:500719642403405824> # Only owners -guild_only: <:sad:500719642403405824> # Only guilds +cooldown : <:stopwatch:542477522147868672> # On cooldown +owner_only: <:exclamation:542368036255039509> # Only owners +guild_only: <:exclamation:542368036255039509> # Only guilds core : locale: @@ -14,6 +14,13 @@ core : 7 : <:sad:500719642403405824> # Invalid locale 8 : <:sad:500719642403405824> # Missing permissions (guild) +logs : + ready : '<:spacewump:542723940997529641>' + shard : + ready : '<:create_webhook:542716503674454016>' + resume : '<:update_webhook:542716504089690124>' + disconnect: '<:remove_webhook:542716503624253461>' + util : ping : 0 : <:bored:500719642164199425> # Pinging @@ -44,6 +51,7 @@ info: 13 : <:dnd:362670805676720128> # Total DnD members 14 : <:offline:362670805441708032> # Total offline members 15 : <:exclamation:542368036255039509> # Invalid query + avatar : <:blueberry:506201160382939141> # User's avatar commands : 0 : <:blueberry:506201160382939141> # Guild prefix 1 : <:spirit:332131321759399937> # More info diff --git a/src/assets/i18n/en_us/logs_simple.yml b/src/assets/i18n/en_us/logs_simple.yml new file mode 100644 index 0000000..8323573 --- /dev/null +++ b/src/assets/i18n/en_us/logs_simple.yml @@ -0,0 +1,6 @@ +connection: + ready : '`[$[date:now] / $[process:hash]]` $[emoji#0] Master client on Wump (`v$[wump:version]`) connected' + shard : + ready : '`[$[date:now] / $[process:hash]]` $[emoji#0] Shard `#$[shard:id]` connected to Wump (`v$[wump:version]`)' + resume : '`[$[date:now] / $[process:hash]]` $[emoji#0] Shard `#$[shard:id]` resumed to Wump (`v$[wump:version]`)' + disconnect: '`[$[date:now] / $[process:hash]]` $[emoji#0] Shard `#$[shard:id]` disconnected from Wump (`v$[wump:version]`)' \ No newline at end of file diff --git a/src/assets/i18n/en_us/strings.yml b/src/assets/i18n/en_us/strings.yml index b77ecad..d6e20ff 100644 --- a/src/assets/i18n/en_us/strings.yml +++ b/src/assets/i18n/en_us/strings.yml @@ -62,6 +62,7 @@ util : info : stats : fetching: '$[emoji#0] Fetching statistics, this may take some time...' + avatar : '$[emoji#0] Here''s **$[user:full]** avatar' commands: multi : - '$[emoji#0] The prefix for **$[guild:name]** is `$[guild:prefix]`' diff --git a/src/assets/i18n/nl/logs_simple.yml b/src/assets/i18n/nl/logs_simple.yml new file mode 100644 index 0000000..5008ced --- /dev/null +++ b/src/assets/i18n/nl/logs_simple.yml @@ -0,0 +1,6 @@ +connection: + ready : '`[$[date:now] / $[process:hash]]` $[emoji#0] Meester client op Wump (`v$[wump:version]`) is verbonden' + shard : + ready : '`[$[date:now] / $[process:hash]]` $[emoji#0] Shard `#$[shard:id]` is verbonden naar Wump (`v$[wump:version]`)' + resume : '`[$[date:now] / $[process:hash]]` $[emoji#0] Shard `#$[shard:id]` is hervat naar Wump (`v$[wump:version]`)' + disconnect: '`[$[date:now] / $[process:hash]]` $[emoji#0] Shard `#$[shard:id]` is losgekoppeld van Wump (`v$[wump:version]`)' \ No newline at end of file diff --git a/src/assets/i18n/nl/strings.yml b/src/assets/i18n/nl/strings.yml index 7021afd..4d74374 100644 --- a/src/assets/i18n/nl/strings.yml +++ b/src/assets/i18n/nl/strings.yml @@ -61,6 +61,7 @@ util : info : stats : fetching: '$[emoji#0] Statistieken aan het ophalen, dit kan enige tijd duren...' + avatar : '$[emoji#0] Hier is **$[user:full]** avatar' commands: multi : - '$[emoji#0] Het voorvoegsel voor **$[guild:name]** is `$[guild:prefix]`' diff --git a/src/assets/img/emoji/Audit logs/create_webhook.png b/src/assets/img/emoji/Audit logs/create_webhook.png new file mode 100644 index 0000000000000000000000000000000000000000..e896a4f480fd031c779506227ce99f80cd84bc8b GIT binary patch literal 10098 zcmZ9SRa6{Jw6+Hr+#zTP?!jGx4^AM#-F+YgcZUSGV1wJ>8Z5Z`1PSg0g1bAM`Tl>c zb8#+OR`*4BRqd+%zR#}6Ppb0R7~~iL003K20i+JU2K{%Sp}^05;$~w20F$sHNJ`Ty z>)78n-B8|r_f&JXqnT>DkgS6Z9SL1va0(5vE_js_TvUg(aPc^GoER314bs%q*4|MzzD8c}45C|#9{7dmZs zu(y|I)aLP7ULF-ma_hCt<9O3e>5re(TZ0KDktVQKN#z0H9VN57Mn-5WO#5AFKJN)^T*9>w5L zGBM=4PEH<3404deO=n~E;aVw03lAEiP#n^Z{yG7EFIU)M>twz+4_e46R9(mE!_OE< z1lfB4Oa;`x{(R!OE)@9kRJ7$|f*u0cc3C9AClzwAB$R~3*z&O&&dZW&O4K{8cdp2b zUnB-PCA$|a@uZ|DB6h#Tvdu;Vd@ohq)mfsG?=EFaGtHdu`(oiet~wf5)d z-HC6LpU{sH-Su0Wtf>!$z#s@ZK;X;D0%f#Mu4I)zA!G+FC_=VF&0*zNo&O!LHHLLE z;Gc_d;)rF#meBjnx&_~;@Q|MV)Yfuc=5#N%8_FSPZA%`q?6Ga@8PUwoe^zSe1f51Y z_q^9mfl>e!!{MsK)>7??*CltygBVB?ZTjawerTYu5y#BZG~q2SUSw0^j~3bhFrAlB!r9s&|(+|2!iA~ z8>Lk?65gyDfZ^ZihfQDw4yyFT*kb_>_V*KgZ;lkb68E$@3G|FviTMFGS=-@tUWQul zQ##>2KAXg#d;t$96!|0ioYC~p(MKj-pn%&PO= z1RkZwl7WE|7AWrGT$g+R0Cnc?QB77W0mmgbN4B+}ELbvyjl`gtAmO+5swOLu!%F-80jPa@jT$YlQM_6v9+ICNa@aadf;nG# ze9&6+d5%xZU!QxrI7mhTsxIZ}*<9aLaoA~2v%c-UmZv`YH563Di2pSfWOg12VPHgO#q!$EXb5oHm*- zUK7mO{qT5HuPUCqJ3g)|mh)KhmZ=KBRlj$9OeEhqY{+qoGjXY}3=M+xMI>B!(EfFH z^!If0O-Bc*beq#gQB2^`({j0n2Y1B!%9rKE4wx5ca!4R4o5T+oYO$uEw6(Sdh(GBip@xR3W1!+v&P*vBjjK0aZ5pg!q}F8lp0tp=Z`GHS$Y;kqqA|t7 zXD6qKh)5~-_cizV9V^TW{s{ME7 zO;|Jv;}BldZ5J}>2&5FH``2;1>_^X<&eqfUd6V^P{siY!n(Y3f9Ujg6lCXSu`2!q2A@ z9BoHG{k#7sZtIxYR;kRY zuj*(ntoMnwN1WeKa98T#fll(h`4yyf5!NyDmu_RN%Ajjs!CjA@+~|Xl5E_b#QRBoL ziEyhR^aMvo$I|36UztLx_MP&Im-k=I8+#fs0ld@Mo@@K7UR$v#A2VIj`nRTVMXOyu z*6D&szxjM{_A4Q%Y+Q1tAc`NtNBP?^V1EBtp~KW1c|AN!s>HkanbzOuxv+@@owl>HYt z2iSUU5Bp9&z1Qva7x(Qnv`(zKzN{e;?SA4;h7+QPSJUfPAc0JyWF=_K>7&MyyoLZG z1mffCyFC^f8VzkylPgSYCXSZ<2&x&o@6_X}j~m)5H>`ddWv+AiY_PmW^j;sl9q_FA=MPhd3^@@zHTiOYKQ@Tt zX;yFzo*m9?U+(_P)D1;EKTP$Zt-xOZz{tJQPdi_ zZm3K`V?2-*XNNY->C1q&uz!oBm_im26Qt1)gFv)@0YT~*kGH3Rly8pcg5|`HUKGVCSrdaS1s#|CY{1~d@0a1dDuNF< z%V&`T=FDkhlltFb4#yY@>KqO)sXo&-!bO&4+l2uYP3e7 zml|c7>z3eP#Y2kqTV(u22Z2X{?O*enx<4%=k4{cf zRj&4R*@#8G&hq34A;N0>q!ucCid)-0*5Zg-i>>$3J$-3yGAiFv4e0D zV`_kI^OtPKf?}@_cj-&^5*7yt<;g^*}xr+}hTb?S44-uE77}+>$@5#`MQ1l+w>F z!wxGA``GsN+)ny7Tjugbc8yR4L!>laThlO9o@Fns3=4R>oaQ^$@ zd`<3^h{`tcdDvr_S@J)Z7SCTf^WYdq?7pvZ3Bu{Zno7bsB*D~6x~xQMpx z$K@u-kMLzdV-;N_Hr?7FkE4aZ+tJYL91=S!3W}MM*7G447Hykp52B4p;OiyrW)Vl{ z-E$Wp$RX8=2VEJ&OKa;UU6>3htFPD4shBN&vq^}AgydJw`IruYCeue)e!~88@uA~l zGkX0M(>j&kQC?#wO#(lC^3CKznSPVQA~OBIzQJ^j#CC5qEK-IPH=`l#QD|eCrakXj zM&K4`-ieiq2D{dBga9&PSt+nntjorjVYHJKW7_>Ijt=@}K)Tb-ku_zh-K-C#=1cIz z@Hi?Xm;T!lXEKYmJ=p>YJn42ZG(_tijV~`YJGC7ht7Jl4Up?_O#RHzN=SgfXN~z+U z!9ikEA0;k2&TyZ71iGbKp12l3$n z5ptt4{b3HvOG{ayGBR&#Iv+;g`mK||R5bbr=(q^|OuBE8)4^T2rZLOrCUxe>^Ck6Pt;gk-9UoWEcZ7;GYM(RnasS zt=#eR%;<#WH=~JvCDRRU7J}@njc)o|C_~E@z@XFC!|GookvM2HSw1|2=!%l7tD{r4 zGiA^#@D+0KVu2yY_tJA_riPhH8zee#l_Eop^Vt&PbH7L~B=xq~%EV@e+2XDjJNM!$ zb9bD#I!bBm3u%VS3}#e(<%9Wa;{3x=^lA&v=trdYUcF!slycHQ);Sqf5=2Yd#7{~r zSXfw3SRh%%`R`cV>05AZe)>nh@DuY)1L*gsw?8IlMRSejw_VD-jNomvcXDbb{QM~X zh-gPGWBCZ^Xt!x02v2z@{YSLt=7Y6cSeRfCK10(VM0FAA?-60|n@cdMeG-Fm>zgFP z`cJT|jO~-NVT@KBkavWcwruHG*k@6AwBnT5rd3u$&cp6TwpD%9SY3NU2kSMho1>>Q zIJbV-u)HdXU$2E`rR#el90L6U(Al7_a6IlKLZNwLW3J*nXQe@_|O75Ken#7Bm&WW?{Efd^Jn1||VN7F&Jw z7~ujYHGd?RTs0k_JH|+GUNq-3srwkJ+y7`1JGuYBed=;|ezNcOF!}Vf5sEv`sZ}1x z68=k?WmdaPGZt^iQ-as^7kq;4rldVO8PqenkHx(cZP%*M)*8A*{N_1)f%?R|8u5@m z`}CQ}eFq6>R2|ZTVmSY)U&Zf=+1ebDFh3xpDnWfT0+TRoHayiKS*y*R+XbkICpp_KJf1NB#K!O0j!(iw$NxOL?M~v6d$Y~{AjEUU!F3-YcJ;|}qMC3D=8*>B3+oZqXNOa-ad$a#OAHI#5tqXwc|TU%e$ z{OM6_*U$>ziF*91(5@=~vetetF|c|5y-~pN+Hnt`Ke*9BUtj;<%f-gew@F}+SV1&i z$j4DbR-06byYTvVX}M=0uO$v-g%= z0-ugiQBYn|6_^cjyT18zBD9w*ZjQ{-UVK%~0bqkM z?76cHa;QK3@hCihe-tZSyPtE`>`a(2`DOh(BiGH-QG++z zH=|%VbxpfZ@=v#4BM!q8=0{4G?MJob96hMH8tl)L%Ybc;1N6DAwDrCP85;@+Ldp4u zYmZIh+@5RgDK+g+E(+2yBFzF~4+wNVB~b-AC^ z?1uTQwR<0I>zL@du4eFO9(-4hSKQ)bdmcxf7F1I6CmHPJd5cKTTNx$Ni{c|;;0G1a zeb|Yg3$OzKHXeJ`klI|^_7h~#y1%A{#`7JI9~VPMpjlF@X26XQN5QUHrCn>9fonjI zy(1cZ&m_+d>)X9FEFGO|!>jv1MaCaIX>W7!D9TvD4JYg^PL2H*RPTwSXBDyjHB=u) zCE-lyx?az|W~i2M>rry9-^z+)4~pHc-imT>x03>ck*N>X#D5NcC@lJAe!A9ydiW1k zT(vidW^gaL;}SK@_V%!Q2}Ny8h+FMI>6(S-YJ`cSWjhza)H}ZBLA&U;*W8J`Nbp*h z*pCJ!hXf^#x!Daa8m{e)w2b4&M~;zpKUmhcq3%S)PolnpnTMY5Y>Y|2#V9Utnp&?e zEwNsPKcSev9EBib9$DJ_IojX<{QUeJ64{w$tN3(2IhlZv=m-Y8;!u#@y<}9+#9D~o z<$rPXeA$?5jzoL@gr;wcXc1}O3pLManB6!$mg%}XZP6U37iMu4`Zm48ye?rj!;pO% zZP^;?lFXBhyRt$$naCU@i`?=Hv}j!-+5XtLlx0czznZa;9)BBInX_UEtJGvg z#(RDPaCdW4X^n3)W(?jdNl}7QM}(c{oaPYn%WFPZ=8a_Xmnukn{ zIH-%ey6y%t7u@JF3uzwAa=%;ORoJenpv{B-mj?cbfm?%y9_3q=H zD!gm-P9Doo4`5C*UlX{v+(O+D{Fu4~n_C(F>or_Lz3RBkW3daZ*o%c~1YlWU_a?>T$d`mf+=3hv0- zH@fN<7njY@2^mHU|2w8M03Lp&RmaPUYe|+;N5FGSeq+<0KS`2hnlJ9GDLyzs_C9^z zA#g5e)Y&JI-9t6C4FD2g)qW-7-n#TBu?~RilWpDNH)i~Y_O@>Pe2kO%)xd8-e{`4T z;KS5;8hsCinh0(mO!I7x`tWgwRiK4PAmuT3|DFT05s@+}fE~^2_MSerte^%J;`*m! z@r|xDu-pdgvU%u>OT1w%Ynu7-Nl@$|?Y5W!z?@W}1p_xP>7&$NQRFN4T%OC`9GX^F z9S)%(TCPe=-3jm9cEPpcwmORi(5jOE8yYpDLmt8)^6u$bnl%sEp`ab6N*Z86mu*fC zRuK^a&s~hqEpY7~5|JLEGoY`(lR7r=)zoyoScTCd-m`p|hO4xO*J6C-j0Jbj7!hw? z&{{GC5PWjHYptaCkI|9Wx^kGomAI4BC(zv2LH4#Rorx4yS>>T$;B4MX0q`g+EVDCR zDh5>XBQZaSiD?iEsdKiK_9cWT6nAuVII`W&+ZjH!IYAz^70!({szcDFMU=v}4+8KP z*Z`wY4JHn*u_8I%|8m0?FLD+s_(>@awqC{eR2bq zdqOeis|*Co_9x(y{67}#Bwji+~7h4h%qGhwnJqGbUJvvTJdgc+d*0S;C^zVFIP9?xT7y+cF0d2(`6JZ1+w1U;GjN?p&CgwX>5_gny_ z9d%kydb<<|`P>T{-kHB{zAdOukr6qSawtcEN(!+I({0@f;t!X=x%i_k3YiH#4&l4> zD*S$^L9b_t#W3e0(OajD@t##WP| zj|WosAODyz~9%nzQG=(FXlpQ9=4*wcTc>?}hB;Xa0t5&w4B zw2XVvu!!#s2{`(7KwBP$RbJ+2y^OH&ceQ18C>ybuH$ej^Whyq2iTX#P_3DrEdh*2X zf7!}Q*gG~9N)QQrKA7ix9@ghpW3jrpf0Aga_I1jhDaedjWWqZS7ZvcL!Oa;@1v^ke z!_cqCmb9L`!TRR940}(MVPi>6@4MqZDpeyY4dASMZ!7*~_&M$r1kYFR@PcRL z+iOvmdLn|z`umIMBhG%7VPPY7=d-W2em{Nod{xAfmf-ks%W$~K5I1Q?MOI?s8fHuo zcSmDj5QvK>FiB1D3LzMemS3B`vrX-CPWD3o!iEjlb*mAjm&SYq`zc!c@Uv-?2GP!- zS%r9+)t@>q$+U!1<7;dg@GME)x1%r&8d%>*st~veH3xi$-?=qO|M)>+PY!6(tp#@88T8 zYU>J@1>C~4#<6gI*8w$`Cz*rfvl%Pp6j`g2^3ay`kI;DuhL|t8vLbW?;J98N47auq zjrW+uFC%kRxc(dE6&wNi&i?^)*Eu~KXE?q`YNUU|*?xwI&6MD<`Y@>{oiSA8vi58`^ZN7j(V{x5;VXp3E=}L7v<##lH29h10qV zd&!2v?&_?jC`%OrG@iM|4rd5map%*z9Wg2{4%xi>+7WY|>vXE&m%mRfnW(o|FPjI4 z)oY@E{BKwN*EgFO9GwE)*Mm8rLS**SE@vB)G)i}2#JlcDlQhZF8;y<@){?!?Bfh&L zfO0yk2TM5>S&E)i2cI}Tp!f=9*-vVU zOK$*k-?0HlxUi}kn;6K?zci=_+RwMwdb{3G!MU*3{nI2a0(GLT|9VfTjQ$Vrcq@_j z(^qPCDfP48*Z8ogs3j6A*sO#ZYvry&b;m&z{YoTP=iIFv%l zs-q=kemD8>A*44ERz@i3f?M>fTv`m9a(1)f^$k7h5SNwe2U&#%#!pq+bxtN-#Qbrz z@0f5*V~EOF5<0VmYA;r^zUPIjs5oGmI{QRVx*}lRmDY@s&#$MK1)bv;`AduR$?xYI zDp5n~cg1dYyS5gGl?^Z1>%P8m=D%C~@j6V>K1f7?u+K;Hqf87;&p|i+))E#fW{X8y zKy2LmI_FR?PZ%Wd#P+JCB@(72jdi2Bwdxhnw<;em+s^z#`8lbO_ti} zcLef(y3G8vizMh7)X(#lJSakug(vvMQ7dc$NfKo!UH?GH1@zx+vZ>c2)4WcDS8T-2 zy`l+YL6&UfZ~qdC?W_0l4Kr;iUL{nB{*J-#nt_gr(-Z-b1ZDu!RDK(E2Co3%4MfeB z0Ji;}8c_S`i;~>Cv_*1rT{3q`ki^5(fChn zJJW^h$6SWdyj|c%Fsf>WcE#ghvW;LGFI=p^1_WQ1N8dGzGZd;OVQP&H{+uSbcI$MZ z3(9VDZ6Qos3Wq%Wv3m@be`;BBA&HS)MZ*{1f;mtj05=*t;|84iaT;mq{x{;yDdhNNox{7naCs=mUI^buvQT7nZf78};h`fJiv{8{LGg7-M(2Fip1Id^;7I9e}et=d{*H;NG_ySU!)3sU@nARM$TyArMBu`KR5|a-SFAO zNMBOyBiV42iIhQjN=ap!x0vtTLZu*Xm$72`Eat@+AfRQz68Jj#)T_`udsDbIK9>Hb_hg2rGu z)JFlEo3P{Gnq@Q&Bo4}fhW#rwnJ%`UFQ4?7C=**hwOo%VPrv9EhTBvENG+}krita? z*!%hyj-hQoviQGTPN+{3wm}dwuK}4e^7ozH(gQ6u!^Fk^u|k97zVp&&i6x9zFe-cDO{)<6 z;67{eM3)ZE>Tw3`Q{Jywaxjsfe*J=u=HlZ60XC=G9KZVEC9#IBa9bT_pQCWo%Fo|LyT zCYY6(hpBfl6-*6rcn!bOM+l{jl70G}K%pE%2`}KM-rkjKtB$gDohp}jiYIp(c#Y2k zgeb_X-NhS}yja<^J7-<>cB0{CF|On?7~K|NJ@{XZ5KhlZjOIm~6O+xdwm*uHqU}s% z?&44^bRDF1J#81J8T*ud@XX4$i?y1)aD3sBA4LWA`$w~A^8s0`b!imQbfk3pjHT}W zY>}*8EPTzRgX1wMGUd{r1>6@w zYHLa^>O0IfBAzQA-;##WC;ZbmwE1wX6qr&!>(th9NiAR|-ICAUUK=HOx0GGf>v`8+ z&v#Y0*QOTzlJg$tAY}%jdEM~nM?Up?ExchDyjQ=_+n4%sw`~}$sriKMU{Vglnefs)> zA(qw9@Z`^GwRN>pTxbLnTxYnwn>xfRxJ|Omwiw~^VcKZM=6Y;&XBdoZ8u;^8*6H@9 z5sEY4oAL4G>$tT@Z*q0r$I=jHdb^p@`COz~+u(GySiKA|_+-~&hy&G(Yb+!rEqR-& zH?-wEM@+>)d$PBePMSuY!uuZq@VPcQa^%eNZ)DMNGVhZma>aeGllFcPC7*$2xu}A} z#eg<9EpnKcz$+@kXCz8Ibuaim)#s}7QxW#H*Ecy2NK*d}Tui~)xbPh*Mf9@-p9N;R z{(UmJ=r1?u^kbfVqPN7#uAN;|Xla5IwOd(>x_2O2V~#W#>r{=-z(5KWxunuW%m8+p zX=L2h2ai4hx|DWxAq;^TQ%8P6LT(@~CKs|4zZVJ&P-zu}MgFf^AIgp-EuxO5){`9i z>~No{$@aWWSjI_}<&fJ~#I{U+)4lGr_SBhbdzA^=yiF(Dc7cTB`SGdQllN3EFE4lK z++Lgb!Xe(GqNra>0Hb8zp~p)T%$xp9LLo|(%z0^%M}+}cX;m$cgHM$RXv<+rM+5LC zCeasi2=Q^{FCt0Z0*PK8rqcpX1iQggl7!WdTq;Yg{$6v(4mWG@m@F^D(V#VGAD$A+ z%t+La>tEJj_q{-Av^N(rY3}asj+rxrzv73NeP3{&pq2erA$N#e9XdYc$a(s4rnFe= zf)$CwU`T%tvA|@Pm7)Z_WA4Aw$4L#6r~CJkVrphQ{M_rk%;|gqMs&R;9x+G!>w70B zox4Z%6FF_SDLSvZEbgi;nm_#zi-G0Puh{VR8YNw*^8L?9?tjO$vD4D6em&o-onR)s`-59yt`LM4X={g@Myw zzxEdu*kHH+UfYau!i=BaXJqQ*l=uT_C#R-*Fp1gn&WpcOk&uQp zsKsj5HA=>j8ynR|lh^r6R?G2yM1m|WN;kII{GUB(|9^WLBiSoew}GL7oCqU)uMPm9 MD60ypmNpIfAK?$*d;kCd literal 0 HcmV?d00001 diff --git a/src/assets/img/emoji/Audit logs/remove_webhook.png b/src/assets/img/emoji/Audit logs/remove_webhook.png new file mode 100644 index 0000000000000000000000000000000000000000..21407db4d7cd496e894b0d7e91b2394893eaf6f8 GIT binary patch literal 9476 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 x6UK{=HS)N|LkcM`5(iDpWXlf literal 0 HcmV?d00001 diff --git a/src/assets/img/emoji/Audit logs/update_webhook.png b/src/assets/img/emoji/Audit logs/update_webhook.png new file mode 100644 index 0000000000000000000000000000000000000000..0460c8804760003513d49e619185e76e1a208fd0 GIT binary patch literal 8594 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 IigvO82lLH?D*ylh literal 0 HcmV?d00001 diff --git a/src/assets/img/emoji/ok_hand.png b/src/assets/img/emoji/ok_hand.png new file mode 100644 index 0000000000000000000000000000000000000000..41c20fb273aee398854cbca712c213ea52972ac1 GIT binary patch literal 13944 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

2GRTWVeIar(fS?! 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 Cf5Gzr literal 0 HcmV?d00001 diff --git a/src/commands/Discord/Image/fox.js b/src/commands/Discord/Image/fox.js index 3d75d35..4a74849 100644 --- a/src/commands/Discord/Image/fox.js +++ b/src/commands/Discord/Image/fox.js @@ -2,7 +2,7 @@ const { DiscordCommand } = require('../../../core'); const w = require('wumpfetch'); -module.exports = class Cat extends DiscordCommand { +module.exports = class Fox extends DiscordCommand { constructor(bot) { super(bot, { name : 'fox', diff --git a/src/commands/Discord/Image/lizard.js b/src/commands/Discord/Image/lizard.js index ecfe714..08ba5e2 100644 --- a/src/commands/Discord/Image/lizard.js +++ b/src/commands/Discord/Image/lizard.js @@ -2,7 +2,7 @@ const { DiscordCommand } = require('../../../core'); const w = require('wumpfetch'); -module.exports = class Cat extends DiscordCommand { +module.exports = class Lizard extends DiscordCommand { constructor(bot) { super(bot, { name : 'lizard', diff --git a/src/commands/Discord/Image/penguin.js b/src/commands/Discord/Image/penguin.js index db221c0..cc3fd5e 100644 --- a/src/commands/Discord/Image/penguin.js +++ b/src/commands/Discord/Image/penguin.js @@ -2,7 +2,7 @@ const { DiscordCommand } = require('../../../core'); const w = require('wumpfetch'); -module.exports = class Cat extends DiscordCommand { +module.exports = class Penguin extends DiscordCommand { constructor(bot) { super(bot, { name : 'penguin', diff --git a/src/commands/Discord/Information/avatar.js b/src/commands/Discord/Information/avatar.js new file mode 100644 index 0000000..c61fc94 --- /dev/null +++ b/src/commands/Discord/Information/avatar.js @@ -0,0 +1,80 @@ +const { DiscordCommand } = require('../../../core'); + +const w = require('wumpfetch'); +const sizeOf = require('../../../util/sizeOf'); +const { extname } = require('path'); + +let s; +try { s = require('sharp'); } +catch (ex) { throw new Error('Sharp not found, not loading this command'); } + +module.exports = class Avatar extends DiscordCommand { + constructor(bot) { + super(bot, { + name : 'avatar', + syntax : 'avatar [...user:string] [--large] [--(nearest|linear)]', + aliases : [ 'avt', 'pfp' ], + argument : [ '[...user:string]', '[--large]', '[--(nearest|linear)]' ], + description: 'Get a user\'s avatar', + + hidden : false, + enabled : true, + cooldown : 5000, + category : 'Information', + ownerOnly : false, + guildOnly : false, + permissions: [ 'embedLinks' ] + }); + + this.regex = [/--large/i, /--(nearest|linear)/i, /--greyscale/i]; + } + + async execute(msg, args) { + const resize = + this.regex[1].test(args) && this.regex[1].exec(args)[0].toLowerCase() === '--nearest' ? 'NEAREST' : + this.regex[1].test(args) && this.regex[1].exec(args)[0].toLowerCase() === '--linear' ? 'LINEAR_A' : 'LINEAR_B'; + + const oldArgs = args; + args = args.join(' ').trim().replace(this.regex[0], '').replace(this.regex[1], '').replace(this.regex[2], '').split(' ').filter((v) => { return v !== ''; }); + let user = this.bot.REST.getUser(args[0] ? args.join(' ') : msg.author.id); + if (!user) user = this.bot.users.get(msg.author.id); + + let img, dim; + const avatarURL = (user.avatar ? user.avatarURL : user.defaultAvatarURL).split('?')[0]; + + if (this.regex[0].test(oldArgs.join(' '))) { + img = await w(avatarURL).send(); + img = img.body; + + dim = sizeOf(img); + img = await s(img) + .resize(dim.width * 2, dim.height * 2, { kernel: resize === 'LINEAR_B' ? s.kernel.linearB : resize === 'LINEAR_A' ? s.kernel.linearA : resize === 'NEAREST' ? s.kernel.nearest : s.kernel.linearA }) // { fit: 'inside' } + .toBuffer(); + if (this.regex[2].exec(args)) img = await s(img).greyscale().toBuffer(); + } else { + img = await w(avatarURL).send(); + img = img.body; + } + + if (this.regex[2].test(oldArgs)) img = await s(img).greyscale().toBuffer(); + + msg.channel.createMessage({ + embed: { + image: { url: `attachment://thumb${extname(avatarURL)}` }, + color: this.bot.col['info']['avatar'], + description: `${this.localize(msg.author.locale['info']['avatar'], { user: user })} (\`${this.regex[0].test(oldArgs.join(' ')) ? 'LARGE' : 'DEFAULT'} ${resize} ${this.regex[2].exec(oldArgs) ? 'GREYSCALE' : ''}\`)` + } + }, { + file: img, + name: `thumb${extname(avatarURL)}` + }); + } + + localize(msg, extData) { + if (!msg) return ''; + + return msg + .replace(/\$\[user:full]/g, `${extData.user.username}'${!extData.user.username.toLowerCase().endsWith('s') ? 's' : ''}`) + .replace(/\$\[emoji#0]/g, this.bot.emote('info', 'avatar')); + } +}; \ No newline at end of file diff --git a/src/commands/Discord/Information/guild.js b/src/commands/Discord/Information/guild.js index 4cff123..1b1ef60 100644 --- a/src/commands/Discord/Information/guild.js +++ b/src/commands/Discord/Information/guild.js @@ -2,7 +2,7 @@ const { DiscordCommand } = require('../../../core'); const moment = require('moment'); require('../../../util/moment/diff.js'); -module.exports = class name extends DiscordCommand { +module.exports = class Guild extends DiscordCommand { constructor(bot) { super(bot, { name : 'guild', diff --git a/src/core/clients/Discord.js b/src/core/clients/Discord.js index 66826fd..35c7040 100644 --- a/src/core/clients/Discord.js +++ b/src/core/clients/Discord.js @@ -39,11 +39,12 @@ module.exports = class WumpDiscord extends Eris { this.schema = Schema; this.Collection = Collection; - this.ua = options.ua ? options.ua : undefined; - this.pkg = options.pkg ? options.pkg : undefined; - this.col = options.colors ? options.colors : undefined; - this.ico = options.emojis ? options.emojis : undefined; - this.conf = options.config ? options.config : undefined; + this.ua = options.ua ? options.ua : undefined; + this.pkg = options.pkg ? options.pkg : undefined; + this.col = options.colors ? options.colors : undefined; + this.ico = options.emojis ? options.emojis : undefined; + this.conf = options.config ? options.config : undefined; + this.start = Date.now(); this.requestHandler.userAgent = this.ua ? this.ua : `Wump (https://github.com/PassTheWessel/wump, ${this.pkg.version})`; } diff --git a/src/core/clients/DiscordWebhook.js b/src/core/clients/DiscordWebhook.js index 373a486..bf87a44 100644 --- a/src/core/clients/DiscordWebhook.js +++ b/src/core/clients/DiscordWebhook.js @@ -1,4 +1,4 @@ -const fetch = require('wumpfetch'); +const w = require('wumpfetch'); const { randomBytes } = require('crypto'); module.exports = class DiscordWebhook { @@ -11,14 +11,16 @@ module.exports = class DiscordWebhook { (async() => { try { if (!this.extData.token || !this.extData.channel) return this.hook = undefined; - this.hook = await fetch(`${this.baseURL}/${this.extData.channel}/${this.extData.token}`, { method: 'GET' }).send(); + this.payloadURL = `${this.baseURL}/${this.extData.channel}/${this.extData.token}`; + this.hook = await w(this.payloadURL).send(); if (this.hook.statusCode !== 200) throw new SyntaxError( 'Failed to fetch webhook' ); } catch (ex) { throw ex; } })(); } - async send(data = {}) { + async send(payload = {}) { if (!this.hook) return true; - return await fetch(`${this.baseURL}/${this.extData.channel}/${this.extData.token}`, { method: 'POST', data: data }).send(); + const req = await w(this.payloadURL, { method: 'POST', data: payload, sendDataAs: 'json' }).send(); + return req; } }; \ No newline at end of file diff --git a/src/core/registry/Discord/Commands.js b/src/core/registry/Discord/Commands.js index 1586de7..659e4ed 100644 --- a/src/core/registry/Discord/Commands.js +++ b/src/core/registry/Discord/Commands.js @@ -105,6 +105,9 @@ module.exports = class CommandRegistry { cmd = this.bot.cmds.filter((v) => v.extData.name.toLowerCase() === cmd || v.extData.aliases.includes(cmd)); if (cmd.length > 0) { + if (!this.bot.cache.has('commands_ran')) this.bot.cache.set('commands_ran', 1); + else this.bot.cache.set('commands_ran', this.bot.cache.get('commands_ran') + 1); + user['entryAge'] = Date.now(); guild['entryAge'] = Date.now(); cmd = cmd[0]; @@ -141,7 +144,7 @@ module.exports = class CommandRegistry { return msg.channel.createMessage({ embed: { color : this.bot.col['cooldown'], - description: this.localize(msg.author.locale['cooldown'], { left: moment.duration(timeLeft).format('YYYY[y] M[M] DD[d] H[h] m[m] s[S] SS[ms]'), author: msg.author }) + description: this.localize(msg.author.locale['cooldown'], { left: moment.duration(timeLeft).format(`YYYY[y] M[M] DD[d] H[h] m[m] ${timeLeft > 1000 ? 's[.]SS[s]' : 's[s] SS[ms]'}`), author: msg.author }) } }); } diff --git a/src/events/Discord/ready.js b/src/events/Discord/ready.js index 076a265..fbf1f9c 100644 --- a/src/events/Discord/ready.js +++ b/src/events/Discord/ready.js @@ -1,10 +1,16 @@ const { DiscordEvent } = require('../../core'); +const moment = require('moment'); +const { safeLoad } = require('js-yaml'); const { green, cyan } = require('../../util/colors'); +const { join: pJoin } = require('path'); +const { readFileSync } = require('fs'); module.exports = class Ready extends DiscordEvent { constructor(bot) { super(bot, { name: 'ready' }); + + this.strings = safeLoad(readFileSync(pJoin(__dirname, '..', '..', 'assets', 'i18n', bot.conf['discord']['locale'], 'logs_simple.yml'), { encoding: 'utf8' })); } emit() { @@ -19,14 +25,26 @@ module.exports = class Ready extends DiscordEvent { }); } + this.bot.hook.send({ content: this.localize(this.strings['connection']['ready']) }); + // Cache flushing if entry isn't used within `flushTime` minutes const flushTime = 1800000; setInterval(() => { const uCache = this.bot.cache.get('users') || []; + const gCache = this.bot.cache.get('guilds') || []; - uCache.forEach((v, _) => (new Date(v.entryAge) <= new Date(new Date() - flushTime)) ? uCache.splice(_, 1) : undefined); gCache.forEach((v, _) => (new Date(v.entryAge) <= new Date(new Date() - flushTime)) ? gCache.splice(_, 1) : undefined); }, flushTime); } -}; \ No newline at end of file + + localize(msg) { + if (!msg) return ''; + return msg + .replace(/\$\[wump:version]/g, `${this.bot.pkg.version} ${this.bot.conf['nightly'] ? 'NIGHTLY' : 'DISTRIBUTIONs'}`) + .replace(/\$\[process:hash]/g, process.hash) + .replace(/\$\[date:now]/g, moment(Date.now()).format('HH[:]mm[:]ss')) + .replace(/\$\[emoji#0]/g, this.bot.emote('logs', 'ready')); + } +}; +// YYYY[y] M[M] DD[d] H[h] m[m] ${startTime > 1000 ? 's[.]SS[s]' : 's[s] SS[ms]'} \ No newline at end of file diff --git a/src/events/Discord/shardDisconnect.js b/src/events/Discord/shardDisconnect.js new file mode 100644 index 0000000..fda8bdf --- /dev/null +++ b/src/events/Discord/shardDisconnect.js @@ -0,0 +1,28 @@ +const { DiscordEvent } = require('../../core'); + +const moment = require('moment'); +const { safeLoad } = require('js-yaml'); +const { join: pJoin } = require('path'); +const { readFileSync } = require('fs'); + +module.exports = class shardDisconnect extends DiscordEvent { + constructor(bot) { + super(bot, { name: 'shardDisconnect' }); + + this.strings = safeLoad(readFileSync(pJoin(__dirname, '..', '..', 'assets', 'i18n', bot.conf['discord']['locale'], 'logs_simple.yml'), { encoding: 'utf8' })); + } + + emit(err, id) { + this.bot.hook.send({ content: this.localize(this.strings['connection']['shard']['disconnect'], { shard: id }) }); + } + + localize(msg, extData) { + if (!msg) return ''; + return msg + .replace(/\$\[shard:id]/g, extData.shard) + .replace(/\$\[wump:version]/g, `${this.bot.pkg.version} ${this.bot.conf['nightly'] ? 'NIGHTLY' : 'DISTRIBUTION'}`) + .replace(/\$\[process:hash]/g, process.hash) + .replace(/\$\[date:now]/g, moment(Date.now()).format('HH[:]mm[:]ss')) + .replace(/\$\[emoji#0]/g, this.bot.emote('logs', 'shard', 'disconnect')); + } +}; \ No newline at end of file diff --git a/src/events/Discord/shardReady.js b/src/events/Discord/shardReady.js new file mode 100644 index 0000000..8deff7f --- /dev/null +++ b/src/events/Discord/shardReady.js @@ -0,0 +1,28 @@ +const { DiscordEvent } = require('../../core'); + +const moment = require('moment'); +const { safeLoad } = require('js-yaml'); +const { join: pJoin } = require('path'); +const { readFileSync } = require('fs'); + +module.exports = class ShardReady extends DiscordEvent { + constructor(bot) { + super(bot, { name: 'shardReady' }); + + this.strings = safeLoad(readFileSync(pJoin(__dirname, '..', '..', 'assets', 'i18n', bot.conf['discord']['locale'], 'logs_simple.yml'), { encoding: 'utf8' })); + } + + emit(id) { + this.bot.hook.send({ content: this.localize(this.strings['connection']['shard']['ready'], { shard: id }) }); + } + + localize(msg, extData) { + if (!msg) return ''; + return msg + .replace(/\$\[shard:id]/g, extData.shard) + .replace(/\$\[wump:version]/g, `${this.bot.pkg.version} ${this.bot.conf['nightly'] ? 'NIGHTLY' : 'DISTRIBUTION'}`) + .replace(/\$\[process:hash]/g, process.hash) + .replace(/\$\[date:now]/g, moment(Date.now()).format('HH[:]mm[:]ss')) + .replace(/\$\[emoji#0]/g, this.bot.emote('logs', 'shard', 'ready')); + } +}; \ No newline at end of file diff --git a/src/events/Discord/shardResume.js b/src/events/Discord/shardResume.js new file mode 100644 index 0000000..dbd3e72 --- /dev/null +++ b/src/events/Discord/shardResume.js @@ -0,0 +1,28 @@ +const { DiscordEvent } = require('../../core'); + +const moment = require('moment'); +const { safeLoad } = require('js-yaml'); +const { join: pJoin } = require('path'); +const { readFileSync } = require('fs'); + +module.exports = class ShardResume extends DiscordEvent { + constructor(bot) { + super(bot, { name: 'shardResume' }); + + this.strings = safeLoad(readFileSync(pJoin(__dirname, '..', '..', 'assets', 'i18n', bot.conf['discord']['locale'], 'logs_simple.yml'), { encoding: 'utf8' })); + } + + emit(id) { + this.bot.hook.send({ content: this.localize(this.strings['connection']['shard']['resume'], { shard: id }) }); + } + + localize(msg, extData) { + if (!msg) return ''; + return msg + .replace(/\$\[shard:id]/g, extData.shard) + .replace(/\$\[wump:version]/g, `${this.bot.pkg.version} ${this.bot.conf['nightly'] ? 'NIGHTLY' : 'DISTRIBUTION'}`) + .replace(/\$\[process:hash]/g, process.hash) + .replace(/\$\[date:now]/g, moment(Date.now()).format('HH[:]mm[:]ss')) + .replace(/\$\[emoji#0]/g, this.bot.emote('logs', 'shard', 'resume')); + } +}; \ No newline at end of file diff --git a/src/main.js b/src/main.js index 3c7f2c4..216021d 100644 --- a/src/main.js +++ b/src/main.js @@ -22,7 +22,7 @@ globalize(); let Discord, Database; process.argv = require('larg')(process.argv.slice(2)); -process.hash = String.string(Math.floor(Math.random() * 5) + 3); +process.hash = String.string(8); process.handleError = (err, name, type, exit = false, custom = false) => { if (!custom) print(0, `${type ? type : green('Master')} !! ${name ? name : err.name ? err.name : 'Error'} -\n${red(`${err.message && err.stack ? `${err.message}\n${err.stack}` : err}`)}`); @@ -71,10 +71,14 @@ process.on('SIGINT', () => { print(2, `${yellow('Database')} >> ${green('Connected to database')}` ); })(); - if (conf['discord']['enabled']) { print(2, `${cyan('Discord')} >> Creating client...`); Discord = new DiscordClient(conf['discord']['token'], { + webhook :{ + token : conf['discord']['webhook']['token'] || undefined, + channel: conf['discord']['webhook']['channel'] || undefined + }, + clientOptions : { maxShards : 'auto', getAllUsers : false, diff --git a/src/util/sizeOf/detector.js b/src/util/sizeOf/detector.js new file mode 100644 index 0000000..5dd36b4 --- /dev/null +++ b/src/util/sizeOf/detector.js @@ -0,0 +1,13 @@ +'use strict'; + +var typeHandlers = require('./types'); + +module.exports = function (buffer, filepath) { + var type, result; + for (type in typeHandlers) { + result = typeHandlers[type].detect(buffer, filepath); + if (result) { + return type; + } + } +}; diff --git a/src/util/sizeOf/index.js b/src/util/sizeOf/index.js new file mode 100644 index 0000000..22dc8c2 --- /dev/null +++ b/src/util/sizeOf/index.js @@ -0,0 +1,126 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); + +var typeHandlers = require('./types'); +var detector = require('./detector'); + +// Maximum buffer size, with a default of 512 kilobytes. +// TO-DO: make this adaptive based on the initial signature of the image +var MaxBufferSize = 512*1024; + +/** + * Return size information based on a buffer + * + * @param {Buffer} buffer + * @param {String} filepath + * @returns {Object} + */ +function lookup (buffer, filepath) { + // detect the file type.. don't rely on the extension + var type = detector(buffer, filepath); + + // find an appropriate handler for this file type + if (type in typeHandlers) { + var size = typeHandlers[type].calculate(buffer, filepath); + if (size !== false) { + size.type = type; + return size; + } + } + + // throw up, if we don't understand the file + throw new TypeError('unsupported file type: ' + type + ' (file: ' + filepath + ')'); +} + +/** + * Reads a file into a buffer. + * + * The callback will be called after the process has completed. The + * callback's first argument will be an error (or null). The second argument + * will be the Buffer, if the operation was successful. + * + * @param {String} filepath + * @param {Function} callback + */ +function asyncFileToBuffer (filepath, callback) { + // open the file in read only mode + fs.open(filepath, 'r', function (err, descriptor) { + if (err) { return callback(err); } + fs.fstat(descriptor, function (err, stats) { + if (err) { return callback(err); } + var size = stats.size; + if (size <= 0) { + return callback(new Error('File size is not greater than 0 —— ' + filepath)); + } + var bufferSize = Math.min(size, MaxBufferSize); + var buffer = Buffer.alloc(bufferSize); + // read first buffer block from the file, asynchronously + fs.read(descriptor, buffer, 0, bufferSize, 0, function (err) { + if (err) { return callback(err); } + // close the file, we are done + fs.close(descriptor, function (err) { + callback(err, buffer); + }); + }); + }); + }); +} + +/** + * Synchronously reads a file into a buffer, blocking the nodejs process. + * + * @param {String} filepath + * @returns {Buffer} + */ +function syncFileToBuffer (filepath) { + // read from the file, synchronously + var descriptor = fs.openSync(filepath, 'r'); + var size = fs.fstatSync(descriptor).size; + var bufferSize = Math.min(size, MaxBufferSize); + var buffer = Buffer.alloc(bufferSize); + fs.readSync(descriptor, buffer, 0, bufferSize, 0); + fs.closeSync(descriptor); + return buffer; +} + +/** + * @param {Buffer|string} input - buffer or relative/absolute path of the image file + * @param {Function} callback - optional function for async detection + */ +module.exports = function (input, callback) { + + // Handle buffer input + if (Buffer.isBuffer(input)) { + return lookup(input); + } + + // input should be a string at this point + if (typeof input !== 'string') { + throw new TypeError('invalid invocation'); + } + + // resolve the file path + var filepath = path.resolve(input); + + if (typeof callback === 'function') { + asyncFileToBuffer(filepath, function (err, buffer) { + if (err) { return callback(err); } + + // return the dimensions + var dimensions; + try { + dimensions = lookup(buffer, filepath); + } catch (e) { + err = e; + } + callback(err, dimensions); + }); + } else { + var buffer = syncFileToBuffer(filepath); + return lookup(buffer, filepath); + } +}; + +module.exports.types = Object.keys(typeHandlers); diff --git a/src/util/sizeOf/readUInt.js b/src/util/sizeOf/readUInt.js new file mode 100644 index 0000000..9bceff4 --- /dev/null +++ b/src/util/sizeOf/readUInt.js @@ -0,0 +1,11 @@ +'use strict'; + +// Abstract reading multi-byte unsigned integers +function readUInt (buffer, bits, offset, isBigEndian) { + offset = offset || 0; + var endian = isBigEndian ? 'BE' : 'LE'; + var method = buffer['readUInt' + bits + endian]; + return method.call(buffer, offset); +} + +module.exports = readUInt; diff --git a/src/util/sizeOf/types.js b/src/util/sizeOf/types.js new file mode 100644 index 0000000..b27da76 --- /dev/null +++ b/src/util/sizeOf/types.js @@ -0,0 +1,19 @@ +'use strict'; + +// load all available handlers for browserify support +var typeHandlers = { + bmp: require('./types/bmp'), + cur: require('./types/cur'), + dds: require('./types/dds'), + gif: require('./types/gif'), + icns: require('./types/icns'), + ico: require('./types/ico'), + jpg: require('./types/jpg'), + png: require('./types/png'), + psd: require('./types/psd'), + svg: require('./types/svg'), + tiff: require('./types/tiff'), + webp: require('./types/webp'), +}; + +module.exports = typeHandlers; diff --git a/src/util/sizeOf/types/bmp.js b/src/util/sizeOf/types/bmp.js new file mode 100644 index 0000000..ada0141 --- /dev/null +++ b/src/util/sizeOf/types/bmp.js @@ -0,0 +1,17 @@ +'use strict'; + +function isBMP (buffer) { + return ('BM' === buffer.toString('ascii', 0, 2)); +} + +function calculate (buffer) { + return { + 'width': buffer.readUInt32LE(18), + 'height': Math.abs(buffer.readInt32LE(22)) + }; +} + +module.exports = { + 'detect': isBMP, + 'calculate': calculate +}; diff --git a/src/util/sizeOf/types/cur.js b/src/util/sizeOf/types/cur.js new file mode 100644 index 0000000..c4449b9 --- /dev/null +++ b/src/util/sizeOf/types/cur.js @@ -0,0 +1,17 @@ +'use strict'; + +var TYPE_CURSOR = 2; + +function isCUR (buffer) { + var type; + if (buffer.readUInt16LE(0) !== 0) { + return false; + } + type = buffer.readUInt16LE(2); + return type === TYPE_CURSOR; +} + +module.exports = { + 'detect': isCUR, + 'calculate': require('./ico').calculate +}; diff --git a/src/util/sizeOf/types/dds.js b/src/util/sizeOf/types/dds.js new file mode 100644 index 0000000..ae46447 --- /dev/null +++ b/src/util/sizeOf/types/dds.js @@ -0,0 +1,18 @@ +'use strict'; + +function isDDS(buffer){ + return buffer.readUInt32LE(0) === 0x20534444; +} + +function calculate(buffer){ + // read file resolution metadata + return { + 'height': buffer.readUInt32LE(12), + 'width': buffer.readUInt32LE(16) + }; +} + +module.exports = { + 'detect': isDDS, + 'calculate': calculate +}; diff --git a/src/util/sizeOf/types/gif.js b/src/util/sizeOf/types/gif.js new file mode 100644 index 0000000..b497079 --- /dev/null +++ b/src/util/sizeOf/types/gif.js @@ -0,0 +1,19 @@ +'use strict'; + +var gifRegexp = /^GIF8[79]a/; +function isGIF (buffer) { + var signature = buffer.toString('ascii', 0, 6); + return (gifRegexp.test(signature)); +} + +function calculate(buffer) { + return { + 'width': buffer.readUInt16LE(6), + 'height': buffer.readUInt16LE(8) + }; +} + +module.exports = { + 'detect': isGIF, + 'calculate': calculate +}; diff --git a/src/util/sizeOf/types/icns.js b/src/util/sizeOf/types/icns.js new file mode 100644 index 0000000..199b0e6 --- /dev/null +++ b/src/util/sizeOf/types/icns.js @@ -0,0 +1,122 @@ +'use strict'; + +/** + * ICNS Header + * + * | Offset | Size | Purpose | + * | 0 | 4 | Magic literal, must be "icns" (0x69, 0x63, 0x6e, 0x73) | + * | 4 | 4 | Length of file, in bytes, msb first. | + * + **/ +var SIZE_HEADER = 4 + 4; // 8 +var FILE_LENGTH_OFFSET = 4; // MSB => BIG ENDIAN + +/** + * Image Entry + * + * | Offset | Size | Purpose | + * | 0 | 4 | Icon type, see OSType below. | + * | 4 | 4 | Length of data, in bytes (including type and length), msb first. | + * | 8 | n | Icon data | + * + **/ +var ENTRY_LENGTH_OFFSET = 4; // MSB => BIG ENDIAN + +function isICNS (buffer) { + return ('icns' === buffer.toString('ascii', 0, 4)); +} + +var ICON_TYPE_SIZE = { + ICON: 32, + 'ICN#': 32, + // m => 16 x 16 + 'icm#': 16, + icm4: 16, + icm8: 16, + // s => 16 x 16 + 'ics#': 16, + ics4: 16, + ics8: 16, + is32: 16, + s8mk: 16, + icp4: 16, + // l => 32 x 32 + icl4: 32, + icl8: 32, + il32: 32, + l8mk: 32, + icp5: 32, + ic11: 32, + // h => 48 x 48 + ich4: 48, + ich8: 48, + ih32: 48, + h8mk: 48, + // . => 64 x 64 + icp6: 64, + ic12: 32, + // t => 128 x 128 + it32: 128, + t8mk: 128, + ic07: 128, + // . => 256 x 256 + ic08: 256, + ic13: 256, + // . => 512 x 512 + ic09: 512, + ic14: 512, + // . => 1024 x 1024 + ic10: 1024, +}; + +function readImageHeader(buffer, imageOffset) { + var imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET; + // returns [type, length] + return [ + buffer.toString('ascii', imageOffset, imageLengthOffset), + buffer.readUInt32BE(imageLengthOffset) + ]; +} + +function getImageSize(type) { + var size = ICON_TYPE_SIZE[type]; + return { width: size, height: size, type: type }; +} + +function calculate (buffer) { + var + bufferLength = buffer.length, + imageOffset = SIZE_HEADER, + fileLength = buffer.readUInt32BE(FILE_LENGTH_OFFSET), + imageHeader, + imageSize, + result; + + imageHeader = readImageHeader(buffer, imageOffset); + imageSize = getImageSize(imageHeader[0]); + imageOffset += imageHeader[1]; + + if (imageOffset === fileLength) { + return imageSize; + } + + result = { + width: imageSize.width, + height: imageSize.height, + images: [imageSize] + }; + + while (imageOffset < fileLength && imageOffset < bufferLength) { + imageHeader = readImageHeader(buffer, imageOffset); + imageSize = getImageSize(imageHeader[0]); + imageOffset += imageHeader[1]; + result.images.push(imageSize); + } + + return result; +} + +module.exports = { + 'detect': isICNS, + 'calculate': calculate +}; diff --git a/src/util/sizeOf/types/ico.js b/src/util/sizeOf/types/ico.js new file mode 100644 index 0000000..5a87cc7 --- /dev/null +++ b/src/util/sizeOf/types/ico.js @@ -0,0 +1,81 @@ +'use strict'; + +var TYPE_ICON = 1; + +/** + * ICON Header + * + * | Offset | Size | Purpose | + * | 0 | 2 | Reserved. Must always be 0. | + * | 2 | 2 | Image type: 1 for icon (.ICO) image, 2 for cursor (.CUR) image. Other values are invalid. | + * | 4 | 2 | Number of images in the file. | + * + **/ +var SIZE_HEADER = 2 + 2 + 2; // 6 + +/** + * Image Entry + * + * | Offset | Size | Purpose | + * | 0 | 1 | Image width in pixels. Can be any number between 0 and 255. Value 0 means width is 256 pixels. | + * | 1 | 1 | Image height in pixels. Can be any number between 0 and 255. Value 0 means height is 256 pixels. | + * | 2 | 1 | Number of colors in the color palette. Should be 0 if the image does not use a color palette. | + * | 3 | 1 | Reserved. Should be 0. | + * | 4 | 2 | ICO format: Color planes. Should be 0 or 1. | + * | | | CUR format: The horizontal coordinates of the hotspot in number of pixels from the left. | + * | 6 | 2 | ICO format: Bits per pixel. | + * | | | CUR format: The vertical coordinates of the hotspot in number of pixels from the top. | + * | 8 | 4 | The size of the image's data in bytes | + * | 12 | 4 | The offset of BMP or PNG data from the beginning of the ICO/CUR file | + * + **/ +var SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4; // 16 + +function isICO (buffer) { + var type; + if (buffer.readUInt16LE(0) !== 0) { + return false; + } + type = buffer.readUInt16LE(2); + return type === TYPE_ICON; +} + +function getSizeFromOffset(buffer, offset) { + var value = buffer.readUInt8(offset); + return value === 0 ? 256 : value; +} + +function getImageSize(buffer, imageIndex) { + var offset = SIZE_HEADER + (imageIndex * SIZE_IMAGE_ENTRY); + return { + 'width': getSizeFromOffset(buffer, offset), + 'height': getSizeFromOffset(buffer, offset + 1) + }; +} + +function calculate (buffer) { + var + nbImages = buffer.readUInt16LE(4), + result = getImageSize(buffer, 0), + imageIndex; + + if (nbImages === 1) { + return result; + } + + result.images = [{ + width: result.width, + height: result.height + }]; + + for (imageIndex = 1; imageIndex < nbImages; imageIndex += 1) { + result.images.push(getImageSize(buffer, imageIndex)); + } + + return result; +} + +module.exports = { + 'detect': isICO, + 'calculate': calculate +}; diff --git a/src/util/sizeOf/types/jpg.js b/src/util/sizeOf/types/jpg.js new file mode 100644 index 0000000..68a2270 --- /dev/null +++ b/src/util/sizeOf/types/jpg.js @@ -0,0 +1,145 @@ +'use strict'; + +// NOTE: we only support baseline and progressive JPGs here +// due to the structure of the loader class, we only get a buffer +// with a maximum size of 4096 bytes. so if the SOF marker is outside +// if this range we can't detect the file size correctly. + +function isJPG (buffer) { //, filepath + var SOIMarker = buffer.toString('hex', 0, 2); + return ('ffd8' === SOIMarker); +} + +function isEXIF (buffer) { //, filepath + var exifMarker = buffer.toString('hex', 2, 6); + return (exifMarker === '45786966'); // 'Exif' +} + +function extractSize (buffer, i) { + return { + 'height' : buffer.readUInt16BE(i), + 'width' : buffer.readUInt16BE(i + 2) + }; +} + +var APP1_DATA_SIZE_BYTES = 2; +var EXIF_HEADER_BYTES = 6; +var TIFF_BYTE_ALIGN_BYTES = 2; +var MOTOROLA_BYTE_ALIGN = '4d4d'; + +// Each entry is exactly 12 bytes +var IDF_ENTRY_BYTES = 12; +var NUM_DIRECTORY_ENTRIES_BYTES = 2; + +function extractOrientation (buffer, i) { + // Skip APP1 Data Size + var exifBlock = buffer.slice(APP1_DATA_SIZE_BYTES, i); + + // TODO: support intel byte alignment + var byteAlign = exifBlock.toString('hex', EXIF_HEADER_BYTES, EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES); + if (byteAlign !== MOTOROLA_BYTE_ALIGN) { + return; + } + + // TODO: assert that this contains 0x002A + // var STATIC_MOTOROLA_TIFF_HEADER_BYTES = 2; + // var TIFF_IMAGE_FILE_DIRECTORY_BYTES = 4; + + // TODO: derive from TIFF_IMAGE_FILE_DIRECTORY_BYTES + var idfOffset = 8; + + // IDF osset works from right after the header bytes + // (so the offset includes the tiff byte align) + var offset = EXIF_HEADER_BYTES + idfOffset; + + var idfDirectoryEntries = exifBlock.readUInt16BE(offset); + + var start; + var end; + for (var directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) { + start = offset + NUM_DIRECTORY_ENTRIES_BYTES + (directoryEntryNumber * IDF_ENTRY_BYTES); + end = start + IDF_ENTRY_BYTES; + + var block = exifBlock.slice(start, end); + var tagNumber = block.readUInt16BE(0); + + // 0x0112 (decimal: 274) is the `orientation` tag ID + if (tagNumber === 274) { + var dataFormat = block.readUInt16BE(2); + if (dataFormat !== 3) { + return; + } + + // unsinged int has 2 bytes per component + // if there would more than 4 bytes in total it's a pointer + var numberOfComponents = block.readUInt32BE(4); + if (numberOfComponents !== 1) { + return; + } + + var orientation = block.readUInt16BE(8); + + return orientation; + } + } +} + +function validateBuffer (buffer, i) { + // index should be within buffer limits + if (i > buffer.length) { + throw new TypeError('Corrupt JPG, exceeded buffer limits'); + } + // Every JPEG block must begin with a 0xFF + if (buffer[i] !== 0xFF) { + throw new TypeError('Invalid JPG, marker table corrupted'); + } +} + +function calculate (buffer) { + // Skip 4 chars, they are for signature + buffer = buffer.slice(4); + + var orientation; + + var i, next; + while (buffer.length) { + // read length of the next block + i = buffer.readUInt16BE(0); + + + if (isEXIF(buffer)) { + orientation = extractOrientation(buffer, i); + } + + // ensure correct format + validateBuffer(buffer, i); + + // 0xFFC0 is baseline standard(SOF) + // 0xFFC1 is baseline optimized(SOF) + // 0xFFC2 is progressive(SOF2) + next = buffer[i + 1]; + if (next === 0xC0 || next === 0xC1 || next === 0xC2) { + var size = extractSize(buffer, i + 5); + + if (!orientation) { + return size; + } + + return { + width: size.width, + height: size.height, + orientation: orientation + }; + } + + // move to the next block + buffer = buffer.slice(i + 2); + } + + throw new TypeError('Invalid JPG, no size found'); +} + +module.exports = { + 'detect': isJPG, + 'calculate': calculate +}; diff --git a/src/util/sizeOf/types/png.js b/src/util/sizeOf/types/png.js new file mode 100644 index 0000000..78b9535 --- /dev/null +++ b/src/util/sizeOf/types/png.js @@ -0,0 +1,38 @@ +'use strict'; + +var pngSignature = 'PNG\r\n\x1a\n'; +var pngImageHeaderChunkName = 'IHDR'; + +// Used to detect "fried" png's: http://www.jongware.com/pngdefry.html +var pngFriedChunkName = 'CgBI'; + +function isPNG (buffer) { + if (pngSignature === buffer.toString('ascii', 1, 8)) { + var chunkName = buffer.toString('ascii', 12, 16); + if (chunkName === pngFriedChunkName) { + chunkName = buffer.toString('ascii', 28, 32); + } + if (chunkName !== pngImageHeaderChunkName) { + throw new TypeError('invalid png'); + } + return true; + } +} + +function calculate (buffer) { + if (buffer.toString('ascii', 12, 16) === pngFriedChunkName) { + return { + 'width': buffer.readUInt32BE(32), + 'height': buffer.readUInt32BE(36) + }; + } + return { + 'width': buffer.readUInt32BE(16), + 'height': buffer.readUInt32BE(20) + }; +} + +module.exports = { + 'detect': isPNG, + 'calculate': calculate +}; diff --git a/src/util/sizeOf/types/psd.js b/src/util/sizeOf/types/psd.js new file mode 100644 index 0000000..dec4304 --- /dev/null +++ b/src/util/sizeOf/types/psd.js @@ -0,0 +1,17 @@ +'use strict'; + +function isPSD (buffer) { + return ('8BPS' === buffer.toString('ascii', 0, 4)); +} + +function calculate (buffer) { + return { + 'width': buffer.readUInt32BE(18), + 'height': buffer.readUInt32BE(14) + }; +} + +module.exports = { + 'detect': isPSD, + 'calculate': calculate +}; diff --git a/src/util/sizeOf/types/svg.js b/src/util/sizeOf/types/svg.js new file mode 100644 index 0000000..1b821f2 --- /dev/null +++ b/src/util/sizeOf/types/svg.js @@ -0,0 +1,78 @@ +'use strict'; + +var svgReg = /"']|"[^"]*"|'[^']*')*>/; +function isSVG (buffer) { + return svgReg.test(buffer); +} + +var extractorRegExps = { + 'root': svgReg, + 'width': /\bwidth=(['"])([^%]+?)\1/, + 'height': /\bheight=(['"])([^%]+?)\1/, + 'viewbox': /\bviewBox=(['"])(.+?)\1/ +}; + +function parseViewbox (viewbox) { + var bounds = viewbox.split(' '); + return { + 'width': parseInt(bounds[2], 10), + 'height': parseInt(bounds[3], 10) + }; +} + +function parseAttributes (root) { + var width = root.match(extractorRegExps.width); + var height = root.match(extractorRegExps.height); + var viewbox = root.match(extractorRegExps.viewbox); + return { + 'width': width && parseInt(width[2], 10), + 'height': height && parseInt(height[2], 10), + 'viewbox': viewbox && parseViewbox(viewbox[2]) + }; +} + +function calculateByDimensions (attrs) { + return { + 'width': attrs.width, + 'height': attrs.height + }; +} + +function calculateByViewbox (attrs) { + var ratio = attrs.viewbox.width / attrs.viewbox.height; + if (attrs.width) { + return { + 'width': attrs.width, + 'height': Math.floor(attrs.width / ratio) + }; + } + if (attrs.height) { + return { + 'width': Math.floor(attrs.height * ratio), + 'height': attrs.height + }; + } + return { + 'width': attrs.viewbox.width, + 'height': attrs.viewbox.height + }; +} + +function calculate (buffer) { + var root = buffer.toString('utf8').match(extractorRegExps.root); + if (root) { + var attrs = parseAttributes(root[0]); + if (attrs.width && attrs.height) { + return calculateByDimensions(attrs); + } + if (attrs.viewbox) { + return calculateByViewbox(attrs); + } + } + throw new TypeError('invalid svg'); +} + +module.exports = { + 'detect': isSVG, + 'calculate': calculate +}; diff --git a/src/util/sizeOf/types/tiff.js b/src/util/sizeOf/types/tiff.js new file mode 100644 index 0000000..6f50c61 --- /dev/null +++ b/src/util/sizeOf/types/tiff.js @@ -0,0 +1,120 @@ +'use strict'; + +// based on http://www.compix.com/fileformattif.htm +// TO-DO: support big-endian as well + +var fs = require('fs'); +var readUInt = require('../readUInt'); + +function isTIFF (buffer) { + var hex4 = buffer.toString('hex', 0, 4); + return ('49492a00' === hex4 || '4d4d002a' === hex4); +} + +// Read IFD (image-file-directory) into a buffer +function readIFD (buffer, filepath, isBigEndian) { + + var ifdOffset = readUInt(buffer, 32, 4, isBigEndian); + + // read only till the end of the file + var bufferSize = 1024; + var fileSize = fs.statSync(filepath).size; + if (ifdOffset + bufferSize > fileSize) { + bufferSize = fileSize - ifdOffset - 10; + } + + // populate the buffer + var endBuffer = Buffer.alloc(bufferSize); + var descriptor = fs.openSync(filepath, 'r'); + fs.readSync(descriptor, endBuffer, 0, bufferSize, ifdOffset); + + // var ifdLength = readUInt(endBuffer, 16, 0, isBigEndian); + var ifdBuffer = endBuffer.slice(2); //, 2 + 12 * ifdLength); + return ifdBuffer; +} + +// TIFF values seem to be messed up on Big-Endian, this helps +function readValue (buffer, isBigEndian) { + var low = readUInt(buffer, 16, 8, isBigEndian); + var high = readUInt(buffer, 16, 10, isBigEndian); + return (high << 16) + low; +} + +// move to the next tag +function nextTag (buffer) { + if (buffer.length > 24) { + return buffer.slice(12); + } +} + +// Extract IFD tags from TIFF metadata +/* eslint-disable complexity */ +function extractTags (buffer, isBigEndian) { + var tags = {}; + var code, type, length; + + while (buffer && buffer.length) { + code = readUInt(buffer, 16, 0, isBigEndian); + type = readUInt(buffer, 16, 2, isBigEndian); + length = readUInt(buffer, 32, 4, isBigEndian); + + // 0 means end of IFD + if (code === 0) { + break; + } else { + // 256 is width, 257 is height + // if (code === 256 || code === 257) { + if (length === 1 && (type === 3 || type === 4)) { + tags[code] = readValue(buffer, isBigEndian); + } + + // move to the next tag + buffer = nextTag(buffer); + } + } + return tags; +} +/* eslint-enable complexity */ + +// Test if the TIFF is Big Endian or Little Endian +function determineEndianness (buffer) { + var signature = buffer.toString('ascii', 0, 2); + if ('II' === signature) { + return 'LE'; + } else if ('MM' === signature) { + return 'BE'; + } +} + +function calculate (buffer, filepath) { + + if (!filepath) { + throw new TypeError('Tiff doesn\'t support buffer'); + } + + // Determine BE/LE + var isBigEndian = determineEndianness(buffer) === 'BE'; + + // read the IFD + var ifdBuffer = readIFD(buffer, filepath, isBigEndian); + + // extract the tags from the IFD + var tags = extractTags(ifdBuffer, isBigEndian); + + var width = tags[256]; + var height = tags[257]; + + if (!width || !height) { + throw new TypeError('Invalid Tiff, missing tags'); + } + + return { + 'width': width, + 'height': height + }; +} + +module.exports = { + 'detect': isTIFF, + 'calculate': calculate +}; diff --git a/src/util/sizeOf/types/webp.js b/src/util/sizeOf/types/webp.js new file mode 100644 index 0000000..9f35c69 --- /dev/null +++ b/src/util/sizeOf/types/webp.js @@ -0,0 +1,71 @@ +'use strict'; + +// based on https://developers.google.com/speed/webp/docs/riff_container + +function isWebP (buffer) { + var riffHeader = 'RIFF' === buffer.toString('ascii', 0, 4); + var webpHeader = 'WEBP' === buffer.toString('ascii', 8, 12); + var vp8Header = 'VP8' === buffer.toString('ascii', 12, 15); + return (riffHeader && webpHeader && vp8Header); +} + +/* eslint-disable complexity */ +function calculate (buffer) { + var chunkHeader = buffer.toString('ascii', 12, 16); + buffer = buffer.slice(20, 30); + + // Extended webp stream signature + if (chunkHeader === 'VP8X') { + var extendedHeader = buffer[0]; + var validStart = (extendedHeader & 0xc0) === 0; + var validEnd = (extendedHeader & 0x01) === 0; + if (validStart && validEnd) { + return calculateExtended(buffer); + } else { + return false; + } + } + + // Lossless webp stream signature + if (chunkHeader === 'VP8 ' && buffer[0] !== 0x2f) { + return calculateLossy(buffer); + } + + // Lossy webp stream signature + var signature = buffer.toString('hex', 3, 6); + if (chunkHeader === 'VP8L' && signature !== '9d012a') { + return calculateLossless(buffer); + } + + return false; +} +/* eslint-enable complexity */ + +function calculateExtended (buffer) { + return { + 'width': 1 + buffer.readUIntLE(4, 3), + 'height': 1 + buffer.readUIntLE(7, 3) + }; +} + +function calculateLossless (buffer) { + return { + 'width': 1 + (((buffer[2] & 0x3F) << 8) | buffer[1]), + 'height': 1 + (((buffer[4] & 0xF) << 10) | (buffer[3] << 2) | + ((buffer[2] & 0xC0) >> 6)) + }; +} + +function calculateLossy (buffer) { + // `& 0x3fff` returns the last 14 bits + // TO-DO: include webp scaling in the calculations + return { + 'width': buffer.readInt16LE(6) & 0x3fff, + 'height': buffer.readInt16LE(8) & 0x3fff + }; +} + +module.exports = { + 'detect': isWebP, + 'calculate': calculate +}; diff --git a/yarn.lock b/yarn.lock index 3ce583c..7751c56 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43,6 +43,11 @@ ansi-escapes@^3.2.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" @@ -60,6 +65,19 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -89,6 +107,21 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +bindings@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.4.0.tgz#909efa49f2ebe07ecd3cb136778f665052040127" + integrity sha512-7znEVX22Djn+nYjxCWKDne0RRloa9XfYa84yk3s+HkE3LpDYZmhArYr9O9huBoHY3/oXispx5LorIX7Sl2CgSQ== + dependencies: + file-uri-to-path "1.0.0" + +bl@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + bluebird@3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -107,6 +140,24 @@ bson@^1.1.0, bson@~1.1.0: resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.0.tgz#bee57d1fb6a87713471af4e32bcae36de814b5b0" integrity sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA== +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + callsites@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3" @@ -126,6 +177,11 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +chownr@^1.0.1, chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" @@ -143,7 +199,12 @@ cli-width@^2.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= -color-convert@^1.9.0: +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -155,6 +216,27 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.0.tgz#d8e9fb096732875774c84bf922815df0308d0ffc" + integrity sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + complex.js@2.0.11: version "2.0.11" resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.11.tgz#09a873fbf15ffd8c18c9c2201ccef425c32b8bf1" @@ -165,6 +247,16 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -195,11 +287,33 @@ decimal.js@10.0.2: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.0.2.tgz#50fd0f9184139f543e5b84c97681534292deb640" integrity sha512-qL5tUTXAWjB5cSBfm0V2a4jO5FaDLumCfwc/0f7WaTOT3WU8pIeq2HHrd98eXHtbey4qFWlaPzfml1JWIoO9TQ== +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -207,6 +321,13 @@ doctrine@^2.1.0: dependencies: esutils "^2.0.2" +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + eris@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/eris/-/eris-0.9.0.tgz#a2796839f7768cd40645c2c6b1bf0c86ba3147f3" @@ -325,6 +446,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + external-editor@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" @@ -364,6 +490,11 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + flat-cache@^1.2.1: version "1.3.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" @@ -379,6 +510,23 @@ fraction.js@4.0.12: resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.12.tgz#0526d47c65a5fb4854df78bc77f7bec708d7b8c3" integrity sha512-8Z1K0VTG4hzYY7kA/1sj4/r1/RWLBD3xwReT/RCrUCbzPszjNQCCsy3ktkU/eaEqX3MYa4pY37a52eiBlPMlhA== +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-copy-file-sync@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz#11bf32c096c10d126e5f6b36d06eece776062918" + integrity sha512-2QY5eeqVv4m2PfyMiEuy9adxNP+ajf+8AR05cEi+OAzPcOj90hvFImeZhTmKLBgSd9EvG33jsD7ZRxsx9dThkQ== + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + dependencies: + minipass "^2.2.1" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -389,6 +537,25 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + glob@^7.1.2, glob@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" @@ -416,6 +583,11 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -449,11 +621,16 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + inquirer@^6.1.0: version "6.2.2" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" @@ -473,6 +650,18 @@ inquirer@^6.1.0: strip-ansi "^5.0.0" through "^2.3.6" +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -483,6 +672,11 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -563,6 +757,11 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -575,7 +774,27 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -mkdirp@^0.5.1: +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minipass@^2.2.1, minipass@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -665,6 +884,16 @@ nabbit@^0.0.2: resolved "https://registry.yarnpkg.com/nabbit/-/nabbit-0.0.2.tgz#35722cbc9745016477449befc3db580d2e9306cb" integrity sha512-2baEoEz/ugzmqTtgzHz03Z3CmmBSgsEeONxnZp++x3QRo8IBfc4FTQsP7R4IFGchYIYlvuFqf02hBGNqXCmaWQ== +nan@^2.12.1: + version "2.12.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" + integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== + +napi-build-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.1.tgz#1381a0f92c39d66bf19852e7873432fc2123e508" + integrity sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -675,12 +904,39 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -object-assign@^4.0.1: +node-abi@^2.2.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.7.0.tgz#e2f814088ab97c85504ae2bacb8f93d5d77cbc2b" + integrity sha512-egTtvNoZLMjwxkL/5iiJKYKZgn2im0zP+G+PncMxICYGiD3aZtXUvEsDmu0pF8gpASvLZyD8v53qi1/ELaRZpg== + dependencies: + semver "^5.4.1" + +noop-logger@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" + integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= + +npmlog@^4.0.1, npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -711,6 +967,11 @@ opusscript@^0.0.4: resolved "https://registry.yarnpkg.com/opusscript/-/opusscript-0.0.4.tgz#c718edcfdcd2a1f55fadb266dd07268d4a46afde" integrity sha512-bEPZFE2lhUJYQD5yfTFO4RhbRZ937x6hRwBC1YoGacT35bwDVwKFP1+amU8NYfZL/v4EU7ZTU3INTqzYAnuP7Q== +os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -738,21 +999,87 @@ path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +prebuild-install@^5.2.2: + version "5.2.3" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.2.3.tgz#096f5116e63eeef57ae533a2ee460b13d7872704" + integrity sha512-sdijGV8EkK244XbYJLRhOLiHj9QZKUaYW6uDotEPpRGrC5FUXFr6mZhGHr9NjhU0MISI+JSqZ0geVZMs2kIDRQ== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.0" + mkdirp "^0.5.1" + napi-build-utils "^1.0.1" + node-abi "^2.2.0" + noop-logger "^0.1.1" + npmlog "^4.0.1" + os-homedir "^1.0.1" + pump "^2.0.1" + rc "^1.2.7" + simple-get "^2.7.0" + tar-fs "^1.13.0" + tunnel-agent "^0.6.0" + which-pm-runs "^1.0.0" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +pump@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" + integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +readable-stream@^2.0.6, readable-stream@^2.3.0, readable-stream@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + regexp-clone@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-0.0.1.tgz#a7c2e09891fdbf38fbb10d376fb73003e68ac589" @@ -810,7 +1137,7 @@ rxjs@^6.4.0: dependencies: tslib "^1.9.0" -safe-buffer@5.1.2, safe-buffer@^5.1.2: +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -832,11 +1159,33 @@ seed-random@2.2.0: resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54" integrity sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ= -semver@^5.1.0, semver@^5.5.0, semver@^5.5.1: +semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +sharp@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.21.3.tgz#381937de66c123687f2ac7186f85921c6bb19cdd" + integrity sha512-5qZk8r+YgfyztLEKkNez20Wynq/Uh1oNyP5T/3gTYwt2lBYGs9iDs5m0yVsZEPm8eVBbAJhS08J1wp/g+Ai1Qw== + dependencies: + bindings "^1.3.1" + color "^3.1.0" + detect-libc "^1.0.3" + fs-copy-file-sync "^1.1.1" + nan "^2.12.1" + npmlog "^4.1.2" + prebuild-install "^5.2.2" + semver "^5.6.0" + simple-get "^3.0.3" + tar "^4.4.8" + tunnel-agent "^0.6.0" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -849,11 +1198,41 @@ shebang-regex@^1.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -signal-exit@^3.0.2: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= + +simple-get@^2.7.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" + integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-get@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.0.3.tgz#924528ac3f9d7718ce5e9ec1b1a69c0be4d62efa" + integrity sha512-Wvre/Jq5vgoz31Z9stYWPLn0PqRqmBDpFSdypAnHu5AvRVCYPRYGnvryNLiXu8GOBNDH82J2FRHUGMjjHUpXFw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + slice-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" @@ -880,7 +1259,16 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -string-width@^2.1.0, string-width@^2.1.1: +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -888,6 +1276,20 @@ string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -902,7 +1304,7 @@ strip-ansi@^5.0.0: dependencies: ansi-regex "^4.0.0" -strip-json-comments@^2.0.1: +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -924,6 +1326,42 @@ table@^5.0.2, table@^5.1.0: slice-ansi "^2.0.0" string-width "^2.1.1" +tar-fs@^1.13.0: + version "1.16.3" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" + integrity sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw== + dependencies: + chownr "^1.0.1" + mkdirp "^0.5.1" + pump "^1.0.0" + tar-stream "^1.1.2" + +tar-stream@^1.1.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +tar@^4.4.8: + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.4" + minizlib "^1.1.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -946,11 +1384,23 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + tweetnacl@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.1.tgz#2594d42da73cd036bd0d2a54683dd35a6b55ca17" @@ -975,11 +1425,21 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + vm2@^3.6.3: version "3.6.10" resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.6.10.tgz#a9066c3849ad8a3ea35b9c0cf79a6589ce6e3cbe" integrity sha512-p4LBl7theIhmKaWPdCn25kEIG0bfDDEDx1lexXH7gcCu9pHIT+PKFgofwLHVHUGhe39lKExeaYVEZtdbQhdl2g== +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -987,6 +1447,13 @@ which@^1.2.9: dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -1015,3 +1482,13 @@ wumpfetch@^0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/wumpfetch/-/wumpfetch-0.0.5.tgz#c9afe264eb4190b9e4ecb5839c98e0a2c9ecf143" integrity sha512-FqLFJCPX7A61egdlGQ6yK9eTWkHP1+n2+BJoW6S+1foRzqiV9sr2b9Tdw+w/jnW7MqcqZ+j1SAmcKfVxSYsEgA== + +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==