From 83f3b796f0386a2b9aa649dbe9f7de7707cec601 Mon Sep 17 00:00:00 2001 From: danielcardeenas Date: Thu, 2 Apr 2020 18:12:06 -0600 Subject: [PATCH] Add modular listeners --- package-lock.json | 2689 ++++++++++++++++- package.json | 8 +- src/api/functions/send-image.ts | 1 - src/api/functions/send-text.ts | 19 + src/api/helpers/exposed.enum.ts | 4 + src/api/model/ack-type.ts | 8 + src/api/model/chat-state.ts | 5 + src/api/model/chat.ts | 3 + src/api/model/contact.ts | 2 + src/api/model/group-change-event.ts | 4 + src/api/model/group-metadata.ts | 2 +- src/api/model/group-notification-type.ts | 11 + src/api/model/index.ts | 7 + src/api/model/live-location.ts | 9 + src/api/model/message-type.ts | 14 + src/api/model/message.ts | 8 +- src/api/model/partial-message.ts | 24 + src/api/model/participant-event.ts | 7 + src/api/whatsapp.ts | 1013 ++++++- src/lib/middleware/middleware.ts | 20 +- .../wapi/functions/are-all-messages-loaded.js | 14 + src/lib/wapi/functions/clear-chat.js | 7 + src/lib/wapi/functions/delete-conversation.js | 31 + src/lib/wapi/functions/delete-messages.js | 46 + .../download-file-with-credentials.js | 30 + .../functions/get-all-chats-with-messages.js | 5 +- .../wapi/functions/get-all-group-metadata.js | 12 + .../functions/get-all-messages-in-chat.js | 32 + .../wapi/functions/get-all-new-messages.js | 4 +- .../wapi/functions/get-all-unread-messages.js | 5 +- src/lib/wapi/functions/get-battery-level.js | 15 + src/lib/wapi/functions/get-common-groups.js | 29 + src/lib/wapi/functions/get-group-admins.js | 15 + src/lib/wapi/functions/get-group-metadata.js | 11 + .../functions/get-group-participant-ids.js | 16 + .../wapi/functions/get-group-participants.js | 8 + src/lib/wapi/functions/get-host.js | 6 + src/lib/wapi/functions/get-me.js | 9 + src/lib/wapi/functions/get-number-profile.js | 29 + .../functions/get-profile-pic-from-server.js | 7 + src/lib/wapi/functions/get-unread-messages.js | 93 + src/lib/wapi/functions/index.js | 58 +- src/lib/wapi/functions/is-connected.js | 14 + .../load-and-get-all-messages-in-chat.js | 35 + .../load-earlier-messages-til-date.js | 20 + src/lib/wapi/functions/revoke-invite-link.js | 10 + .../wapi/functions/send-message-with-tags.js | 39 + src/lib/wapi/functions/send-message.js | 24 +- src/lib/wapi/functions/send-message2.js | 2 +- src/lib/wapi/functions/send-seen.js | 21 + src/lib/wapi/helper/is-chat-message.js | 16 + .../add-all-new-messages.listener.js | 11 + .../listeners/add-new-messages.listener.js | 17 + src/lib/wapi/listeners/index.js | 3 + src/lib/wapi/listeners/init-listeners.js | 73 + src/lib/wapi/store/get-store.js | 13 +- src/lib/wapi/store/store-objects.js | 10 +- src/lib/wapi/wapi.js | 1455 ++++----- 58 files changed, 5288 insertions(+), 815 deletions(-) create mode 100644 src/api/functions/send-text.ts create mode 100644 src/api/model/ack-type.ts create mode 100644 src/api/model/chat-state.ts create mode 100644 src/api/model/group-change-event.ts create mode 100644 src/api/model/group-notification-type.ts create mode 100644 src/api/model/live-location.ts create mode 100644 src/api/model/message-type.ts create mode 100644 src/api/model/partial-message.ts create mode 100644 src/api/model/participant-event.ts create mode 100644 src/lib/wapi/functions/are-all-messages-loaded.js create mode 100644 src/lib/wapi/functions/clear-chat.js create mode 100644 src/lib/wapi/functions/delete-conversation.js create mode 100644 src/lib/wapi/functions/delete-messages.js create mode 100644 src/lib/wapi/functions/download-file-with-credentials.js create mode 100644 src/lib/wapi/functions/get-all-group-metadata.js create mode 100644 src/lib/wapi/functions/get-all-messages-in-chat.js create mode 100644 src/lib/wapi/functions/get-battery-level.js create mode 100644 src/lib/wapi/functions/get-common-groups.js create mode 100644 src/lib/wapi/functions/get-group-admins.js create mode 100644 src/lib/wapi/functions/get-group-metadata.js create mode 100644 src/lib/wapi/functions/get-group-participant-ids.js create mode 100644 src/lib/wapi/functions/get-group-participants.js create mode 100644 src/lib/wapi/functions/get-host.js create mode 100644 src/lib/wapi/functions/get-me.js create mode 100644 src/lib/wapi/functions/get-number-profile.js create mode 100644 src/lib/wapi/functions/get-profile-pic-from-server.js create mode 100644 src/lib/wapi/functions/get-unread-messages.js create mode 100644 src/lib/wapi/functions/is-connected.js create mode 100644 src/lib/wapi/functions/load-and-get-all-messages-in-chat.js create mode 100644 src/lib/wapi/functions/load-earlier-messages-til-date.js create mode 100644 src/lib/wapi/functions/revoke-invite-link.js create mode 100644 src/lib/wapi/functions/send-message-with-tags.js create mode 100644 src/lib/wapi/functions/send-seen.js create mode 100644 src/lib/wapi/helper/is-chat-message.js create mode 100644 src/lib/wapi/listeners/add-all-new-messages.listener.js create mode 100644 src/lib/wapi/listeners/add-new-messages.listener.js create mode 100644 src/lib/wapi/listeners/index.js create mode 100644 src/lib/wapi/listeners/init-listeners.js diff --git a/package-lock.json b/package-lock.json index 97fa8d24..1326fd53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sulla", - "version": "1.1.3", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -76,6 +76,15 @@ "@types/node": "*" } }, + "@types/sharp": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.24.0.tgz", + "integrity": "sha512-+0WeyJajTSoIacBzonsq856whNJC+cN9FNEs0yZ6hFq/V1CZmlqM8vBRy7TKZunH+gIO7SwDCzgXYWRRbzqfDA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -319,11 +328,19 @@ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", "dev": true }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "ansi-styles": { "version": "3.2.1", @@ -333,6 +350,12 @@ "color-convert": "^1.9.0" } }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true + }, "anymatch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", @@ -343,24 +366,65 @@ "picomatch": "^2.0.4" } }, + "append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, + "requires": { + "buffer-equal": "^1.0.0" + } + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, + "arr-filter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", + "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", + "dev": true, + "requires": { + "make-iterator": "^1.0.0" + } + }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, + "arr-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", + "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", + "dev": true, + "requires": { + "make-iterator": "^1.0.0" + } + }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", @@ -373,6 +437,72 @@ "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", "dev": true }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-initial": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", + "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", + "dev": true, + "requires": { + "array-slice": "^1.0.0", + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, + "array-last": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", + "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "dev": true, + "requires": { + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, + "array-sort": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", + "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "dev": true, + "requires": { + "default-compare": "^1.0.0", + "get-value": "^2.0.6", + "kind-of": "^5.0.2" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -441,6 +571,18 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "async-done": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", + "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.2", + "process-nextick-args": "^2.0.0", + "stream-exhaust": "^1.0.1" + } + }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", @@ -452,12 +594,46 @@ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, + "async-settle": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", + "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", + "dev": true, + "requires": { + "async-done": "^1.2.2" + } + }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "bach": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", + "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", + "dev": true, + "requires": { + "arr-filter": "^1.1.1", + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "array-each": "^1.0.0", + "array-initial": "^1.0.0", + "array-last": "^1.1.1", + "async-done": "^1.2.2", + "async-settle": "^1.0.0", + "now-and-later": "^2.0.0" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -521,8 +697,7 @@ "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" }, "big.js": { "version": "5.2.2", @@ -536,6 +711,42 @@ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", "dev": true }, + "bl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", + "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "buffer": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.5.0.tgz", + "integrity": "sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -674,6 +885,12 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" }, + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -795,8 +1012,7 @@ "chownr": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", - "dev": true + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==" }, "chrome-trace-event": { "version": "1.0.2", @@ -909,6 +1125,45 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", + "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", + "dev": true, + "requires": { + "arr-map": "^2.0.2", + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -919,6 +1174,15 @@ "object-visit": "^1.0.0" } }, + "color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -932,6 +1196,21 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -1031,12 +1310,26 @@ "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", "dev": true }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, "copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", @@ -1057,6 +1350,16 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "copy-props": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", + "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", + "dev": true, + "requires": { + "each-props": "^1.3.0", + "is-plain-object": "^2.0.1" + } + }, "copy-webpack-plugin": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz", @@ -1228,6 +1531,16 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "date-fns": { "version": "2.11.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.11.1.tgz", @@ -1254,10 +1567,40 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "requires": { + "mimic-response": "^2.0.0" + } + }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "default-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", + "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", + "dev": true, + "requires": { + "kind-of": "^5.0.2" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "default-resolution": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", + "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", "dev": true }, "defaults": { @@ -1268,6 +1611,15 @@ "clone": "^1.0.2" } }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", @@ -1309,6 +1661,11 @@ } } }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, "des.js": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", @@ -1325,6 +1682,11 @@ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -1378,6 +1740,16 @@ "stream-shift": "^1.0.0" } }, + "each-props": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", + "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.1", + "object.defaults": "^1.1.0" + } + }, "elliptic": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", @@ -1409,7 +1781,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -1443,6 +1814,50 @@ "is-arrayish": "^0.2.1" } }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1554,6 +1969,11 @@ } } }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -1563,6 +1983,29 @@ "homedir-polyfill": "^1.0.1" } }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dev": true, + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", + "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", @@ -1688,6 +2131,18 @@ } } }, + "fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + } + }, "fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", @@ -1933,6 +2388,25 @@ } } }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -1943,21 +2417,53 @@ "readable-stream": "^2.3.6" } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", "requires": { - "map-cache": "^0.2.2" - } - }, + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -1968,6 +2474,29 @@ "readable-stream": "^2.0.0" } }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, + "fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + } + }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -1992,6 +2521,60 @@ "dev": true, "optional": true }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "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" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2013,6 +2596,11 @@ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + }, "glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", @@ -2035,6 +2623,807 @@ "is-glob": "^4.0.1" } }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "dependencies": { + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-watcher": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", + "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-done": "^1.2.0", + "chokidar": "^2.0.0", + "is-negated-glob": "^1.0.0", + "just-debounce": "^1.0.0", + "object.defaults": "^1.1.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fsevents": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "dev": true, + "optional": true, + "requires": { + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, "global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", @@ -2104,6 +3493,15 @@ } } }, + "glogg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", + "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "dev": true, + "requires": { + "sparkles": "^1.0.0" + } + }, "got": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", @@ -2137,11 +3535,220 @@ "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", "dev": true }, + "gulp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", + "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "dev": true, + "requires": { + "glob-watcher": "^5.0.3", + "gulp-cli": "^2.2.0", + "undertaker": "^1.2.1", + "vinyl-fs": "^3.0.0" + }, + "dependencies": { + "ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "dev": true, + "requires": { + "ansi-wrap": "^0.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "gulp-cli": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz", + "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1", + "archy": "^1.0.0", + "array-sort": "^1.0.0", + "color-support": "^1.1.3", + "concat-stream": "^1.6.0", + "copy-props": "^2.0.1", + "fancy-log": "^1.3.2", + "gulplog": "^1.0.0", + "interpret": "^1.1.0", + "isobject": "^3.0.1", + "liftoff": "^3.1.0", + "matchdep": "^2.0.0", + "mute-stdout": "^1.0.0", + "pretty-hrtime": "^1.0.0", + "replace-homedir": "^1.0.0", + "semver-greatest-satisfied-range": "^1.1.0", + "v8flags": "^3.0.1", + "yargs": "^7.1.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.0" + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "^3.0.0" + } + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "^1.0.0" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -2334,8 +3941,7 @@ "ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, "iferr": { "version": "0.1.5", @@ -2449,8 +4055,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "interpret": { "version": "1.2.0", @@ -2464,6 +4069,16 @@ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -2576,8 +4191,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-glob": { "version": "4.0.1", @@ -2603,6 +4217,12 @@ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -2645,16 +4265,46 @@ "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", "dev": true }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, "is-retry-allowed": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", "dev": true }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", "dev": true }, "is-windows": { @@ -2704,6 +4354,12 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -2721,12 +4377,28 @@ } } }, + "just-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", + "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", + "dev": true + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, + "last-run": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", + "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", + "dev": true, + "requires": { + "default-resolution": "^2.0.0", + "es6-weak-map": "^2.0.1" + } + }, "latest-version": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", @@ -2736,6 +4408,15 @@ "package-json": "^4.0.0" } }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", @@ -2745,12 +4426,67 @@ "invert-kv": "^2.0.0" } }, + "lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, + "requires": { + "flush-write-stream": "^1.0.2" + } + }, + "liftoff": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "dev": true, + "requires": { + "extend": "^3.0.0", + "findup-sync": "^3.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + } + }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, "loader-runner": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", @@ -2816,6 +4552,15 @@ "pify": "^3.0.0" } }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -2840,6 +4585,144 @@ "object-visit": "^1.0.0" } }, + "matchdep": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", + "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", + "dev": true, + "requires": { + "findup-sync": "^2.0.0", + "micromatch": "^3.0.4", + "resolve": "^1.4.0", + "stack-trace": "0.0.10" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -2921,6 +4804,11 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -2942,10 +4830,40 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "minizlib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", + "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } }, "mississippi": { "version": "3.0.0", @@ -2987,14 +4905,18 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, + "mkdirp-classic": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz", + "integrity": "sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -3033,6 +4955,12 @@ "minimatch": "^3.0.4" } }, + "mute-stdout": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", + "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", + "dev": true + }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -3057,18 +4985,42 @@ "to-regex": "^3.0.1" } }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node-abi": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.15.0.tgz", + "integrity": "sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg==", + "requires": { + "semver": "^5.4.1" + } + }, + "node-addon-api": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.0.tgz", + "integrity": "sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==" + }, "node-libs-browser": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", @@ -3137,6 +5089,11 @@ } } }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + }, "nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -3164,6 +5121,15 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dev": true, + "requires": { + "once": "^1.3.2" + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -3173,11 +5139,26 @@ "path-key": "^2.0.0" } }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "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": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-copy": { "version": "0.1.0", @@ -3210,6 +5191,12 @@ } } }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -3219,6 +5206,40 @@ "isobject": "^3.0.0" } }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -3228,6 +5249,16 @@ "isobject": "^3.0.1" } }, + "object.reduce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", + "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3324,6 +5355,15 @@ } } }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", @@ -3435,6 +5475,17 @@ "safe-buffer": "^5.1.1" } }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -3445,6 +5496,12 @@ "json-parse-better-errors": "^1.0.1" } }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true + }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", @@ -3498,6 +5555,21 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -3537,6 +5609,21 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -3561,6 +5648,35 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, + "prebuild-install": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz", + "integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==", + "requires": { + "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.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + } + } + }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", @@ -3573,6 +5689,12 @@ "integrity": "sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg==", "dev": true }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true + }, "pretty-quick": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-2.0.1.tgz", @@ -3755,7 +5877,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -3847,7 +5968,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -3858,11 +5978,71 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "dependencies": { + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -3886,6 +6066,15 @@ "picomatch": "^2.0.7" } }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, "regenerator-runtime": { "version": "0.13.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", @@ -3921,6 +6110,27 @@ "rc": "^1.0.1" } }, + "remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + } + }, + "remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, + "requires": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + } + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -3939,6 +6149,23 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "replace-homedir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", + "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1", + "is-absolute": "^1.0.0", + "remove-trailing-separator": "^1.1.0" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4006,6 +6233,15 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, + "requires": { + "value-or-function": "^3.0.0" + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -4090,8 +6326,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "semver-compare": { "version": "1.0.0", @@ -4108,6 +6343,15 @@ "semver": "^5.0.3" } }, + "semver-greatest-satisfied-range": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", + "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", + "dev": true, + "requires": { + "sver-compat": "^1.5.0" + } + }, "semver-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", @@ -4123,8 +6367,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-value": { "version": "2.0.1", @@ -4165,6 +6408,29 @@ "safe-buffer": "^5.0.1" } }, + "sharp": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.25.2.tgz", + "integrity": "sha512-l1GN0kFNtJr3U9i9pt7a+vo2Ij0xv4tTKDIPx8W6G9WELhPwrMyZZJKAAQNBSI785XB4uZfS5Wpz8C9jWV4AFQ==", + "requires": { + "color": "^3.1.2", + "detect-libc": "^1.0.3", + "node-addon-api": "^2.0.0", + "npmlog": "^4.1.2", + "prebuild-install": "^5.3.3", + "semver": "^7.1.3", + "simple-get": "^3.1.0", + "tar": "^6.0.1", + "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "semver": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==" + } + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -4185,6 +6451,36 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + }, + "simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -4362,6 +6658,12 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, + "sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", + "dev": true + }, "spawn-command": { "version": "0.0.2-1", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", @@ -4418,6 +6720,12 @@ "figgy-pudding": "^3.5.1" } }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -4459,6 +6767,12 @@ "stream-shift": "^1.0.0" } }, + "stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "dev": true + }, "stream-http": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", @@ -4482,7 +6796,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -4500,11 +6813,19 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -4520,8 +6841,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { "version": "5.5.0", @@ -4531,12 +6851,82 @@ "has-flag": "^3.0.0" } }, + "sver-compat": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", + "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", + "dev": true, + "requires": { + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true }, + "tar": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.1.tgz", + "integrity": "sha512-bKhKrrz2FJJj5s7wynxy/fyxpE0CmCjmOQ1KV4KkgXFWOgoIT/NbTMnB1n+LFNrNk0SSBVGGxcK5AGsyC+pW5Q==", + "requires": { + "chownr": "^1.1.3", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.3.tgz", + "integrity": "sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "tar-fs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", + "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "tar-stream": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", + "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", + "requires": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "term-size": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", @@ -4634,6 +7024,22 @@ "xtend": "~4.0.1" } }, + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "dev": true + }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -4649,6 +7055,16 @@ "setimmediate": "^1.0.4" } }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -4696,6 +7112,15 @@ "is-number": "^7.0.0" } }, + "to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, + "requires": { + "through2": "^2.0.3" + } + }, "touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", @@ -4743,6 +7168,20 @@ "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -4754,6 +7193,12 @@ "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", "dev": true }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, "undefsafe": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", @@ -4780,6 +7225,29 @@ } } }, + "undertaker": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", + "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "bach": "^1.0.0", + "collection-map": "^1.0.0", + "es6-weak-map": "^2.0.1", + "last-run": "^1.1.0", + "object.defaults": "^1.0.0", + "object.reduce": "^1.0.0", + "undertaker-registry": "^1.0.0" + } + }, + "undertaker-registry": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", + "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", + "dev": true + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -4810,6 +7278,16 @@ "imurmurhash": "^0.1.4" } }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, "unique-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", @@ -4963,6 +7441,15 @@ "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", "dev": true }, + "v8flags": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -4973,6 +7460,85 @@ "spdx-expression-parse": "^3.0.0" } }, + "value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + } + } + }, + "vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "requires": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + } + }, + "vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, + "requires": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -6071,8 +8637,15 @@ "which-pm-runs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } }, "widest-line": { "version": "2.0.1", diff --git a/package.json b/package.json index ae329b4d..efe1a0ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sulla", - "version": "1.1.3", + "version": "2.0.0", "description": "Javascript whatsapp framework", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -41,8 +41,10 @@ "devDependencies": { "@types/node": "^13.9.8", "@types/puppeteer": "^2.0.1", + "@types/sharp": "^0.24.0", "concurrently": "^5.1.0", "copy-webpack-plugin": "^5.1.1", + "gulp": "^4.0.2", "husky": "^4.2.3", "nodemon": "^2.0.2", "prettier": "^2.0.2", @@ -53,9 +55,11 @@ "webpack-cli": "^3.3.11" }, "dependencies": { + "axios": "^0.19.2", "ora": "^4.0.3", "puppeteer": "^2.1.1", "qrcode-terminal": "^0.12.0", - "rxjs": "^6.5.4" + "rxjs": "^6.5.4", + "sharp": "^0.25.2" } } diff --git a/src/api/functions/send-image.ts b/src/api/functions/send-image.ts index 3d75fdcb..bc41b665 100644 --- a/src/api/functions/send-image.ts +++ b/src/api/functions/send-image.ts @@ -1,7 +1,6 @@ import * as fs from 'fs'; declare module WAPI { - // New const sendImage: ( to: string, imgBase64: string, diff --git a/src/api/functions/send-text.ts b/src/api/functions/send-text.ts new file mode 100644 index 00000000..06806630 --- /dev/null +++ b/src/api/functions/send-text.ts @@ -0,0 +1,19 @@ +declare module WAPI { + const sendSeen: (to: string) => void; + const sendMessage: (to: string, content: string) => string; +} + +/** + * Sends a text message to given chat + * @param to chat id: xxxxx@us.c + * @param content text message + */ +export async function sendText(to: string, content: string) { + return await this.page.evaluate( + ({ to, content }) => { + WAPI.sendSeen(to); + return WAPI.sendMessage(to, content); + }, + { to, content } + ); +} diff --git a/src/api/helpers/exposed.enum.ts b/src/api/helpers/exposed.enum.ts index 4028e60d..e242527d 100644 --- a/src/api/helpers/exposed.enum.ts +++ b/src/api/helpers/exposed.enum.ts @@ -1,3 +1,7 @@ export enum ExposedFn { OnMessage = 'onMessage', + OnAnyMessage = 'onAnyMessage', + onAck = 'onAck', + onParticipantsChanged = 'onParticipantsChanged', + onStateChanged = 'onStateChanged', } diff --git a/src/api/model/ack-type.ts b/src/api/model/ack-type.ts new file mode 100644 index 00000000..4e3f779c --- /dev/null +++ b/src/api/model/ack-type.ts @@ -0,0 +1,8 @@ +export enum AckType { + ACK_ERROR = -1, + ACK_PENDING = 0, + ACK_SERVER = 1, + ACK_DEVICE = 2, + ACK_READ = 3, + ACK_PLAYED = 4, +} diff --git a/src/api/model/chat-state.ts b/src/api/model/chat-state.ts new file mode 100644 index 00000000..3408f4ed --- /dev/null +++ b/src/api/model/chat-state.ts @@ -0,0 +1,5 @@ +export enum ChatState { + TYPING = 0, + RECORDING = 1, + PAUSED = 2, +} diff --git a/src/api/model/chat.ts b/src/api/model/chat.ts index 0db8f417..a2478141 100644 --- a/src/api/model/chat.ts +++ b/src/api/model/chat.ts @@ -25,4 +25,7 @@ export interface Chat { presence: any; t: number; unreadCount: number; + ack?: any; + isOnline?: any; + lastSeen?: any; } diff --git a/src/api/model/contact.ts b/src/api/model/contact.ts index 2cd6d3dd..8d832a8a 100644 --- a/src/api/model/contact.ts +++ b/src/api/model/contact.ts @@ -31,4 +31,6 @@ export interface Contact { type: string; verifiedLevel: any; verifiedName: any; + isOnline?: any; + lastSeen?: any; } diff --git a/src/api/model/group-change-event.ts b/src/api/model/group-change-event.ts new file mode 100644 index 00000000..97aa7e3d --- /dev/null +++ b/src/api/model/group-change-event.ts @@ -0,0 +1,4 @@ +export enum GroupChangeEvent { + Remove = 'remove', + Add = 'add', +} diff --git a/src/api/model/group-metadata.ts b/src/api/model/group-metadata.ts index 8ad9be11..59afd9b2 100644 --- a/src/api/model/group-metadata.ts +++ b/src/api/model/group-metadata.ts @@ -1,4 +1,4 @@ -import { Id } from './id'; +import { Id } from '.'; export interface GroupMetadata { id: Id; diff --git a/src/api/model/group-notification-type.ts b/src/api/model/group-notification-type.ts new file mode 100644 index 00000000..632d41ec --- /dev/null +++ b/src/api/model/group-notification-type.ts @@ -0,0 +1,11 @@ +export enum GroupNotificationType { + Add = 'add', + Inivite = 'invite', + Remove = 'remove', + Leave = 'leave', + Subject = 'subject', + Description = 'description', + Picture = 'picture', + Announce = 'announce', + Restrict = 'restrict', +} diff --git a/src/api/model/index.ts b/src/api/model/index.ts index 1af5d391..e6df99a9 100644 --- a/src/api/model/index.ts +++ b/src/api/model/index.ts @@ -1,3 +1,10 @@ export { Chat } from './chat'; +export { ChatState } from './chat-state'; export { Contact } from './contact'; +export { GroupChangeEvent } from './group-change-event'; +export { GroupMetadata } from './group-metadata'; +export { GroupNotificationType } from './group-notification-type'; +export { Id } from './id'; export { Message } from './message'; +export { ParticipantEvent } from './participant-event'; +export { PartialMessage } from './partial-message'; diff --git a/src/api/model/live-location.ts b/src/api/model/live-location.ts new file mode 100644 index 00000000..6c720b6a --- /dev/null +++ b/src/api/model/live-location.ts @@ -0,0 +1,9 @@ +export interface LiveLocation { + id: string; + lat: number; + lng: number; + speed: number; + lastUpdated: number; + accuracy: number; + degrees: any; +} diff --git a/src/api/model/message-type.ts b/src/api/model/message-type.ts new file mode 100644 index 00000000..e86709a2 --- /dev/null +++ b/src/api/model/message-type.ts @@ -0,0 +1,14 @@ +export enum MessageTypes { + TEXT = 'chat', + AUDIO = 'audio', + VOICE = 'ptt', + IMAGE = 'image', + VIDEO = 'video', + DOCUMENT = 'document', + STICKER = 'sticker', + LOCATION = 'location', + CONTACT_CARD = 'vcard', + CONTACT_CARD_MULTI = 'multi_vcard', + REVOKED = 'revoked', + UNKNOWN = 'unknown', +} diff --git a/src/api/model/message.ts b/src/api/model/message.ts index e92cd58c..274b3599 100644 --- a/src/api/model/message.ts +++ b/src/api/model/message.ts @@ -2,12 +2,16 @@ export interface Message { id: string; body: string; type: string; + mimetype?: string; + lat?: string; + lng?: string; + loc?: string; t: number; notifyName: string; from: string; to: string; - author: string; self: string; + duration?: string | number; ack: number; invis: boolean; isNewMsg: boolean; @@ -16,6 +20,7 @@ export interface Message { broadcast: boolean; isForwarded: boolean; labels: any[]; + caption: string; sender: { id: string; name: string; @@ -95,6 +100,7 @@ export interface Message { presence: { id: string; chatstates: any[] }; }; chatId: string; + quotedMsg: any; quotedMsgObj: any; mediaData: {}; } diff --git a/src/api/model/partial-message.ts b/src/api/model/partial-message.ts new file mode 100644 index 00000000..4cf0356e --- /dev/null +++ b/src/api/model/partial-message.ts @@ -0,0 +1,24 @@ +export interface PartialMessage { + id: ID; + body: string; + type: string; + t: number; + notifyName: string; + from: string; + to: string; + self: string; + ack: number; + invis: boolean; + star: boolean; + broadcast: boolean; + mentionedJidList: any[]; + isForwarded: boolean; + labels: any[]; +} + +interface ID { + fromMe: boolean; + remote: string; + id: string; + _serialized: string; +} diff --git a/src/api/model/participant-event.ts b/src/api/model/participant-event.ts new file mode 100644 index 00000000..a50fd402 --- /dev/null +++ b/src/api/model/participant-event.ts @@ -0,0 +1,7 @@ +import { GroupChangeEvent, Id } from '.'; + +export interface ParticipantEvent { + by: Id; + action: GroupChangeEvent; + who: [Id]; +} diff --git a/src/api/whatsapp.ts b/src/api/whatsapp.ts index 05f566a5..e0a048d2 100644 --- a/src/api/whatsapp.ts +++ b/src/api/whatsapp.ts @@ -1,25 +1,173 @@ +import axios from 'axios'; import { Page } from 'puppeteer'; +import * as sharp from 'sharp'; +import { sendText } from './functions/send-text'; import { ExposedFn } from './helpers/exposed.enum'; -import { Chat } from './model/chat'; -import { Contact } from './model/contact'; -import { Id } from './model/id'; +import { + Chat, + ChatState, + Contact, + Id, + PartialMessage, + ParticipantEvent, +} from './model'; +import { LiveLocation } from './model/live-location'; import { Message } from './model/message'; -import { sendImage } from './functions'; - declare module WAPI { const waitNewMessages: (rmCallback: boolean, callback: Function) => void; - const sendMessage: (to: string, content: string) => void; + const allNewMessagesListener: (callback: Function) => void; + const onStateChanged: (callback: Function) => void; + const onAddedToGroup: (callback: Function) => any; + const onParticipantsChanged: (groupId: string, callback: Function) => any; + const onLiveLocation: (chatId: string, callback: Function) => any; + const sendMessage: (to: string, content: string) => string; + const sendMessageWithTags: (to: string, content: string) => string; + const setChatState: (chatState: ChatState, chatId: string) => void; + const reply: ( + to: string, + content: string, + quotedMsg: string | Message + ) => void; + const getGeneratedUserAgent: (userAgent?: string) => string; + const forwardMessages: ( + to: string, + messages: string | (string | Message)[], + skipMyMessages: boolean + ) => any; + const sendLocation: (to: string, lat: any, lng: any, loc: string) => void; + const addParticipant: (groupId: string, contactId: string) => void; + const setMyName: (newName: string) => void; + const setMyStatus: (newStatus: string) => void; + const getStatus: (contactId: string) => void; + const getGroupAdmins: (groupId: string) => Contact[]; + const removeParticipant: (groupId: string, contactId: string) => void; + const promoteParticipant: (groupId: string, contactId: string) => void; + const demoteParticipant: (groupId: string, contactId: string) => void; + const sendImageAsSticker: ( + webpBase64: string, + to: string, + metadata?: any + ) => void; + const createGroup: ( + groupName: string, + contactId: string | string[] + ) => Promise; const sendSeen: (to: string) => void; + const deleteConversation: (chatId: string) => boolean; + const clearChat: (chatId: string) => void; + const getGroupInviteLink: (chatId: string) => Promise | boolean; + const sendImage: ( + base64: string, + to: string, + filename: string, + caption: string + ) => void; + const sendMessageWithThumb: ( + thumb: string, + url: string, + title: string, + description: string, + chatId: string + ) => void; + const getBusinessProfilesProducts: (to: string) => any; + const sendImageWithProduct: ( + base64: string, + to: string, + caption: string, + bizNumber: string, + productId: string + ) => any; + const sendFile: ( + base64: string, + to: string, + filename: string, + caption: string + ) => void; + const sendVideoAsGif: ( + base64: string, + to: string, + filename: string, + caption: string + ) => void; const getAllContacts: () => Contact[]; + const getWAVersion: () => String; + const getMe: () => any; + const getAllUnreadMessages: () => PartialMessage[]; + const getAllChatsWithMessages: (withNewMessageOnly?: boolean) => any; const getAllChats: () => Chat[]; - const getAllChatsWithNewMessages: () => Chat[]; + const getBatteryLevel: () => Number; + const getChat: (contactId: string) => Chat; + const getProfilePicFromServer: (chatId: string) => any; + const getAllChatIds: () => string[]; + const getAllChatsWithNewMsg: () => Chat[]; + const getAllNewMessages: () => any; const getAllGroups: () => Chat[]; const getGroupParticipantIDs: (groupId: string) => Id[]; + const leaveGroup: (groupId: string) => any; const getContact: (contactId: string) => Contact; + const getNumberProfile: (contactId: string) => any; + const getChatById: (contactId: string) => Chat; + const deleteMessages: ( + contactId: string, + messageId: string[] | string, + onlyLocal: boolean + ) => any; const sendContact: (to: string, contact: string | string[]) => any; + const simulateTyping: (to: string, on: boolean) => void; + const isConnected: () => Boolean; + const loadEarlierMessages: (contactId: string) => Message[]; + const loadAllEarlierMessages: (contactId: string) => void; + const asyncLoadAllEarlierMessages: (contactId: string) => void; + const getUnreadMessages: ( + includeMe: boolean, + includeNotifications: boolean, + use_unread_count: boolean + ) => any; + const getAllMessagesInChat: ( + chatId: string, + includeMe: boolean, + includeNotifications: boolean + ) => [Message]; + const loadAndGetAllMessagesInChat: ( + chatId: string, + includeMe: boolean, + includeNotifications: boolean + ) => [Message]; const sendMessageMentioned: (...args: any) => any; } +declare global { + interface Window { + l10n: any; + } +} + +export const getBase64 = async (url: string) => { + try { + const res = await axios.get(url, { + responseType: 'arraybuffer', + }); + return `data:${res.headers['content-type']};base64,${Buffer.from( + res.data, + 'binary' + ).toString('base64')}`; + } catch (error) { + console.log('TCL: getBase64 -> error', error); + } +}; + +function base64MimeType(encoded) { + var result = null; + if (typeof encoded !== 'string') { + return result; + } + var mime = encoded.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+).*,.*/); + if (mime && mime.length) { + result = mime[1]; + } + return result; +} + export class Whatsapp { constructor(public page: Page) { this.page = page; @@ -35,21 +183,424 @@ export class Whatsapp { ); } + /** + * @event Listens to all new messages + * @param to callback + * @fires Message + */ + public async onAnyMessage(fn: (message: Message) => void) { + this.page + .exposeFunction(ExposedFn.OnAnyMessage, (message: Message) => fn(message)) + .then((_) => + this.page.evaluate(() => { + WAPI.allNewMessagesListener(window['onAnyMessage']); + }) + ); + } + + /** + * @event Listens to messages received + * @returns Observable stream of messages + */ + public onStateChanged(fn: (state: string) => void) { + this.page + .exposeFunction(ExposedFn.onStateChanged, (state: string) => fn(state)) + .then(() => + this.page.evaluate(() => { + WAPI.onStateChanged((_) => window['onStateChanged'](_.state)); + }) + ); + } + + /** + * set your about me + * @param newStatus String new profile status + */ + public async setMyStatus(newStatus: string) { + return await this.page.evaluate( + ({ newStatus }) => { + WAPI.setMyStatus(newStatus); + }, + { newStatus } + ); + } + + /** + * Set your profile name + * @param newName String new name to set for your profile + */ + public async setMyName(newName: string) { + return await this.page.evaluate( + ({ newName }) => { + WAPI.setMyName(newName); + }, + { newName } + ); + } + + /** + * Sets the chat state + * @param {ChatState|0|1|2} chatState The state you want to set for the chat. Can be TYPING (0), RECRDING (1) or PAUSED (2). + * @param {String} chatId + */ + public async setChatState(chatState: ChatState, chatId: String) { + return await this.page.evaluate( + ({ chatState, chatId }) => { + WAPI.setChatState(chatState, chatId); + }, + //@ts-ignore + { chatState, chatId } + ); + } + + /** + * Returns the connecction state + * @returns Any of OPENING, PAIRING, UNPAIRED, UNPAIRED_IDLE, CONNECTED, TIMEOUT, CONFLICT, UNLAUNCHED, PROXYBLOCK, TOS_BLOCK, SMB_TOS_BLOCK, DEPRECATED_VERSION + */ + public async getConnectionState() { + return await this.page.evaluate(() => { + //@ts-ignore + return Store.State.default.state; + }); + } + + /** + * @event Listens to messages acknowledgement Changes + * @returns Observable stream of messages + */ + public onAck(fn: (message: Message) => void) { + this.page.exposeFunction(ExposedFn.onAck, (message: Message) => + fn(message) + ); + } + + /** + * Shuts down the page and browser + * @returns true + */ + public async kill() { + console.log('Shutting Down'); + if (this.page) await this.page.close(); + if (this.page.browser) await this.page.browser().close(); + return true; + } + + public async forceRefocus() { + //255 is the address of 'use here' + const useHere: string = await this.page.evaluate(() => { + return window.l10n.localeStrings[window.l10n._locale.l][0][ + window.l10n.localeStrings['en']?.[0].findIndex( + (x: string) => x.toLowerCase() == 'use here' + ) || 257 + ]; + }); + await this.page.waitForFunction( + `[...document.querySelectorAll("div[role=button")].find(e=>{return e.innerHTML.toLowerCase()==="${useHere.toLowerCase()}"})`, + { timeout: 0 } + ); + await this.page.evaluate( + `[...document.querySelectorAll("div[role=button")].find(e=>{return e.innerHTML.toLowerCase()=="${useHere.toLowerCase()}"}).click()` + ); + } + + /** + * @event Listens to live locations from a chat that already has valid live locations + * @param chatId the chat from which you want to subscribes to live location updates + * @param fn callback that takes in a LiveLocation + * @returns boolean, if returns false then there were no valid live locations in the chat of chatId + * @emits LiveLocation + */ + public onLiveLocation( + chatId: string, + fn: (liveLocationChangedEvent: LiveLocation) => void + ) { + const funcName = + 'onLiveLocation_' + chatId.replace('_', '').replace('_', ''); + return this.page + .exposeFunction(funcName, (liveLocationChangedEvent: LiveLocation) => + fn(liveLocationChangedEvent) + ) + .then((_) => + this.page.evaluate( + ({ chatId, funcName }) => { + //@ts-ignore + return WAPI.onLiveLocation(chatId, window[funcName]); + }, + { chatId, funcName } + ) + ); + } + + /** + * @event Listens to add and remove evevnts on Groups + * @param to group id: xxxxx-yyyy@us.c + * @param to callback + * @returns Observable stream of participantChangedEvent + */ + public onParticipantsChanged( + groupId: string, + fn: (participantChangedEvent: ParticipantEvent) => void + ) { + const funcName = + 'onParticipantsChanged_' + groupId.replace('_', '').replace('_', ''); + return this.page + .exposeFunction(funcName, (participantChangedEvent: ParticipantEvent) => + fn(participantChangedEvent) + ) + .then((_) => + this.page.evaluate( + ({ groupId, funcName }) => { + //@ts-ignore + WAPI.onParticipantsChanged(groupId, window[funcName]); + }, + { groupId, funcName } + ) + ); + } + + /** + * @event Fires callback with Chat object every time the host phone is added to a group. + * @param to callback + * @returns Observable stream of Chats + */ + public onAddedToGroup(fn: (chat: Chat) => any) { + const funcName = 'onAddedToGroup'; + return this.page + .exposeFunction(funcName, (chat: any) => fn(chat)) + .then((_) => + this.page.evaluate(() => { + //@ts-ignore + WAPI.onAddedToGroup(window.onAddedToGroup); + }) + ); + } + /** * Sends a text message to given chat * @param to chat id: xxxxx@us.c * @param content text message */ - public async sendText(to: string, content: string) { + public sendText = sendText; + + /** + * Sends a text message to given chat that includes mentions. + * In order to use this method correctly you will need to send the text like this: + * "@4474747474747 how are you?" + * Basically, add a @ symbol before the number of the contact you want to mention. + * @param to chat id: xxxxx@us.c + * @param content text message + */ + public async sendTextWithMentions(to: string, content: string) { return await this.page.evaluate( ({ to, content }) => { WAPI.sendSeen(to); - WAPI.sendMessage(to, content); + return WAPI.sendMessageWithTags(to, content); }, { to, content } ); } + public async sendMessageWithThumb( + thumb: string, + url: string, + title: string, + description: string, + chatId: string + ) { + return await this.page.evaluate( + ({ thumb, url, title, description, chatId }) => { + WAPI.sendMessageWithThumb(thumb, url, title, description, chatId); + }, + { + thumb, + url, + title, + description, + chatId, + } + ); + } + + /** + * Sends a location message to given chat + * @param to chat id: xxxxx@c.us + * @param lat latitude: '51.5074' + * @param lng longitude: '0.1278' + * @param loc location text: 'LONDON!' + */ + public async sendLocation(to: string, lat: any, lng: any, loc: string) { + return await this.page.evaluate( + ({ to, lat, lng, loc }) => { + WAPI.sendLocation(to, lat, lng, loc); + }, + { to, lat, lng, loc } + ); + } + + /** + * Get the generated user agent, this is so you can send it to the decryption module. + * @returns String useragent of wa-web session + */ + public async getGeneratedUserAgent(userAgent: string) { + return await this.page.evaluate( + ({ userAgent }) => WAPI.getGeneratedUserAgent(userAgent), + { userAgent } + ); + } + + /** + * Sends a image to given chat, with caption or not, using base64 + * @param to chat id xxxxx@us.c + * @param base64 base64 data:image/xxx;base64,xxx + * @param filename string xxxxx + * @param caption string xxxxx + */ + public async sendImage( + to: string, + base64: string, + filename: string, + caption: string + ) { + return await this.page.evaluate( + ({ to, base64, filename, caption }) => { + WAPI.sendImage(base64, to, filename, caption); + }, + { to, base64, filename, caption } + ); + } + + /** + * + * @param to string chatid + * @param content string reply text + * @param quotedMsg string | Message the msg object or id to reply to. + */ + public async reply(to: string, content: string, quotedMsg: any) { + return await this.page.evaluate( + ({ to, content, quotedMsg }) => { + WAPI.reply(to, content, quotedMsg); + }, + { to, content, quotedMsg } + ); + } + + /** + * Sends a file to given chat, with caption or not, using base64. This is exactly the same as sendImage + * @param to chat id xxxxx@us.c + * @param base64 base64 data:image/xxx;base64,xxx + * @param filename string xxxxx + * @param caption string xxxxx + */ + public async sendFile( + to: string, + base64: string, + filename: string, + caption: string + ) { + return await this.page.evaluate( + ({ to, base64, filename, caption }) => { + WAPI.sendImage(base64, to, filename, caption); + }, + { to, base64, filename, caption } + ); + } + + /** + * Sends a video to given chat as a gif, with caption or not, using base64 + * @param to chat id xxxxx@us.c + * @param base64 base64 data:video/xxx;base64,xxx + * @param filename string xxxxx + * @param caption string xxxxx + */ + public async sendVideoAsGif( + to: string, + base64: string, + filename: string, + caption: string + ) { + return await this.page.evaluate( + ({ to, base64, filename, caption }) => { + WAPI.sendVideoAsGif(base64, to, filename, caption); + }, + { to, base64, filename, caption } + ); + } + + /** + * Sends a video to given chat as a gif by using a giphy link, with caption or not, using base64 + * @param to chat id xxxxx@us.c + * @param giphyMediaUrl string https://media.giphy.com/media/oYtVHSxngR3lC/giphy.gif => https://i.giphy.com/media/oYtVHSxngR3lC/200w.mp4 + * @param caption string xxxxx + */ + public async sendGiphy(to: string, giphyMediaUrl: string, caption: string) { + var ue = /^https?:\/\/media\.giphy\.com\/media\/([a-zA-Z0-9]+)/; + var n = ue.exec(giphyMediaUrl); + if (n) { + const r = `https://i.giphy.com/${n[1]}.mp4`; + const filename = `${n[1]}.mp4`; + const base64 = await getBase64(r); + return await this.page.evaluate( + ({ to, base64, filename, caption }) => { + WAPI.sendVideoAsGif(base64, to, filename, caption); + }, + { to, base64, filename, caption } + ); + } else { + console.log('something is wrong with this giphy link'); + return; + } + } + + /** + * Returns an object with all of your host device details + */ + public async getMe() { + // return await this.page.evaluate(() => WAPI.getMe()); + //@ts-ignore + return await this.page.evaluate(() => Store.Me.attributes); + } + + /** + * Find any product listings of the given number. Use this to query a catalog + * + * @param id id of buseinss profile (i.e the number with @c.us) + * @param done Optional callback function for async execution + * @returns None + */ + public async getBusinessProfilesProducts(id: string) { + return await this.page.evaluate( + ({ id }) => { + WAPI.getBusinessProfilesProducts(id); + }, + { id } + ); + } + + /** + * Sends product with image to chat + * @param imgBase64 Base64 image data + * @param chatid string the id of the chat that you want to send this product to + * @param caption string the caption you want to add to this message + * @param bizNumber string the @c.us number of the business account from which you want to grab the product + * @param productId string the id of the product within the main catalog of the aforementioned business + * @param done - function - Callback function to be called contained the buffered messages. + * @returns + */ + public async sendImageWithProduct( + to: string, + base64: string, + caption: string, + bizNumber: string, + productId: string + ) { + return await this.page.evaluate( + ({ to, base64, bizNumber, caption, productId }) => { + WAPI.sendImageWithProduct(base64, to, caption, bizNumber, productId); + }, + { to, base64, bizNumber, caption, productId } + ); + } + /** * Sends contact card to given chat id * @param {string} to 'xxxx@c.us' @@ -62,6 +613,38 @@ export class Whatsapp { ); } + /** + * Simulate '...typing' in chat + * @param {string} to 'xxxx@c.us' + * @param {boolean} on turn on similated typing, false to turn it off you need to manually turn this off. + */ + public async simulateTyping(to: string, on: boolean) { + return await this.page.evaluate( + ({ to, on }) => WAPI.simulateTyping(to, on), + { to, on } + ); + } + + /** + * Forward an array of messages to a specific chat using the message ids or Objects + * + * @param {string} to '000000000000@c.us' + * @param {string|array[Message | string]} messages this can be any mixture of message ids or message objects + * @param {boolean} skipMyMessages This indicates whether or not to skip your own messages from the array + */ + + public async forwardMessages( + to: string, + messages: any, + skipMyMessages: boolean + ) { + return await this.page.evaluate( + ({ to, messages, skipMyMessages }) => + WAPI.forwardMessages(to, messages, skipMyMessages), + { to, messages, skipMyMessages } + ); + } + /** * Retrieves all contacts * @returns array of [Contact] @@ -70,18 +653,49 @@ export class Whatsapp { return await this.page.evaluate(() => WAPI.getAllContacts()); } + public async getWAVersion() { + return await this.page.evaluate(() => WAPI.getWAVersion()); + } + + /** + * Retrieves if the phone is online. Please note that this may not be real time. + * @returns Boolean + */ + public async isConnected() { + return await this.page.evaluate(() => WAPI.isConnected()); + } + + /** + * Retrieves Battery Level + * @returns Number + */ + public async getBatteryLevel() { + return await this.page.evaluate(() => WAPI.getBatteryLevel()); + } + /** * Retrieves all chats * @returns array of [Chat] */ public async getAllChats(withNewMessageOnly = false) { if (withNewMessageOnly) { - return await this.page.evaluate(() => WAPI.getAllChatsWithNewMessages()); + return this.page.evaluate(() => WAPI.getAllChatsWithNewMsg()); } else { - return await this.page.evaluate(() => WAPI.getAllChats()); + return this.page.evaluate(() => WAPI.getAllChats()); } } + /** + * Retrieves all chats with messages + * @returns array of [Chat] + */ + public async getAllChatsWithMessages(withNewMessageOnly = false) { + return this.page.evaluate( + (withNewMessageOnly) => WAPI.getAllChatsWithMessages(withNewMessageOnly), + withNewMessageOnly + ); + } + /** * Retrieve all groups * @returns array of groups @@ -89,7 +703,7 @@ export class Whatsapp { public async getAllGroups(withNewMessagesOnly = false) { if (withNewMessagesOnly) { // prettier-ignore - const chats = await this.page.evaluate(() => WAPI.getAllChatsWithNewMessages()); + const chats = await this.page.evaluate(() => WAPI.getAllChatsWithNewMsg()); return chats.filter((chat) => chat.isGroup); } else { const chats = await this.page.evaluate(() => WAPI.getAllChats()); @@ -108,6 +722,17 @@ export class Whatsapp { ); } + /** + * Removes the host device from the group + * @param groupId group id + */ + public async leaveGroup(groupId: string) { + return await this.page.evaluate( + (groupId) => WAPI.leaveGroup(groupId), + groupId + ); + } + /** * Returns group members [Contact] objects * @param groupId @@ -125,6 +750,7 @@ export class Whatsapp { * @param contactId * @returns contact detial as promise */ + //@ts-ignore public async getContact(contactId: string) { return await this.page.evaluate( (contactId) => WAPI.getContact(contactId), @@ -132,6 +758,366 @@ export class Whatsapp { ); } + /** + * Retrieves chat object of given contact id + * @param contactId + * @returns contact detial as promise + */ + public async getChatById(contactId: string) { + return await this.page.evaluate( + (contactId) => WAPI.getChatById(contactId), + contactId + ); + } + + /** + * Retrieves chat object of given contact id + * @param contactId + * @returns contact detial as promise + */ + public async getChat(contactId: string) { + return await this.page.evaluate( + (contactId) => WAPI.getChat(contactId), + contactId + ); + } + + /** + * Retrieves chat picture + * @param chatId + * @returns Url of the chat picture or undefined if there is no picture for the chat. + */ + public async getProfilePicFromServer(chatId: string) { + return await this.page.evaluate( + (chatId) => WAPI.getProfilePicFromServer(chatId), + chatId + ); + } + + /** + * Sets a chat status to seen. Marks all messages as ack: 3 + * @param chatId chat id: xxxxx@us.c + */ + public async sendSeen(chatId: string) { + return await this.page.evaluate((chatId) => WAPI.sendSeen(chatId), chatId); + } + + /** + * Load more messages in chat object from server. Use this in a while loop + * @param contactId + * @returns contact detial as promise + */ + public async loadEarlierMessages(contactId: string) { + return await this.page.evaluate( + (contactId) => WAPI.loadEarlierMessages(contactId), + contactId + ); + } + + /** + * Get the status of a contact + * @param contactId {string} to '000000000000@c.us' + * returns: {id: string,status: string} + */ + + public async getStatus(contactId: string) { + return await this.page.evaluate( + (contactId) => WAPI.getStatus(contactId), + contactId + ); + } + + /** + * Load all messages in chat object from server. + * @param contactId + * @returns contact detial as promise + */ + public async asyncLoadAllEarlierMessages(contactId: string) { + return await this.page.evaluate( + (contactId) => WAPI.asyncLoadAllEarlierMessages(contactId), + contactId + ); + } + + /** + * Load all messages in chat object from server. + * @param contactId + * @returns contact detial as promise + */ + public async loadAllEarlierMessages(contactId: string) { + return await this.page.evaluate( + (contactId) => WAPI.loadAllEarlierMessages(contactId), + contactId + ); + } + + /** + * Delete the conversation from your whatsapp + * @param chatId + * @returns boolean + */ + public async deleteChat(chatId: string) { + return await this.page.evaluate( + (chatId) => WAPI.deleteConversation(chatId), + chatId + ); + } + + /** + * Delete all messages from the chat. + * @param chatId + * @returns boolean + */ + public async clearChat(chatId: string) { + return await this.page.evaluate((chatId) => WAPI.clearChat(chatId), chatId); + } + + /** + * Retreives an invite link for a group chat. returns false if chat is not a group. + * @param chatId + * @returns Promise + */ + public async getGroupInviteLink(chatId: string) { + return await this.page.evaluate( + (chatId) => WAPI.getGroupInviteLink(chatId), + chatId + ); + } + + /** + * Deletes message of given message id + * @param chatId The chat id from which to delete the message. + * @param messageId The specific message id of the message to be deleted + * @param onlyLocal If it should only delete locally (message remains on the other recipienct's phone). Defaults to false. + * @returns nothing + */ + public async deleteMessage( + chatId: string, + messageId: string[] | string, + onlyLocal: boolean = false + ) { + return await this.page.evaluate( + ({ contactId, messageId, onlyLocal }) => + WAPI.deleteMessages(contactId, messageId, onlyLocal), + { contactId: chatId, messageId, onlyLocal } + ); + } + + /** + * Checks if a number is a valid whatsapp number + * @param contactId, you need to include the @c.us at the end. + * @returns contact detial as promise + */ + public async getNumberProfile(contactId: string) { + return await this.page.evaluate( + (contactId) => WAPI.getNumberProfile(contactId), + contactId + ); + } + + /** + * Retrieves all undread Messages + * @param includeMe + * @param includeNotifications + * @param useUnreadCount + * @returns any + */ + public async getUnreadMessages( + includeMe: boolean, + includeNotifications: boolean, + useUnreadCount: boolean + ) { + return await this.page.evaluate( + ({ includeMe, includeNotifications, use_unread_count }) => + WAPI.getUnreadMessages( + includeMe, + includeNotifications, + use_unread_count + ), + { includeMe, includeNotifications, use_unread_count: useUnreadCount } + ); + } + + /** + * Retrieves all unread Messages. where ack==-1 + * @returns list of messages + */ + public async getAllUnreadMessages() { + return await this.page.evaluate(() => WAPI.getAllUnreadMessages()); + } + + /** + * Retrieves all Messages in a chat + * @param chatId, the chat to get the messages from + * @param includeMe, include my own messages? boolean + * @param includeNotifications + * @returns any + */ + + public async getAllMessagesInChat( + chatId: string, + includeMe: boolean, + includeNotifications: boolean + ) { + return await this.page.evaluate( + ({ chatId, includeMe, includeNotifications }) => + WAPI.getAllMessagesInChat(chatId, includeMe, includeNotifications), + { chatId, includeMe, includeNotifications } + ); + } + + /** + * loads and Retrieves all Messages in a chat + * @param chatId, the chat to get the messages from + * @param includeMe, include my own messages? boolean + * @param includeNotifications + * @returns any + */ + + public async loadAndGetAllMessagesInChat( + chatId: string, + includeMe: boolean, + includeNotifications: boolean + ) { + return await this.page.evaluate( + ({ chatId, includeMe, includeNotifications }) => + WAPI.loadAndGetAllMessagesInChat( + chatId, + includeMe, + includeNotifications + ), + { chatId, includeMe, includeNotifications } + ); + } + + /** + * Sends a text message to given chat + * @param to group name: 'New group' + * @param contacts: A single contact id or an array of contact ids. + * @returns Promise : + * ```javascript + * { + * status: 200, + * gid: { + * server: 'g.us', + * user: '447777777777-1583678870', + * _serialized: '447777777777-1583678870@g.us' + * }, + * participants: [ + * { '447777777777@c.us': [Object] }, + * { '447444444444@c.us': [Object] } + * ] + * } + * ``` + */ + public async createGroup(groupName: string, contacts: string | string[]) { + return await this.page.evaluate( + ({ groupName, contacts }) => WAPI.createGroup(groupName, contacts), + { groupName, contacts } + ); + } + + /** + * Remove participant of Group + * @param {*} idGroup '0000000000-00000000@g.us' + * @param {*} idParticipant '000000000000@c.us' + * @param {*} done - function - Callback function to be called when a new message arrives. + */ + + public async removeParticipant(idGroup: string, idParticipant: string) { + return await this.page.evaluate( + ({ idGroup, idParticipant }) => + WAPI.removeParticipant(idGroup, idParticipant), + { idGroup, idParticipant } + ); + } + + /** + * Add participant to Group + * @param {*} idGroup '0000000000-00000000@g.us' + * @param {*} idParticipant '000000000000@c.us' + * @param {*} done - function - Callback function to be called when a new message arrives. + */ + + public async addParticipant(idGroup: string, idParticipant: string) { + return await this.page.evaluate( + ({ idGroup, idParticipant }) => + WAPI.addParticipant(idGroup, idParticipant), + { idGroup, idParticipant } + ); + } + + /** + * Promote Participant to Admin in Group + * @param {*} idGroup '0000000000-00000000@g.us' + * @param {*} idParticipant '000000000000@c.us' + * @param {*} done - function - Callback function to be called when a new message arrives. + */ + + public async promoteParticipant(idGroup: string, idParticipant: string) { + return await this.page.evaluate( + ({ idGroup, idParticipant }) => + WAPI.promoteParticipant(idGroup, idParticipant), + { idGroup, idParticipant } + ); + } + + /** + * Demote Admin of Group + * @param {*} idGroup '0000000000-00000000@g.us' + * @param {*} idParticipant '000000000000@c.us' + * @param {*} done - function - Callback function to be called when a new message arrives. + */ + public async demoteParticipant(idGroup: string, idParticipant: string) { + return await this.page.evaluate( + ({ idGroup, idParticipant }) => + WAPI.demoteParticipant(idGroup, idParticipant), + { idGroup, idParticipant } + ); + } + + /** + * Get Admins of a Group + * @param {*} idGroup '0000000000-00000000@g.us' + */ + public async getGroupAdmins(idGroup: string) { + return await this.page.evaluate( + (idGroup) => WAPI.getGroupAdmins(idGroup), + idGroup + ); + } + + /** + * This function takes an image and sends it as a sticker to the recipient. This is helpful for sending semi-ephemeral things like QR codes. + * The advantage is that it will not show up in the recipients gallery. This function automatiicaly converts images to the required webp format. + * @param b64: This is the base64 string formatted with data URI. You can also send a plain base64 string but it may result in an error as the function will not be able to determine the filetype before sending. + * @param to: The recipient id. + */ + public async sendImageAsSticker(b64: string, to: string) { + const buff = Buffer.from( + b64.replace(/^data:image\/(png|gif|jpeg);base64,/, ''), + 'base64' + ); + const mimeInfo = base64MimeType(b64); + if (!mimeInfo || mimeInfo.includes('image')) { + //non matter what, convert to webp, resize + autoscale to width 512 px + const scaledImageBuffer = await sharp(buff, { failOnError: false }) + .resize({ width: 512, height: 512 }) + .toBuffer(); + const webp = sharp(scaledImageBuffer, { failOnError: false }).webp(); + const metadata: any = await webp.metadata(); + const webpBase64 = (await webp.toBuffer()).toString('base64'); + return await this.page.evaluate( + ({ webpBase64, to, metadata }) => + WAPI.sendImageAsSticker(webpBase64, to, metadata), + { webpBase64, to, metadata } + ); + } else { + console.log('Not an image'); + return false; + } + } + public async sendMentioned(to: string, message: string, mentioned: string) { console.log(message, mentioned); return await this.page.evaluate( @@ -141,13 +1127,12 @@ export class Whatsapp { { to, message, mentioned } ); } - /** * Sends a text message to given chat * @param to chat id: xxxxx@us.c * @param content text message */ - public sendImage = sendImage; + // public sendImage = sendImage; // /** // * TODO: Fix message not being delivered diff --git a/src/lib/middleware/middleware.ts b/src/lib/middleware/middleware.ts index de16b86d..b4318c27 100644 --- a/src/lib/middleware/middleware.ts +++ b/src/lib/middleware/middleware.ts @@ -8,17 +8,31 @@ declare module WAPI { const waitNewMessages: (rmCallback: boolean, callback: Function) => void; + const waitNewAcknowledgements: (callback: Function) => void; + const onStateChanged: (callback: Function) => void; + const allNewMessagesListener: (callback: Function) => void; } enum ExposedFn { - OnMessage = 'onMessage' + OnMessage = 'onMessage', + OnAck = 'onAck', + OnParticipantsChanged = 'onParticipantsChanged', } /** * Exposes [OnMessage] function */ -WAPI.waitNewMessages(false, data => { - data.forEach(message => { +WAPI.waitNewMessages(false, (data) => { + data.forEach((message) => { window[ExposedFn.OnMessage](message); }); }); + +WAPI.waitNewAcknowledgements(function (data) { + if (!Array.isArray(data)) { + data = [data]; + } + data.forEach(function (message) { + if (window[ExposedFn.OnAck]) window[ExposedFn.OnAck](message); + }); +}); diff --git a/src/lib/wapi/functions/are-all-messages-loaded.js b/src/lib/wapi/functions/are-all-messages-loaded.js new file mode 100644 index 00000000..6b01e072 --- /dev/null +++ b/src/lib/wapi/functions/are-all-messages-loaded.js @@ -0,0 +1,14 @@ +/** + * Checks if all messages are loaded + * @param {string} id Chat id + * @param {Function} done Optional callback + */ +export function areAllMessagesLoaded(id, done) { + const found = WAPI.getChat(id); + if (!found.msgs.msgLoadState.noEarlierMsgs) { + if (done) done(false); + return false; + } + if (done) done(true); + return true; +} diff --git a/src/lib/wapi/functions/clear-chat.js b/src/lib/wapi/functions/clear-chat.js new file mode 100644 index 00000000..24a3dab6 --- /dev/null +++ b/src/lib/wapi/functions/clear-chat.js @@ -0,0 +1,7 @@ +/** + * Clears chat messages + * @param {string} id Chat id + */ +export async function clearChat(id) { + return await Store.ChatUtil.sendClear(Store.Chat.get(id), true); +} diff --git a/src/lib/wapi/functions/delete-conversation.js b/src/lib/wapi/functions/delete-conversation.js new file mode 100644 index 00000000..db7b5e52 --- /dev/null +++ b/src/lib/wapi/functions/delete-conversation.js @@ -0,0 +1,31 @@ +/** + * @param {string} chatId Chat id + * @param {Function} done Optional callback + */ +export function deleteConversation(chatId, done) { + let userId = new window.Store.UserConstructor(chatId, { + intentionallyUsePrivateConstructor: true, + }); + let conversation = WAPI.getChat(userId); + + if (!conversation) { + if (done !== undefined) { + done(false); + } + return false; + } + + window.Store.sendDelete(conversation, false) + .then(() => { + if (done !== undefined) { + done(true); + } + }) + .catch(() => { + if (done !== undefined) { + done(false); + } + }); + + return true; +} diff --git a/src/lib/wapi/functions/delete-messages.js b/src/lib/wapi/functions/delete-messages.js new file mode 100644 index 00000000..58247936 --- /dev/null +++ b/src/lib/wapi/functions/delete-messages.js @@ -0,0 +1,46 @@ +/** + * Deletes message of given message id + * @param {string} chatId The chat id from which to delete the message. + * @param {string[]} messageArray The specific message id of the message to be deleted + * @param {boolean} onlyLocal If it should only delete locally (message remains on the other recipienct's phone). Defaults to false. + * @param {Function} done Optional callback + */ +export function deleteMessages(chatId, messageArray, onlyLocal, done) { + var userId = new Store.WidFactory.createWid(chatId); + let conversation = WAPI.getChat(userId); + if (!conversation) { + if (done !== undefined) { + done(false); + } + return false; + } + + if (!Array.isArray(messageArray)) { + messageArray = [messageArray]; + } + + let messagesToDelete = messageArray + .map((msgId) => + typeof msgId == 'string' ? window.Store.Msg.get(msgId) : msgId + ) + .filter((x) => x); + if (messagesToDelete.length == 0) return true; + let jobs = onlyLocal + ? [conversation.sendDeleteMsgs(messagesToDelete, conversation)] + : [ + conversation.sendRevokeMsgs( + messagesToDelete.filter((msg) => msg.isSentByMe), + conversation + ), + conversation.sendDeleteMsgs( + messagesToDelete.filter((msg) => !msg.isSentByMe), + conversation + ), + ]; + return Promise.all(jobs).then((_) => { + if (done !== undefined) { + done(true); + } + return true; + }); +} diff --git a/src/lib/wapi/functions/download-file-with-credentials.js b/src/lib/wapi/functions/download-file-with-credentials.js new file mode 100644 index 00000000..2e999642 --- /dev/null +++ b/src/lib/wapi/functions/download-file-with-credentials.js @@ -0,0 +1,30 @@ +/** + * Downloads given url file + * @param {string} url + * @param {Function} done Optional callback + */ +export function downloadFileWithCredentials(url, done) { + let xhr = new XMLHttpRequest(); + + xhr.onload = function () { + if (xhr.readyState == 4) { + if (xhr.status == 200) { + let reader = new FileReader(); + reader.readAsDataURL(xhr.response); + reader.onload = function (e) { + done(reader.result.substr(reader.result.indexOf(',') + 1)); + }; + } else { + console.error(xhr.statusText); + } + } else { + console.log(err); + done(false); + } + }; + + xhr.open('GET', url, true); + xhr.withCredentials = true; + xhr.responseType = 'blob'; + xhr.send(null); +} diff --git a/src/lib/wapi/functions/get-all-chats-with-messages.js b/src/lib/wapi/functions/get-all-chats-with-messages.js index d75bc40b..8149f9ba 100644 --- a/src/lib/wapi/functions/get-all-chats-with-messages.js +++ b/src/lib/wapi/functions/get-all-chats-with-messages.js @@ -12,6 +12,7 @@ export async function getAllChatsWithMessages(newOnly, done) { } else { x.push(WAPI.getAllChatIds().map((c) => WAPI.getChat(c))); } - const result = (await Promise.all(x)).flatMap((x) => x); - return JSON.stringify(result); + const _result = (await Promise.all(x)).flatMap((x) => x); + const result = JSON.stringify(_result); + return JSON.parse(result); } diff --git a/src/lib/wapi/functions/get-all-group-metadata.js b/src/lib/wapi/functions/get-all-group-metadata.js new file mode 100644 index 00000000..5d136afd --- /dev/null +++ b/src/lib/wapi/functions/get-all-group-metadata.js @@ -0,0 +1,12 @@ +/** + * Fetches all group metadata objects from store + * @param {Function} done Optional callback + */ +export function getAllGroupMetadata(done) { + const groupData = window.Store.GroupMetadata.map( + (groupData) => groupData.all + ); + + if (done !== undefined) done(groupData); + return groupData; +} diff --git a/src/lib/wapi/functions/get-all-messages-in-chat.js b/src/lib/wapi/functions/get-all-messages-in-chat.js new file mode 100644 index 00000000..11a03d9f --- /dev/null +++ b/src/lib/wapi/functions/get-all-messages-in-chat.js @@ -0,0 +1,32 @@ +/** + * @param {string} id Chat id + * @param {boolean} includeMe + * @param {boolean} includeNotifications + * @param {Function} done Optional callback + */ +export function getAllMessagesInChat( + id, + includeMe, + includeNotifications, + done +) { + const chat = WAPI.getChat(id); + let output = []; + const messages = chat.msgs._models; + + for (const i in messages) { + if (i === 'remove') { + continue; + } + const messageObj = messages[i]; + + let message = WAPI.processMessageObj( + messageObj, + includeMe, + includeNotifications + ); + if (message) output.push(message); + } + if (done !== undefined) done(output); + return output; +} diff --git a/src/lib/wapi/functions/get-all-new-messages.js b/src/lib/wapi/functions/get-all-new-messages.js index 3f21f960..676528a3 100644 --- a/src/lib/wapi/functions/get-all-new-messages.js +++ b/src/lib/wapi/functions/get-all-new-messages.js @@ -5,9 +5,11 @@ import { getAllChatsWithNewMessages } from './get-chats-with-new-messages'; * TODO: Test, seems to be written incorrectly */ export const getAllNewMessages = function () { - return JSON.stringify( + const _newMessages = JSON.stringify( getAllChatsWithNewMessages() .map((c) => WAPI.getChat(c.id._serialized)) .map((c) => c.msgs._models.filter((x) => x.isNewMsg)) || [] ); + + return JSON.parse(_newMessages); }; diff --git a/src/lib/wapi/functions/get-all-unread-messages.js b/src/lib/wapi/functions/get-all-unread-messages.js index 132770e4..98d7159b 100644 --- a/src/lib/wapi/functions/get-all-unread-messages.js +++ b/src/lib/wapi/functions/get-all-unread-messages.js @@ -6,10 +6,13 @@ import { getAllChatsWithNewMessages } from './get-chats-with-new-messages'; * TODO: Test this fn, seems incorrect, should not be async */ export const getAllUnreadMessages = async function () { - return JSON.stringify( + const _partials = JSON.stringify( getAllChatsWithNewMessages() .map((c) => WAPI.getChat(c.id._serialized)) .map((c) => c.msgs._models.filter((x) => x.ack === -1)) .flatMap((x) => x) || [] ); + + const partials = JSON.parse(_partials); + return partials; }; diff --git a/src/lib/wapi/functions/get-battery-level.js b/src/lib/wapi/functions/get-battery-level.js new file mode 100644 index 00000000..3d76de9d --- /dev/null +++ b/src/lib/wapi/functions/get-battery-level.js @@ -0,0 +1,15 @@ +/** + * Retrives battery level + * If plugged in, it will return 100% + * @returns {number} + */ +export function getBatteryLevel() { + if (window.Store.Conn.plugged) { + return 100; + } + output = window.Store.Conn.battery; + if (done !== undefined) { + done(output); + } + return output; +} diff --git a/src/lib/wapi/functions/get-common-groups.js b/src/lib/wapi/functions/get-common-groups.js new file mode 100644 index 00000000..123badd4 --- /dev/null +++ b/src/lib/wapi/functions/get-common-groups.js @@ -0,0 +1,29 @@ +/** + * Retrieves common groups of given participant + * @param {string} participantId + * @param {Function} done Optional callback + */ +export async function getCommonGroups(participantId, done) { + let output = []; + groups = window.WAPI.getAllGroups(); + for (let idx in groups) { + try { + participants = await window.WAPI.getGroupParticipantIDs(groups[idx].id); + if ( + participants.filter((participant) => participant == participantId) + .length + ) { + output.push(groups[idx]); + } + } catch (err) { + console.log('Error in group:'); + console.log(groups[idx]); + console.log(err); + } + } + + if (done !== undefined) { + done(output); + } + return output; +} diff --git a/src/lib/wapi/functions/get-group-admins.js b/src/lib/wapi/functions/get-group-admins.js new file mode 100644 index 00000000..99dc4fd1 --- /dev/null +++ b/src/lib/wapi/functions/get-group-admins.js @@ -0,0 +1,15 @@ +import { _getGroupParticipants } from './get-group-participants'; + +/** + * Retrieves group admins + * @param {string} id Group id + * @param {Function} done Optional callback + */ +export async function getGroupAdmins(id, done) { + const output = (await _getGroupParticipants(id)) + .filter((participant) => participant.isAdmin) + .map((admin) => admin.id); + + if (done !== undefined) done(output); + return output; +} diff --git a/src/lib/wapi/functions/get-group-metadata.js b/src/lib/wapi/functions/get-group-metadata.js new file mode 100644 index 00000000..182d7472 --- /dev/null +++ b/src/lib/wapi/functions/get-group-metadata.js @@ -0,0 +1,11 @@ +/** + * Fetches group metadata object from store by ID + * @param {string} id Group id + * @param {Function} done Optional callback + * @returns Group metadata object + */ +export async function getGroupMetadata(id, done) { + let output = window.Store.GroupMetadata.find(id); + if (done !== undefined) done(output); + return output; +} diff --git a/src/lib/wapi/functions/get-group-participant-ids.js b/src/lib/wapi/functions/get-group-participant-ids.js new file mode 100644 index 00000000..9405c10d --- /dev/null +++ b/src/lib/wapi/functions/get-group-participant-ids.js @@ -0,0 +1,16 @@ +import { _getGroupParticipants } from './get-group-participants'; + +/** + * Fetches IDs of group participants + * @param {string} groupId Group id + * @param {Function} done Optional callback + * @returns {Promise.} Yields list of IDs + */ +export async function getGroupParticipantIDs(groupId, done) { + const output = (await _getGroupParticipants(groupId)).map( + (participant) => participant.id + ); + + if (done !== undefined) done(output); + return output; +} diff --git a/src/lib/wapi/functions/get-group-participants.js b/src/lib/wapi/functions/get-group-participants.js new file mode 100644 index 00000000..b2f20df3 --- /dev/null +++ b/src/lib/wapi/functions/get-group-participants.js @@ -0,0 +1,8 @@ +/** + * Fetches group participants + * @param {string} id Group id + */ +export async function _getGroupParticipants(id) { + const metadata = await WAPI.getGroupMetadata(id); + return metadata.participants; +} diff --git a/src/lib/wapi/functions/get-host.js b/src/lib/wapi/functions/get-host.js new file mode 100644 index 00000000..e37ff46b --- /dev/null +++ b/src/lib/wapi/functions/get-host.js @@ -0,0 +1,6 @@ +/** + * Returns an object with all of your host device details + */ +export function getHost() { + return Store.Me.attributes; +} diff --git a/src/lib/wapi/functions/get-me.js b/src/lib/wapi/functions/get-me.js new file mode 100644 index 00000000..7f4c530d --- /dev/null +++ b/src/lib/wapi/functions/get-me.js @@ -0,0 +1,9 @@ +/** + * Retrieves current user object + */ +export function getMe(done) { + const rawMe = window.Store.Contact.get(window.Store.Conn.me); + + if (done !== undefined) done(rawMe.all); + return rawMe.all; +} diff --git a/src/lib/wapi/functions/get-number-profile.js b/src/lib/wapi/functions/get-number-profile.js new file mode 100644 index 00000000..dca89543 --- /dev/null +++ b/src/lib/wapi/functions/get-number-profile.js @@ -0,0 +1,29 @@ +/** + * Checks if a number is a valid whatsapp number + * @param {*} id User id (you need to include the @c.us at the end.) + * @param {*} done + * @returns contact detial + */ +export async function getNumberProfile(id, done) { + try { + const result = await window.Store.WapQuery.queryExist(id); + if (result.jid === undefined) throw 404; + const data = window.WAPI._serializeNumberStatusObj(result); + if (data.status == 200) data.numberExists = true; + if (done !== undefined) { + done(window.WAPI._serializeNumberStatusObj(result)); + done(data); + } + return data; + } catch (e) { + if (done !== undefined) { + done( + window.WAPI._serializeNumberStatusObj({ + status: e, + jid: id, + }) + ); + } + return e; + } +} diff --git a/src/lib/wapi/functions/get-profile-pic-from-server.js b/src/lib/wapi/functions/get-profile-pic-from-server.js new file mode 100644 index 00000000..be27cca5 --- /dev/null +++ b/src/lib/wapi/functions/get-profile-pic-from-server.js @@ -0,0 +1,7 @@ +/** + * @returns Url of the chat picture. + * @param {string} id Chat id + */ +export function getProfilePicFromServer(id) { + return Store.WapQuery.profilePicFind(id).then((x) => x.eurl); +} diff --git a/src/lib/wapi/functions/get-unread-messages.js b/src/lib/wapi/functions/get-unread-messages.js new file mode 100644 index 00000000..dd9c61d9 --- /dev/null +++ b/src/lib/wapi/functions/get-unread-messages.js @@ -0,0 +1,93 @@ +/** + * Retrieves all undread Messages + * @param {boolean} includeMe + * @param {boolean} includeNotifications + * @param {boolean} useUnreadCount + * @param {Function} done Optional callback + */ +export function getUnreadMessages( + includeMe, + includeNotifications, + useUnreadCount, + done +) { + const chats = window.Store.Chat.models; + const output = []; + + for (const chat in chats) { + if (isNaN(chat)) { + continue; + } + + const messageGroupObj = chats[chat]; + let messageGroup = WAPI._serializeChatObj(messageGroupObj); + messageGroup.messages = []; + + const messages = messageGroupObj.msgs._models; + for (let i = messages.length - 1; i >= 0; i--) { + const messageObj = messages[i]; + if ( + typeof messageObj.isNewMsg != 'boolean' || + messageObj.isNewMsg === false + ) { + continue; + } else { + messageObj.isNewMsg = false; + let message = WAPI.processMessageObj( + messageObj, + includeMe, + includeNotifications + ); + if (message) { + messageGroup.messages.push(message); + } + } + } + + if (messageGroup.messages.length > 0) { + output.push(messageGroup); + } else { + // No messages with isNewMsg true + if (useUnreadCount) { + // Will use unreadCount attribute to fetch last n messages from sender + let n = messageGroupObj.unreadCount; + for (let i = messages.length - 1; i >= 0; i--) { + const messageObj = messages[i]; + if (n > 0) { + if (!messageObj.isSentByMe) { + let message = WAPI.processMessageObj( + messageObj, + includeMe, + includeNotifications + ); + messageGroup.messages.unshift(message); + n -= 1; + } + } else if (n === -1) { + // chat was marked as unread so will fetch last message as unread + if (!messageObj.isSentByMe) { + let message = WAPI.processMessageObj( + messageObj, + includeMe, + includeNotifications + ); + messageGroup.messages.unshift(message); + break; + } + } else { + // unreadCount = 0 + break; + } + } + if (messageGroup.messages.length > 0) { + messageGroupObj.unreadCount = 0; // reset unread counter + output.push(messageGroup); + } + } + } + } + if (done !== undefined) { + done(output); + } + return output; +} diff --git a/src/lib/wapi/functions/index.js b/src/lib/wapi/functions/index.js index be5bf8f7..0f8b9b18 100644 --- a/src/lib/wapi/functions/index.js +++ b/src/lib/wapi/functions/index.js @@ -1,31 +1,55 @@ +export { areAllMessagesLoaded } from './are-all-messages-loaded'; export { createGroup } from './create-group'; +export { deleteConversation } from './delete-conversation'; +export { downloadFileWithCredentials } from './download-file-with-credentials'; export { getAllChats } from './get-all-chats'; export { getAllChatIds } from './get-all-chats-ids'; +export { getAllChatsWithMessages } from './get-all-chats-with-messages'; export { getAllContacts } from './get-all-contacts'; +export { getAllGroupMetadata } from './get-all-group-metadata'; +export { getAllGroups } from './get-all-groups'; +export { getAllMessagesInChat } from './get-all-messages-in-chat'; export { getAllNewMessages } from './get-all-new-messages'; export { getAllUnreadMessages } from './get-all-unread-messages'; -export { getAllChatsWithNewMessages } from './get-chats-with-new-messages'; -export { getContact } from './get-contact'; -export { getMyContacts } from './get-my-contacts'; -export { hasUndreadMessages } from './has-unread-messages'; -export { leaveGroup } from './leave-group'; -export { sendMessage } from './send-message'; -export { sendMessage2 } from './send-message2'; -export { getAllChatsWithMessages } from './get-all-chats-with-messages'; -export { getAllGroups } from './get-all-groups'; -export { sendChatstate } from './send-chat-state'; +export { getBatteryLevel } from './get-battery-level'; export { getChat } from './get-chat'; -export { getStatus } from './get-status'; +export { getChatById } from './get-chat-by-id'; export { getChatByName } from './get-chat-by-name'; -export { sendMessageWithThumb } from './send-message-with-thumb'; +export { getAllChatsWithNewMessages } from './get-chats-with-new-messages'; +export { getCommonGroups } from './get-common-groups'; +export { getContact } from './get-contact'; +export { getGroupAdmins } from './get-group-admins'; export { getGroupInviteLink } from './get-group-invite-link'; +export { getGroupMetadata } from './get-group-metadata'; +export { getGroupParticipantIDs } from './get-group-participant-ids'; +export { _getGroupParticipants } from './get-group-participants'; +export { getHost } from './get-host'; +export { getMe } from './get-me'; +export { getMyContacts } from './get-my-contacts'; export { getNewId } from './get-new-id'; -export { getChatById } from './get-chat-by-id'; +export { getProfilePicFromServer } from './get-profile-pic-from-server'; +export { getStatus } from './get-status'; +export { getUnreadMessages } from './get-unread-messages'; export { getUnreadMessagesInChat } from './get-unread-messages-in-chat'; -export { processMessageObj } from './process-message-object'; -export { loadChatEarlierMessages } from './load-earlier-chat-messages'; +export { hasUndreadMessages } from './has-unread-messages'; +export { isConnected } from './is-connected'; +export { isLoggedIn } from './is-logged-in'; +export { leaveGroup } from './leave-group'; export { - loadAllEarlierMessages, asyncLoadAllEarlierMessages, + loadAllEarlierMessages, } from './load-all-earlier-chat-messages'; -export { isLoggedIn } from './is-logged-in'; +export { loadAndGetAllMessagesInChat } from './load-and-get-all-messages-in-chat'; +export { loadChatEarlierMessages } from './load-earlier-chat-messages'; +export { loadEarlierMessagesTillDate } from './load-earlier-messages-til-date'; +export { processMessageObj } from './process-message-object'; +export { revokeGroupInviteLink } from './revoke-invite-link'; +export { sendChatstate } from './send-chat-state'; +export { sendMessage } from './send-message'; +export { sendMessageWithTags } from './send-message-with-tags'; +export { sendMessageWithThumb } from './send-message-with-thumb'; +export { sendMessage2 } from './send-message2'; +export { sendSeen } from './send-seen'; +export { deleteMessages } from './delete-messages'; +export { clearChat } from './clear-chat'; +export { getNumberProfile } from './get-number-profile'; diff --git a/src/lib/wapi/functions/is-connected.js b/src/lib/wapi/functions/is-connected.js new file mode 100644 index 00000000..b2e2d801 --- /dev/null +++ b/src/lib/wapi/functions/is-connected.js @@ -0,0 +1,14 @@ +/** + * Check if phone is connected + * @param {Function} done Optional callback + */ +export function isConnected(done) { + // Phone Disconnected icon appears when phone is disconnected from the tnternet + const isConnected = + document.querySelector('*[data-icon="alert-phone"]') !== null + ? false + : true; + + if (done !== undefined) done(isConnected); + return isConnected; +} diff --git a/src/lib/wapi/functions/load-and-get-all-messages-in-chat.js b/src/lib/wapi/functions/load-and-get-all-messages-in-chat.js new file mode 100644 index 00000000..1e9f69a4 --- /dev/null +++ b/src/lib/wapi/functions/load-and-get-all-messages-in-chat.js @@ -0,0 +1,35 @@ +/** + * Loads and Retrieves all Messages in a chat + * @param {string} id Chat id + * @param {boolean} includeMe + * @param {boolean} includeNotifications + * @param {Function} done Optional callback + */ +export function loadAndGetAllMessagesInChat( + id, + includeMe, + includeNotifications, + done +) { + return WAPI.loadAllEarlierMessages(id).then((_) => { + const chat = WAPI.getChat(id); + let output = []; + const messages = chat.msgs._models; + + for (const i in messages) { + if (i === 'remove') { + continue; + } + const messageObj = messages[i]; + + let message = WAPI.processMessageObj( + messageObj, + includeMe, + includeNotifications + ); + if (message) output.push(message); + } + if (done !== undefined) done(output); + return output; + }); +} diff --git a/src/lib/wapi/functions/load-earlier-messages-til-date.js b/src/lib/wapi/functions/load-earlier-messages-til-date.js new file mode 100644 index 00000000..439a7e76 --- /dev/null +++ b/src/lib/wapi/functions/load-earlier-messages-til-date.js @@ -0,0 +1,20 @@ +/** + * Loads earlier messages from Store till given date + * @param {string} id Chat id + * @param {*} lastMessage UTC timestamp of last message to be loaded + * @param {Function} done Optional callback + */ +export function loadEarlierMessagesTillDate(id, lastMessage, done) { + const found = WAPI.getChat(id); + x = function () { + if ( + found.msgs.models[0].t > lastMessage && + !found.msgs.msgLoadState.noEarlierMsgs + ) { + found.loadEarlierMsgs().then(x); + } else { + done(); + } + }; + x(); +} diff --git a/src/lib/wapi/functions/revoke-invite-link.js b/src/lib/wapi/functions/revoke-invite-link.js new file mode 100644 index 00000000..6a8d1ae9 --- /dev/null +++ b/src/lib/wapi/functions/revoke-invite-link.js @@ -0,0 +1,10 @@ +/** + * Revokes group invite link + * @param {string} chatId + */ +export async function revokeGroupInviteLink(chatId) { + var chat = Store.Chat.get(chatId); + if (!chat.isGroup) return false; + await Store.GroupInvite.revokeGroupInvite(chat); + return true; +} diff --git a/src/lib/wapi/functions/send-message-with-tags.js b/src/lib/wapi/functions/send-message-with-tags.js new file mode 100644 index 00000000..71b57de3 --- /dev/null +++ b/src/lib/wapi/functions/send-message-with-tags.js @@ -0,0 +1,39 @@ +/** + * Sends text message including @tag mentions + * @param {string} to Chat id + * @param {string} body Body message + */ +export async function sendMessageWithTags(to, body) { + var chat = to.id ? to : Store.Chat.get(to); + var chatId = chat.id._serialized; + var msgIveSent = chat.msgs.filter((msg) => msg.__x_isSentByMe)[0]; + if (!msgIveSent) { + return chat.sendMessage(body); + } + + var tempMsg = Object.create(msgIveSent); + var newId = window.WAPI.getNewMessageId(chatId); + var mentionedJidList = + body + .match(/@(\d*)/g) + .map((x) => new Store.WidFactory.createUserWid(x.replace('@', ''))) || + undefined; + + var extend = { + ack: 0, + id: newId, + local: !0, + self: 'out', + t: parseInt(new Date().getTime() / 1000), + to: new Store.WidFactory.createWid(chatId), + isNewMsg: !0, + type: 'chat', + body, + quotedMsg: null, + mentionedJidList, + }; + + Object.assign(tempMsg, extend); + await Store.addAndSendMsgToChat(chat, tempMsg); + return newId._serialized; +} diff --git a/src/lib/wapi/functions/send-message.js b/src/lib/wapi/functions/send-message.js index 60545600..4a4bd5b4 100644 --- a/src/lib/wapi/functions/send-message.js +++ b/src/lib/wapi/functions/send-message.js @@ -1,14 +1,12 @@ export function sendMessage(id, message, done) { - var chat = WAPI.getChat(id); - if (chat) { + let chat = WAPI.getChat(id); + function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + if (chat !== undefined) { if (done !== undefined) { - chat.sendMessage(message).then(function() { - function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); - } - - var trials = 0; - + chat.sendMessage(message).then(function () { + let trials = 0; function check() { for (let i = chat.msgs.models.length - 1; i >= 0; i--) { let msg = chat.msgs.models[i]; @@ -20,8 +18,7 @@ export function sendMessage(id, message, done) { return True; } trials += 1; - // console.log(trials); - + console.log(trials); if (trials > 30) { done(true); return; @@ -32,8 +29,9 @@ export function sendMessage(id, message, done) { }); return true; } else { - chat.sendMessage(message); - return true; + return chat + .sendMessage(message) + .then((_) => chat.lastReceivedKey._serialized); } } else { if (done !== undefined) done(false); diff --git a/src/lib/wapi/functions/send-message2.js b/src/lib/wapi/functions/send-message2.js index cd6e12ee..6b7d6c19 100644 --- a/src/lib/wapi/functions/send-message2.js +++ b/src/lib/wapi/functions/send-message2.js @@ -3,7 +3,7 @@ export function sendMessage2(id, message, done) { if (chat !== undefined) { try { if (done !== undefined) { - chat.sendMessage(message).then(function() { + chat.sendMessage(message).then(function () { done(true); }); } else { diff --git a/src/lib/wapi/functions/send-seen.js b/src/lib/wapi/functions/send-seen.js new file mode 100644 index 00000000..dff81419 --- /dev/null +++ b/src/lib/wapi/functions/send-seen.js @@ -0,0 +1,21 @@ +/** + * Sends seens to given chat id + * @param {string} id Chat id + * @param {Function} done Optional callback + */ +export function sendSeen(id, done) { + var chat = window.WAPI.getChat(id); + if (chat !== undefined) { + if (done !== undefined) { + Store.SendSeen(chat, false).then(function () { + done(true); + }); + return true; + } else { + Store.SendSeen(chat, false); + return true; + } + } + if (done !== undefined) done(); + return false; +} diff --git a/src/lib/wapi/helper/is-chat-message.js b/src/lib/wapi/helper/is-chat-message.js new file mode 100644 index 00000000..0791da1c --- /dev/null +++ b/src/lib/wapi/helper/is-chat-message.js @@ -0,0 +1,16 @@ +/** + * @returns true if is a chat messae, false otherwise + * @param {Message} message + */ +export function isChatMessage(message) { + if (message.isSentByMe) { + return false; + } + if (message.isNotification) { + return false; + } + if (!message.isUserCreatedType) { + return false; + } + return true; +} diff --git a/src/lib/wapi/listeners/add-all-new-messages.listener.js b/src/lib/wapi/listeners/add-all-new-messages.listener.js new file mode 100644 index 00000000..e8f076d0 --- /dev/null +++ b/src/lib/wapi/listeners/add-all-new-messages.listener.js @@ -0,0 +1,11 @@ +export function allNewMessagesListener() { + window.WAPI.allNewMessagesListener = (callback) => + window.Store.Msg.on('add', (newMessage) => { + if (newMessage && newMessage.isNewMsg) { + let message = window.WAPI.processMessageObj(newMessage, true, false); + if (message) { + callback(message); + } + } + }); +} diff --git a/src/lib/wapi/listeners/add-new-messages.listener.js b/src/lib/wapi/listeners/add-new-messages.listener.js new file mode 100644 index 00000000..770c1ed1 --- /dev/null +++ b/src/lib/wapi/listeners/add-new-messages.listener.js @@ -0,0 +1,17 @@ +export function addNewMessagesListener() { + window.WAPI.waitNewMessages = waitNewMessages; +} + +/** + * Registers a callback to be called when a new message arrives the WAPI. + * @param rmCallbackAfterUse - Boolean - Specify if the callback need to be executed only once + * @param done - function - Callback function to be called when a new message arrives. + * @returns {boolean} + */ +function waitNewMessages(rmCallbackAfterUse = true, done) { + window.WAPI._newMessagesCallbacks.push({ + callback: done, + rmAfterUse: rmCallbackAfterUse, + }); + return true; +} diff --git a/src/lib/wapi/listeners/index.js b/src/lib/wapi/listeners/index.js new file mode 100644 index 00000000..83e760e7 --- /dev/null +++ b/src/lib/wapi/listeners/index.js @@ -0,0 +1,3 @@ +export { initNewMessagesListener } from './init-listeners'; +export { addNewMessagesListener } from './add-new-messages.listener'; +export { allNewMessagesListener } from './add-all-new-messages.listener'; diff --git a/src/lib/wapi/listeners/init-listeners.js b/src/lib/wapi/listeners/init-listeners.js new file mode 100644 index 00000000..d5293037 --- /dev/null +++ b/src/lib/wapi/listeners/init-listeners.js @@ -0,0 +1,73 @@ +/** + * This needs to be executed before new adding new message listeners + */ +export function initNewMessagesListener() { + window.WAPI._newMessagesListener = window.Store.Msg.on( + 'add', + (newMessage) => { + if (newMessage && newMessage.isNewMsg && !newMessage.isSentByMe) { + let message = window.WAPI.processMessageObj(newMessage, false, false); + if (message) { + window.WAPI._newMessagesQueue.push(message); + window.WAPI._newMessagesBuffer.push(message); + } + + // Starts debouncer time to don't call a callback for each message if more than one message arrives + // in the same second + if ( + !window.WAPI._newMessagesDebouncer && + window.WAPI._newMessagesQueue.length > 0 + ) { + window.WAPI._newMessagesDebouncer = setTimeout(() => { + let queuedMessages = window.WAPI._newMessagesQueue; + + window.WAPI._newMessagesDebouncer = null; + window.WAPI._newMessagesQueue = []; + + let removeCallbacks = []; + + window.WAPI._newMessagesCallbacks.forEach(function (callbackObj) { + if (callbackObj.callback !== undefined) { + callbackObj.callback(queuedMessages); + } + if (callbackObj.rmAfterUse === true) { + removeCallbacks.push(callbackObj); + } + }); + + // Remove removable callbacks. + removeCallbacks.forEach(function (rmCallbackObj) { + let callbackIndex = window.WAPI._newMessagesCallbacks.indexOf( + rmCallbackObj + ); + window.WAPI._newMessagesCallbacks.splice(callbackIndex, 1); + }); + }, 1000); + } + } + } + ); + + window.WAPI._unloadInform = (event) => { + // Save in the buffer the ungot unreaded messages + window.WAPI._newMessagesBuffer.forEach((message) => { + Object.keys(message).forEach((key) => + message[key] === undefined ? delete message[key] : '' + ); + }); + sessionStorage.setItem( + 'saved_msgs', + JSON.stringify(window.WAPI._newMessagesBuffer) + ); + + // Inform callbacks that the page will be reloaded. + window.WAPI._newMessagesCallbacks.forEach(function (callbackObj) { + if (callbackObj.callback !== undefined) { + callbackObj.callback({ + status: -1, + message: 'page will be reloaded, wait and register callback again.', + }); + } + }); + }; +} diff --git a/src/lib/wapi/store/get-store.js b/src/lib/wapi/store/get-store.js index f5dc368d..47ee24b9 100644 --- a/src/lib/wapi/store/get-store.js +++ b/src/lib/wapi/store/get-store.js @@ -1,5 +1,8 @@ +import { storeObjects } from './store-objects'; + export function getStore(modules) { let foundCount = 0; + let neededObjects = storeObjects; for (let idx in modules) { if (typeof modules[idx] === 'object' && modules[idx] !== null) { let first = Object.values(modules[idx])[0]; @@ -9,7 +12,7 @@ export function getStore(modules) { if (!module) { continue; } - storeObjects.forEach((needObj) => { + neededObjects.forEach((needObj) => { if (!needObj.conditions || needObj.foundedModule) return; let neededModule = needObj.conditions(module); if (neededModule !== null) { @@ -17,19 +20,19 @@ export function getStore(modules) { needObj.foundedModule = neededModule; } }); - if (foundCount == storeObjects.length) { + if (foundCount == neededObjects.length) { break; } } - let neededStore = storeObjects.find( + let neededStore = neededObjects.find( (needObj) => needObj.id === 'Store' ); window.Store = neededStore.foundedModule ? neededStore.foundedModule : {}; - storeObjects.splice(storeObjects.indexOf(neededStore), 1); - storeObjects.forEach((needObj) => { + neededObjects.splice(neededObjects.indexOf(neededStore), 1); + neededObjects.forEach((needObj) => { if (needObj.foundedModule) { window.Store[needObj.id] = needObj.foundedModule; } diff --git a/src/lib/wapi/store/store-objects.js b/src/lib/wapi/store/store-objects.js index 0a204ef2..2f08f07a 100644 --- a/src/lib/wapi/store/store-objects.js +++ b/src/lib/wapi/store/store-objects.js @@ -13,7 +13,10 @@ export const storeObjects = [ ? module.default : null, }, - { id: 'MediaProcess', conditions: (module) => (module.BLOB ? module : null) }, + { + id: 'MediaProcess', + conditions: (module) => (module.BLOB ? module : null), + }, { id: 'ChatUtil', conditions: (module) => (module.sendClear ? module : null), @@ -136,6 +139,11 @@ export const storeObjects = [ conditions: (module) => module.PLATFORMS && module.Conn ? module.default : null, }, + { + id: 'CallUtils', + conditions: (module) => + module.sendCallEnd && module.parseCall ? module : null, + }, { id: 'Identity', conditions: (module) => diff --git a/src/lib/wapi/wapi.js b/src/lib/wapi/wapi.js index 67ad8748..102e7103 100644 --- a/src/lib/wapi/wapi.js +++ b/src/lib/wapi/wapi.js @@ -1,7 +1,3 @@ -/** - * This script contains WAPI functions that need to be run in the context of the webpage - */ - import { asyncLoadAllEarlierMessages, createGroup, @@ -30,8 +26,33 @@ import { sendChatstate, sendMessageWithThumb, isLoggedIn, + sendMessage, + sendMessage2, + revokeGroupInviteLink, + areAllMessagesLoaded, + loadEarlierMessagesTillDate, + getAllGroupMetadata, + getMe, + getHost, + isConnected, + getAllMessagesInChat, + loadAndGetAllMessagesInChat, + sendMessageWithTags, + sendSeen, + getUnreadMessages, + getCommonGroups, + getGroupParticipantIDs, + _getGroupParticipants, + getGroupAdmins, + getProfilePicFromServer, + downloadFileWithCredentials, + getGroupMetadata, + getBatteryLevel, + deleteConversation, + deleteMessages, + clearChat, + getNumberProfile, } from './functions'; -import * as jsSHA from './jssha'; import { _serializeChatObj, _serializeContactObj, @@ -40,6 +61,12 @@ import { _serializeProfilePicThumb, _serializeRawObj, } from './serializers'; + +import { + initNewMessagesListener, + addNewMessagesListener, + allNewMessagesListener, +} from './listeners'; import { getStore } from './store/get-store'; if (!window.Store || !window.Store.Msg) { @@ -88,37 +115,6 @@ window.WAPI.getChat = getChat; window.WAPI.getStatus = getStatus; window.WAPI.getChatByName = getChatByName; -window.WAPI.sendImageFromDatabasePicBot = function (picId, chatId, caption) { - var chatDatabase = window.WAPI.getChatByName('DATABASEPICBOT'); - var msgWithImg = chatDatabase.msgs.find((msg) => msg.caption == picId); - - if (msgWithImg === undefined) { - return false; - } - var chatSend = WAPI.getChat(chatId); - if (chatSend === undefined) { - return false; - } - const oldCaption = msgWithImg.caption; - - msgWithImg.id.id = getNewId(); - msgWithImg.id.remote = chatId; - msgWithImg.t = Math.ceil(new Date().getTime() / 1000); - msgWithImg.to = chatId; - - if (caption !== undefined && caption !== '') { - msgWithImg.caption = caption; - } else { - msgWithImg.caption = ''; - } - - msgWithImg.collection.send(msgWithImg).then(function (e) { - msgWithImg.caption = oldCaption; - }); - - return true; -}; - window.WAPI.getGeneratedUserAgent = function (useragent) { if (!useragent.includes('WhatsApp')) return 'WhatsApp/0.4.315 ' + useragent; return useragent.replace( @@ -135,202 +131,44 @@ window.WAPI.getWAVersion = function () { }; window.WAPI.sendMessageWithThumb = sendMessageWithThumb; +window.WAPI.revokeGroupInviteLink = revokeGroupInviteLink; window.WAPI.getGroupInviteLink = getGroupInviteLink; window.WAPI.getNewId = getNewId; window.WAPI.getChatById = getChatById; window.WAPI.getUnreadMessagesInChat = getUnreadMessagesInChat; -window.WAPI.loadChatEarlierMessages = loadChatEarlierMessages; +window.WAPI.loadEarlierMessages = loadChatEarlierMessages; window.WAPI.loadAllEarlierMessages = loadAllEarlierMessages; window.WAPI.asyncLoadAllEarlierMessages = asyncLoadAllEarlierMessages; +window.WAPI.areAllMessagesLoaded = areAllMessagesLoaded; +window.WAPI.loadEarlierMessagesTillDate = loadEarlierMessagesTillDate; +window.WAPI.getAllGroupMetadata = getAllGroupMetadata; +window.WAPI.getGroupMetadata = getGroupMetadata; -window.WAPI.areAllMessagesLoaded = function (id, done) { - const found = WAPI.getChat(id); - if (!found.msgs.msgLoadState.noEarlierMsgs) { - if (done) done(false); - return false; - } - if (done) done(true); - return true; -}; - -/** - * Load more messages in chat object from store by ID till a particular date - * - * @param id ID of chat - * @param lastMessage UTC timestamp of last message to be loaded - * @param done Optional callback function for async execution - * @returns None - */ - -window.WAPI.loadEarlierMessagesTillDate = function (id, lastMessage, done) { - const found = WAPI.getChat(id); - x = function () { - if ( - found.msgs.models[0].t > lastMessage && - !found.msgs.msgLoadState.noEarlierMsgs - ) { - found.loadEarlierMsgs().then(x); - } else { - done(); - } - }; - x(); -}; - -/** - * Fetches all group metadata objects from store - * - * @param done Optional callback function for async execution - * @returns {Array|*} List of group metadata - */ -window.WAPI.getAllGroupMetadata = function (done) { - const groupData = window.Store.GroupMetadata.map( - (groupData) => groupData.all - ); - - if (done !== undefined) done(groupData); - return groupData; -}; - -/** - * Fetches group metadata object from store by ID - * - * @param id ID of group - * @param done Optional callback function for async execution - * @returns {T|*} Group metadata object - */ -window.WAPI.getGroupMetadata = async function (id, done) { - let output = window.Store.GroupMetadata.find(id); - if (done !== undefined) done(output); - return output; -}; - -/** - * Fetches group participants - * - * @param id ID of group - * @returns {Promise.<*>} Yields group metadata - * @private - */ -window.WAPI._getGroupParticipants = async function (id) { - const metadata = await WAPI.getGroupMetadata(id); - return metadata.participants; -}; - -/** - * Fetches IDs of group participants - * - * @param id ID of group - * @param done Optional callback function for async execution - * @returns {Promise.} Yields list of IDs - */ -window.WAPI.getGroupParticipantIDs = async function (id, done) { - const output = (await WAPI._getGroupParticipants(id)).map( - (participant) => participant.id - ); - - if (done !== undefined) done(output); - return output; -}; - -window.WAPI.getGroupAdmins = async function (id, done) { - const output = (await WAPI._getGroupParticipants(id)) - .filter((participant) => participant.isAdmin) - .map((admin) => admin.id); - - if (done !== undefined) done(output); - return output; -}; - -/** - * Returns an object with all of your host device details - */ -window.WAPI.getMe = function () { - return Store.Me.attributes; -}; - -/** - * Gets object representing the logged in user - * - * @returns {Array|*|$q.all} - */ -window.WAPI.getMe = function (done) { - const rawMe = window.Store.Contact.get(window.Store.Conn.me); - - if (done !== undefined) done(rawMe.all); - return rawMe.all; -}; +window.WAPI._getGroupParticipants = _getGroupParticipants; +window.WAPI.getGroupParticipantIDs = getGroupParticipantIDs; +window.WAPI.getGroupAdmins = getGroupAdmins; +window.WAPI.getHost = getHost; +window.WAPI.getMe = getMe; window.WAPI.isLoggedIn = isLoggedIn; - -window.WAPI.isConnected = function (done) { - // Phone Disconnected icon appears when phone is disconnected from the tnternet - const isConnected = - document.querySelector('*[data-icon="alert-phone"]') !== null - ? false - : true; - - if (done !== undefined) done(isConnected); - return isConnected; -}; - +window.WAPI.isConnected = isConnected; window.WAPI.processMessageObj = processMessageObj; - -window.WAPI.getAllMessagesInChat = function ( - id, - includeMe, - includeNotifications, - done -) { - const chat = WAPI.getChat(id); - let output = []; - const messages = chat.msgs._models; - - for (const i in messages) { - if (i === 'remove') { - continue; - } - const messageObj = messages[i]; - - let message = WAPI.processMessageObj( - messageObj, - includeMe, - includeNotifications - ); - if (message) output.push(message); - } - if (done !== undefined) done(output); - return output; -}; - -window.WAPI.loadAndGetAllMessagesInChat = function ( - id, - includeMe, - includeNotifications, - done -) { - return WAPI.loadAllEarlierMessages(id).then((_) => { - const chat = WAPI.getChat(id); - let output = []; - const messages = chat.msgs._models; - - for (const i in messages) { - if (i === 'remove') { - continue; - } - const messageObj = messages[i]; - - let message = WAPI.processMessageObj( - messageObj, - includeMe, - includeNotifications - ); - if (message) output.push(message); - } - if (done !== undefined) done(output); - return output; - }); -}; +window.WAPI.getAllMessagesInChat = getAllMessagesInChat; +window.WAPI.loadAndGetAllMessagesInChat = loadAndGetAllMessagesInChat; + +window.WAPI.sendMessageWithTags = sendMessageWithTags; +window.WAPI.sendMessage = sendMessage; +window.WAPI.sendMessage2 = sendMessage2; +window.WAPI.sendSeen = sendSeen; +window.WAPI.getUnreadMessages = getUnreadMessages; +window.WAPI.getCommonGroups = getCommonGroups; +window.WAPI.getProfilePicFromServer = getProfilePicFromServer; +window.WAPI.downloadFileWithCredentials = downloadFileWithCredentials; +window.WAPI.getBatteryLevel = getBatteryLevel; +window.WAPI.deleteConversation = deleteConversation; +window.WAPI.deleteMessages = deleteMessages; +window.WAPI.clearChat = clearChat; +window.WAPI.getNumberProfile = getNumberProfile; window.WAPI.getAllMessageIdsInChat = function ( id, @@ -473,36 +311,6 @@ window.WAPI.sendMessageToID = function (id, message, done) { return false; }; -window.WAPI.sendMessageWithMentions = async function (ch, body) { - var chat = ch.id ? ch : Store.Chat.get(ch); - var chatId = chat.id._serialized; - var msgIveSent = chat.msgs.filter((msg) => msg.__x_isSentByMe)[0]; - if (!msgIveSent) return chat.sendMessage(body); - var tempMsg = Object.create(msgIveSent); - var newId = window.WAPI.getNewMessageId(chatId); - var mentionedJidList = - body - .match(/@(\d*)/g) - .map((x) => new Store.WidFactory.createUserWid(x.replace('@', ''))) || - undefined; - var extend = { - ack: 0, - id: newId, - local: !0, - self: 'out', - t: parseInt(new Date().getTime() / 1000), - to: new Store.WidFactory.createWid(chatId), - isNewMsg: !0, - type: 'chat', - body, - quotedMsg: null, - mentionedJidList, - }; - Object.assign(tempMsg, extend); - await Store.addAndSendMsgToChat(chat, tempMsg); - return newId._serialized; -}; - window.WAPI.sendMessageReturnId = async function (ch, body) { var chat = ch.id ? ch : Store.Chat.get(ch); var chatId = chat.id._serialized; @@ -527,187 +335,6 @@ window.WAPI.sendMessageReturnId = async function (ch, body) { return newId._serialized; }; -window.WAPI.sendMessage = function (id, message, done) { - var chat = WAPI.getChat(id); - function sleep(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); - } - if (chat !== undefined) { - if (done !== undefined) { - chat.sendMessage(message).then(function () { - var trials = 0; - - function check() { - for (let i = chat.msgs.models.length - 1; i >= 0; i--) { - let msg = chat.msgs.models[i]; - - if (!msg.senderObj.isMe || msg.body != message) { - continue; - } - done(WAPI._serializeMessageObj(msg)); - return True; - } - trials += 1; - console.log(trials); - if (trials > 30) { - done(true); - return; - } - sleep(500).then(check); - } - check(); - }); - return true; - } else { - // return WAPI.sendMessageReturnId(chat,message).then(id=>{return id}) - return chat - .sendMessage(message) - .then((_) => chat.lastReceivedKey._serialized); - } - } else { - if (done !== undefined) done(false); - return false; - } -}; - -window.WAPI.sendMessage2 = function (id, message, done) { - var chat = WAPI.getChat(id); - if (chat !== undefined) { - try { - if (done !== undefined) { - chat.sendMessage(message).then(function () { - done(true); - }); - } else { - chat.sendMessage(message); - } - return true; - } catch (error) { - if (done !== undefined) done(false); - return false; - } - } - if (done !== undefined) done(false); - return false; -}; - -window.WAPI.sendSeen = function (id, done) { - var chat = window.WAPI.getChat(id); - if (chat !== undefined) { - if (done !== undefined) { - Store.SendSeen(chat, false).then(function () { - done(true); - }); - return true; - } else { - Store.SendSeen(chat, false); - return true; - } - } - if (done !== undefined) done(); - return false; -}; - -function isChatMessage(message) { - if (message.isSentByMe) { - return false; - } - if (message.isNotification) { - return false; - } - if (!message.isUserCreatedType) { - return false; - } - return true; -} - -window.WAPI.getUnreadMessages = function ( - includeMe, - includeNotifications, - use_unread_count, - done -) { - const chats = window.Store.Chat.models; - let output = []; - - for (let chat in chats) { - if (isNaN(chat)) { - continue; - } - - let messageGroupObj = chats[chat]; - let messageGroup = WAPI._serializeChatObj(messageGroupObj); - - messageGroup.messages = []; - - const messages = messageGroupObj.msgs._models; - for (let i = messages.length - 1; i >= 0; i--) { - let messageObj = messages[i]; - if ( - typeof messageObj.isNewMsg != 'boolean' || - messageObj.isNewMsg === false - ) { - continue; - } else { - messageObj.isNewMsg = false; - let message = WAPI.processMessageObj( - messageObj, - includeMe, - includeNotifications - ); - if (message) { - messageGroup.messages.push(message); - } - } - } - - if (messageGroup.messages.length > 0) { - output.push(messageGroup); - } else { - // no messages with isNewMsg true - if (use_unread_count) { - let n = messageGroupObj.unreadCount; // will use unreadCount attribute to fetch last n messages from sender - for (let i = messages.length - 1; i >= 0; i--) { - let messageObj = messages[i]; - if (n > 0) { - if (!messageObj.isSentByMe) { - let message = WAPI.processMessageObj( - messageObj, - includeMe, - includeNotifications - ); - messageGroup.messages.unshift(message); - n -= 1; - } - } else if (n === -1) { - // chat was marked as unread so will fetch last message as unread - if (!messageObj.isSentByMe) { - let message = WAPI.processMessageObj( - messageObj, - includeMe, - includeNotifications - ); - messageGroup.messages.unshift(message); - break; - } - } else { - // unreadCount = 0 - break; - } - } - if (messageGroup.messages.length > 0) { - messageGroupObj.unreadCount = 0; // reset unread counter - output.push(messageGroup); - } - } - } - } - if (done !== undefined) { - done(output); - } - return output; -}; - window.WAPI.getGroupOwnerID = async function (id, done) { const output = (await WAPI.getGroupMetadata(id)).owner.id; if (done !== undefined) { @@ -716,34 +343,6 @@ window.WAPI.getGroupOwnerID = async function (id, done) { return output; }; -window.WAPI.getCommonGroups = async function (id, done) { - let output = []; - - groups = window.WAPI.getAllGroups(); - - for (let idx in groups) { - try { - participants = await window.WAPI.getGroupParticipantIDs(groups[idx].id); - if (participants.filter((participant) => participant == id).length) { - output.push(groups[idx]); - } - } catch (err) { - console.log('Error in group:'); - console.log(groups[idx]); - console.log(err); - } - } - - if (done !== undefined) { - done(output); - } - return output; -}; - -window.WAPI.getProfilePicFromServer = function (id) { - return Store.WapQuery.profilePicFind(id).then((x) => x.eurl); -}; - window.WAPI.getProfilePicSmallFromId = function (id, done) { window.Store.ProfilePicThumb.find(id).then( function (d) { @@ -774,35 +373,8 @@ window.WAPI.getProfilePicFromId = function (id, done) { ); }; -window.WAPI.downloadFileWithCredentials = function (url, done) { - let xhr = new XMLHttpRequest(); - - xhr.onload = function () { - if (xhr.readyState == 4) { - if (xhr.status == 200) { - let reader = new FileReader(); - reader.readAsDataURL(xhr.response); - reader.onload = function (e) { - done(reader.result.substr(reader.result.indexOf(',') + 1)); - }; - } else { - console.error(xhr.statusText); - } - } else { - console.log(err); - done(false); - } - }; - - xhr.open('GET', url, true); - xhr.withCredentials = true; - xhr.responseType = 'blob'; - xhr.send(null); -}; - window.WAPI.downloadFile = function (url, done) { let xhr = new XMLHttpRequest(); - xhr.onload = function () { if (xhr.readyState == 4) { if (xhr.status == 200) { @@ -825,94 +397,7 @@ window.WAPI.downloadFile = function (url, done) { xhr.send(null); }; -window.WAPI.getBatteryLevel = function (done) { - if (window.Store.Conn.plugged) { - if (done !== undefined) { - done(100); - } - return 100; - } - output = window.Store.Conn.battery; - if (done !== undefined) { - done(output); - } - return output; -}; - -window.WAPI.deleteConversation = function (chatId, done) { - let userId = new window.Store.UserConstructor(chatId, { - intentionallyUsePrivateConstructor: true, - }); - let conversation = WAPI.getChat(userId); - - if (!conversation) { - if (done !== undefined) { - done(false); - } - return false; - } - - window.Store.sendDelete(conversation, false) - .then(() => { - if (done !== undefined) { - done(true); - } - }) - .catch(() => { - if (done !== undefined) { - done(false); - } - }); - - return true; -}; - -window.WAPI.smartDeleteMessages = function ( - chatId, - messageArray, - onlyLocal, - done -) { - var userId = new Store.WidFactory.createWid(chatId); - let conversation = WAPI.getChat(userId); - if (!conversation) { - if (done !== undefined) { - done(false); - } - return false; - } - - if (!Array.isArray(messageArray)) { - messageArray = [messageArray]; - } - - let messagesToDelete = messageArray - .map((msgId) => - typeof msgId == 'string' ? window.Store.Msg.get(msgId) : msgId - ) - .filter((x) => x); - if (messagesToDelete.length == 0) return true; - let jobs = onlyLocal - ? [conversation.sendDeleteMsgs(messagesToDelete, conversation)] - : [ - conversation.sendRevokeMsgs( - messagesToDelete.filter((msg) => msg.isSentByMe), - conversation - ), - conversation.sendDeleteMsgs( - messagesToDelete.filter((msg) => !msg.isSentByMe), - conversation - ), - ]; - return Promise.all(jobs).then((_) => { - if (done !== undefined) { - done(true); - } - return true; - }); -}; - -window.WAPI.deleteMessage = function ( +window.WAPI.deleteMessage2 = function ( chatId, messageArray, revoke = false, @@ -951,34 +436,6 @@ window.WAPI.deleteMessage = function ( return true; }; -window.WAPI.clearChat = async function (id) { - return await Store.ChatUtil.sendClear(Store.Chat.get(id), true); -}; - -window.WAPI.checkNumberStatus = async function (id, done) { - try { - const result = await window.Store.WapQuery.queryExist(id); - if (result.jid === undefined) throw 404; - const data = window.WAPI._serializeNumberStatusObj(result); - if (data.status == 200) data.numberExists = true; - if (done !== undefined) { - done(window.WAPI._serializeNumberStatusObj(result)); - done(data); - } - return data; - } catch (e) { - if (done !== undefined) { - done( - window.WAPI._serializeNumberStatusObj({ - status: e, - jid: id, - }) - ); - } - return e; - } -}; - /** * New messages observable functions. */ @@ -993,99 +450,14 @@ window.WAPI._newMessagesCallbacks = []; window.Store.Msg.off('add'); sessionStorage.removeItem('saved_msgs'); -window.WAPI._newMessagesListener = window.Store.Msg.on('add', (newMessage) => { - if (newMessage && newMessage.isNewMsg && !newMessage.isSentByMe) { - let message = window.WAPI.processMessageObj(newMessage, false, false); - if (message) { - window.WAPI._newMessagesQueue.push(message); - window.WAPI._newMessagesBuffer.push(message); - } - - // Starts debouncer time to don't call a callback for each message if more than one message arrives - // in the same second - if ( - !window.WAPI._newMessagesDebouncer && - window.WAPI._newMessagesQueue.length > 0 - ) { - window.WAPI._newMessagesDebouncer = setTimeout(() => { - let queuedMessages = window.WAPI._newMessagesQueue; - - window.WAPI._newMessagesDebouncer = null; - window.WAPI._newMessagesQueue = []; - - let removeCallbacks = []; - - window.WAPI._newMessagesCallbacks.forEach(function (callbackObj) { - if (callbackObj.callback !== undefined) { - callbackObj.callback(queuedMessages); - } - if (callbackObj.rmAfterUse === true) { - removeCallbacks.push(callbackObj); - } - }); - - // Remove removable callbacks. - removeCallbacks.forEach(function (rmCallbackObj) { - let callbackIndex = window.WAPI._newMessagesCallbacks.indexOf( - rmCallbackObj - ); - window.WAPI._newMessagesCallbacks.splice(callbackIndex, 1); - }); - }, 1000); - } - } -}); - -window.WAPI._unloadInform = (event) => { - // Save in the buffer the ungot unreaded messages - window.WAPI._newMessagesBuffer.forEach((message) => { - Object.keys(message).forEach((key) => - message[key] === undefined ? delete message[key] : '' - ); - }); - sessionStorage.setItem( - 'saved_msgs', - JSON.stringify(window.WAPI._newMessagesBuffer) - ); - - // Inform callbacks that the page will be reloaded. - window.WAPI._newMessagesCallbacks.forEach(function (callbackObj) { - if (callbackObj.callback !== undefined) { - callbackObj.callback({ - status: -1, - message: 'page will be reloaded, wait and register callback again.', - }); - } - }); -}; +initNewMessagesListener(); window.addEventListener('unload', window.WAPI._unloadInform, false); window.addEventListener('beforeunload', window.WAPI._unloadInform, false); window.addEventListener('pageunload', window.WAPI._unloadInform, false); -/** - * Registers a callback to be called when a new message arrives the WAPI. - * @param rmCallbackAfterUse - Boolean - Specify if the callback need to be executed only once - * @param done - function - Callback function to be called when a new message arrives. - * @returns {boolean} - */ -window.WAPI.waitNewMessages = function (rmCallbackAfterUse = true, done) { - window.WAPI._newMessagesCallbacks.push({ - callback: done, - rmAfterUse: rmCallbackAfterUse, - }); - return true; -}; - -window.WAPI.addAllNewMessagesListener = (callback) => - window.Store.Msg.on('add', (newMessage) => { - if (newMessage && newMessage.isNewMsg) { - let message = window.WAPI.processMessageObj(newMessage, true, false); - if (message) { - callback(message); - } - } - }); +addNewMessagesListener(); +allNewMessagesListener(); /** * Registers a callback to be called when a the acknowledgement state of the phone connection. @@ -1093,7 +465,6 @@ window.WAPI.addAllNewMessagesListener = (callback) => * @returns {boolean} */ window.WAPI.onStateChanged = function (callback) { - // (x,y)=>console.log('statechanged',x,x.state) window.Store.State.default.on('change:state', callback); return true; }; @@ -1458,7 +829,7 @@ window.WAPI.getNewMessageId = function (chatId) { // .clone(); newMsgId.fromMe = true; - newMsgId.id = getNewId().toUpperCase(); + newMsgId.id = WAPI.getNewId().toUpperCase(); newMsgId.remote = chatId; newMsgId._serialized = `${newMsgId.fromMe}_${newMsgId.remote}_${newMsgId.id}`; @@ -2147,6 +1518,20 @@ window.WAPI.sendImageAsSticker = async function ( return await window.WAPI._sendSticker(encrypted, chatId, metadata); }; +window.WAPI.sendMessageMentioned = async function (chatId, message, mentioned) { + var chat = WAPI.getChat(chatId); + const user = await Store.Contact.serialize().find( + (x) => x.id.user === mentioned + ); + console.log(user); + chat.sendMessage(message, { + linkPreview: null, + mentionedJidList: [user.id], + quotedMsg: null, + quotedMsgAdminGroupJid: null, + }); +}; + /** This will dump all possible stickers into the chat. ONLY FOR TESTING. THIS IS REALLY ANNOYING!! */ @@ -2169,3 +1554,685 @@ window.WAPI._STICKERDUMP = async function (chatId) { /** * This next line is jsSha */ +('use strict'); +(function (I) { + function w(c, a, d) { + var l = 0, + b = [], + g = 0, + f, + n, + k, + e, + h, + q, + y, + p, + m = !1, + t = [], + r = [], + u, + z = !1; + d = d || {}; + f = d.encoding || 'UTF8'; + u = d.numRounds || 1; + if (u !== parseInt(u, 10) || 1 > u) + throw Error('numRounds must a integer >= 1'); + if (0 === c.lastIndexOf('SHA-', 0)) + if ( + ((q = function (b, a) { + return A(b, a, c); + }), + (y = function (b, a, l, f) { + var g, e; + if ('SHA-224' === c || 'SHA-256' === c) + (g = (((a + 65) >>> 9) << 4) + 15), (e = 16); + else throw Error('Unexpected error in SHA-2 implementation'); + for (; b.length <= g; ) b.push(0); + b[a >>> 5] |= 128 << (24 - (a % 32)); + a = a + l; + b[g] = a & 4294967295; + b[g - 1] = (a / 4294967296) | 0; + l = b.length; + for (a = 0; a < l; a += e) f = A(b.slice(a, a + e), f, c); + if ('SHA-224' === c) b = [f[0], f[1], f[2], f[3], f[4], f[5], f[6]]; + else if ('SHA-256' === c) b = f; + else throw Error('Unexpected error in SHA-2 implementation'); + return b; + }), + (p = function (b) { + return b.slice(); + }), + 'SHA-224' === c) + ) + (h = 512), (e = 224); + else if ('SHA-256' === c) (h = 512), (e = 256); + else throw Error('Chosen SHA variant is not supported'); + else throw Error('Chosen SHA variant is not supported'); + k = B(a, f); + n = x(c); + this.setHMACKey = function (b, a, g) { + var e; + if (!0 === m) throw Error('HMAC key already set'); + if (!0 === z) throw Error('Cannot set HMAC key after calling update'); + f = (g || {}).encoding || 'UTF8'; + a = B(a, f)(b); + b = a.binLen; + a = a.value; + e = h >>> 3; + g = e / 4 - 1; + if (e < b / 8) { + for (a = y(a, b, 0, x(c)); a.length <= g; ) a.push(0); + a[g] &= 4294967040; + } else if (e > b / 8) { + for (; a.length <= g; ) a.push(0); + a[g] &= 4294967040; + } + for (b = 0; b <= g; b += 1) + (t[b] = a[b] ^ 909522486), (r[b] = a[b] ^ 1549556828); + n = q(t, n); + l = h; + m = !0; + }; + this.update = function (a) { + var c, + f, + e, + d = 0, + p = h >>> 5; + c = k(a, b, g); + a = c.binLen; + f = c.value; + c = a >>> 5; + for (e = 0; e < c; e += p) + d + h <= a && ((n = q(f.slice(e, e + p), n)), (d += h)); + l += d; + b = f.slice(d >>> 5); + g = a % h; + z = !0; + }; + this.getHash = function (a, f) { + var d, h, k, q; + if (!0 === m) throw Error('Cannot call getHash after setting HMAC key'); + k = C(f); + switch (a) { + case 'HEX': + d = function (a) { + return D(a, e, k); + }; + break; + case 'B64': + d = function (a) { + return E(a, e, k); + }; + break; + case 'BYTES': + d = function (a) { + return F(a, e); + }; + break; + case 'ARRAYBUFFER': + try { + h = new ArrayBuffer(0); + } catch (v) { + throw Error('ARRAYBUFFER not supported by this environment'); + } + d = function (a) { + return G(a, e); + }; + break; + default: + throw Error('format must be HEX, B64, BYTES, or ARRAYBUFFER'); + } + q = y(b.slice(), g, l, p(n)); + for (h = 1; h < u; h += 1) q = y(q, e, 0, x(c)); + return d(q); + }; + this.getHMAC = function (a, f) { + var d, k, t, u; + if (!1 === m) + throw Error('Cannot call getHMAC without first setting HMAC key'); + t = C(f); + switch (a) { + case 'HEX': + d = function (a) { + return D(a, e, t); + }; + break; + case 'B64': + d = function (a) { + return E(a, e, t); + }; + break; + case 'BYTES': + d = function (a) { + return F(a, e); + }; + break; + case 'ARRAYBUFFER': + try { + d = new ArrayBuffer(0); + } catch (v) { + throw Error('ARRAYBUFFER not supported by this environment'); + } + d = function (a) { + return G(a, e); + }; + break; + default: + throw Error('outputFormat must be HEX, B64, BYTES, or ARRAYBUFFER'); + } + k = y(b.slice(), g, l, p(n)); + u = q(r, x(c)); + u = y(k, e, h, u); + return d(u); + }; + } + function m() {} + function D(c, a, d) { + var l = ''; + a /= 8; + var b, g; + for (b = 0; b < a; b += 1) + (g = c[b >>> 2] >>> (8 * (3 + (b % 4) * -1))), + (l += + '0123456789abcdef'.charAt((g >>> 4) & 15) + + '0123456789abcdef'.charAt(g & 15)); + return d.outputUpper ? l.toUpperCase() : l; + } + function E(c, a, d) { + var l = '', + b = a / 8, + g, + f, + n; + for (g = 0; g < b; g += 3) + for ( + f = g + 1 < b ? c[(g + 1) >>> 2] : 0, + n = g + 2 < b ? c[(g + 2) >>> 2] : 0, + n = + (((c[g >>> 2] >>> (8 * (3 + (g % 4) * -1))) & 255) << 16) | + (((f >>> (8 * (3 + ((g + 1) % 4) * -1))) & 255) << 8) | + ((n >>> (8 * (3 + ((g + 2) % 4) * -1))) & 255), + f = 0; + 4 > f; + f += 1 + ) + 8 * g + 6 * f <= a + ? (l += 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.charAt( + (n >>> (6 * (3 - f))) & 63 + )) + : (l += d.b64Pad); + return l; + } + function F(c, a) { + var d = '', + l = a / 8, + b, + g; + for (b = 0; b < l; b += 1) + (g = (c[b >>> 2] >>> (8 * (3 + (b % 4) * -1))) & 255), + (d += String.fromCharCode(g)); + return d; + } + function G(c, a) { + var d = a / 8, + l, + b = new ArrayBuffer(d), + g; + g = new Uint8Array(b); + for (l = 0; l < d; l += 1) + g[l] = (c[l >>> 2] >>> (8 * (3 + (l % 4) * -1))) & 255; + return b; + } + function C(c) { + var a = { outputUpper: !1, b64Pad: '=', shakeLen: -1 }; + c = c || {}; + a.outputUpper = c.outputUpper || !1; + !0 === c.hasOwnProperty('b64Pad') && (a.b64Pad = c.b64Pad); + if ('boolean' !== typeof a.outputUpper) + throw Error('Invalid outputUpper formatting option'); + if ('string' !== typeof a.b64Pad) + throw Error('Invalid b64Pad formatting option'); + return a; + } + function B(c, a) { + var d; + switch (a) { + case 'UTF8': + case 'UTF16BE': + case 'UTF16LE': + break; + default: + throw Error('encoding must be UTF8, UTF16BE, or UTF16LE'); + } + switch (c) { + case 'HEX': + d = function (a, b, c) { + var f = a.length, + d, + k, + e, + h, + q; + if (0 !== f % 2) + throw Error('String of HEX type must be in byte increments'); + b = b || [0]; + c = c || 0; + q = c >>> 3; + for (d = 0; d < f; d += 2) { + k = parseInt(a.substr(d, 2), 16); + if (isNaN(k)) + throw Error('String of HEX type contains invalid characters'); + h = (d >>> 1) + q; + for (e = h >>> 2; b.length <= e; ) b.push(0); + b[e] |= k << (8 * (3 + (h % 4) * -1)); + } + return { value: b, binLen: 4 * f + c }; + }; + break; + case 'TEXT': + d = function (c, b, d) { + var f, + n, + k = 0, + e, + h, + q, + m, + p, + r; + b = b || [0]; + d = d || 0; + q = d >>> 3; + if ('UTF8' === a) + for (r = 3, e = 0; e < c.length; e += 1) + for ( + f = c.charCodeAt(e), + n = [], + 128 > f + ? n.push(f) + : 2048 > f + ? (n.push(192 | (f >>> 6)), n.push(128 | (f & 63))) + : 55296 > f || 57344 <= f + ? n.push( + 224 | (f >>> 12), + 128 | ((f >>> 6) & 63), + 128 | (f & 63) + ) + : ((e += 1), + (f = + 65536 + + (((f & 1023) << 10) | (c.charCodeAt(e) & 1023))), + n.push( + 240 | (f >>> 18), + 128 | ((f >>> 12) & 63), + 128 | ((f >>> 6) & 63), + 128 | (f & 63) + )), + h = 0; + h < n.length; + h += 1 + ) { + p = k + q; + for (m = p >>> 2; b.length <= m; ) b.push(0); + b[m] |= n[h] << (8 * (r + (p % 4) * -1)); + k += 1; + } + else if ('UTF16BE' === a || 'UTF16LE' === a) + for ( + r = 2, + n = ('UTF16LE' === a && !0) || ('UTF16LE' !== a && !1), + e = 0; + e < c.length; + e += 1 + ) { + f = c.charCodeAt(e); + !0 === n && ((h = f & 255), (f = (h << 8) | (f >>> 8))); + p = k + q; + for (m = p >>> 2; b.length <= m; ) b.push(0); + b[m] |= f << (8 * (r + (p % 4) * -1)); + k += 2; + } + return { value: b, binLen: 8 * k + d }; + }; + break; + case 'B64': + d = function (a, b, c) { + var f = 0, + d, + k, + e, + h, + q, + m, + p; + if (-1 === a.search(/^[a-zA-Z0-9=+\/]+$/)) + throw Error('Invalid character in base-64 string'); + k = a.indexOf('='); + a = a.replace(/\=/g, ''); + if (-1 !== k && k < a.length) + throw Error("Invalid '=' found in base-64 string"); + b = b || [0]; + c = c || 0; + m = c >>> 3; + for (k = 0; k < a.length; k += 4) { + q = a.substr(k, 4); + for (e = h = 0; e < q.length; e += 1) + (d = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.indexOf( + q[e] + )), + (h |= d << (18 - 6 * e)); + for (e = 0; e < q.length - 1; e += 1) { + p = f + m; + for (d = p >>> 2; b.length <= d; ) b.push(0); + b[d] |= ((h >>> (16 - 8 * e)) & 255) << (8 * (3 + (p % 4) * -1)); + f += 1; + } + } + return { value: b, binLen: 8 * f + c }; + }; + break; + case 'BYTES': + d = function (a, b, c) { + var d, n, k, e, h; + b = b || [0]; + c = c || 0; + k = c >>> 3; + for (n = 0; n < a.length; n += 1) + (d = a.charCodeAt(n)), + (h = n + k), + (e = h >>> 2), + b.length <= e && b.push(0), + (b[e] |= d << (8 * (3 + (h % 4) * -1))); + return { value: b, binLen: 8 * a.length + c }; + }; + break; + case 'ARRAYBUFFER': + try { + d = new ArrayBuffer(0); + } catch (l) { + throw Error('ARRAYBUFFER not supported by this environment'); + } + d = function (a, b, c) { + var d, n, k, e, h; + b = b || [0]; + c = c || 0; + n = c >>> 3; + h = new Uint8Array(a); + for (d = 0; d < a.byteLength; d += 1) + (e = d + n), + (k = e >>> 2), + b.length <= k && b.push(0), + (b[k] |= h[d] << (8 * (3 + (e % 4) * -1))); + return { value: b, binLen: 8 * a.byteLength + c }; + }; + break; + default: + throw Error('format must be HEX, TEXT, B64, BYTES, or ARRAYBUFFER'); + } + return d; + } + function r(c, a) { + return (c >>> a) | (c << (32 - a)); + } + function J(c, a, d) { + return (c & a) ^ (~c & d); + } + function K(c, a, d) { + return (c & a) ^ (c & d) ^ (a & d); + } + function L(c) { + return r(c, 2) ^ r(c, 13) ^ r(c, 22); + } + function M(c) { + return r(c, 6) ^ r(c, 11) ^ r(c, 25); + } + function N(c) { + return r(c, 7) ^ r(c, 18) ^ (c >>> 3); + } + function O(c) { + return r(c, 17) ^ r(c, 19) ^ (c >>> 10); + } + function P(c, a) { + var d = (c & 65535) + (a & 65535); + return ( + ((((c >>> 16) + (a >>> 16) + (d >>> 16)) & 65535) << 16) | (d & 65535) + ); + } + function Q(c, a, d, l) { + var b = (c & 65535) + (a & 65535) + (d & 65535) + (l & 65535); + return ( + ((((c >>> 16) + (a >>> 16) + (d >>> 16) + (l >>> 16) + (b >>> 16)) & + 65535) << + 16) | + (b & 65535) + ); + } + function R(c, a, d, l, b) { + var g = (c & 65535) + (a & 65535) + (d & 65535) + (l & 65535) + (b & 65535); + return ( + ((((c >>> 16) + + (a >>> 16) + + (d >>> 16) + + (l >>> 16) + + (b >>> 16) + + (g >>> 16)) & + 65535) << + 16) | + (g & 65535) + ); + } + function x(c) { + var a = [], + d; + if (0 === c.lastIndexOf('SHA-', 0)) + switch ( + ((a = [ + 3238371032, + 914150663, + 812702999, + 4144912697, + 4290775857, + 1750603025, + 1694076839, + 3204075428, + ]), + (d = [ + 1779033703, + 3144134277, + 1013904242, + 2773480762, + 1359893119, + 2600822924, + 528734635, + 1541459225, + ]), + c) + ) { + case 'SHA-224': + break; + case 'SHA-256': + a = d; + break; + case 'SHA-384': + a = [ + new m(), + new m(), + new m(), + new m(), + new m(), + new m(), + new m(), + new m(), + ]; + break; + case 'SHA-512': + a = [ + new m(), + new m(), + new m(), + new m(), + new m(), + new m(), + new m(), + new m(), + ]; + break; + default: + throw Error('Unknown SHA variant'); + } + else throw Error('No SHA variants supported'); + return a; + } + function A(c, a, d) { + var l, + b, + g, + f, + n, + k, + e, + h, + m, + r, + p, + w, + t, + x, + u, + z, + A, + B, + C, + D, + E, + F, + v = [], + G; + if ('SHA-224' === d || 'SHA-256' === d) + (r = 64), + (w = 1), + (F = Number), + (t = P), + (x = Q), + (u = R), + (z = N), + (A = O), + (B = L), + (C = M), + (E = K), + (D = J), + (G = H); + else throw Error('Unexpected error in SHA-2 implementation'); + d = a[0]; + l = a[1]; + b = a[2]; + g = a[3]; + f = a[4]; + n = a[5]; + k = a[6]; + e = a[7]; + for (p = 0; p < r; p += 1) + 16 > p + ? ((m = p * w), + (h = c.length <= m ? 0 : c[m]), + (m = c.length <= m + 1 ? 0 : c[m + 1]), + (v[p] = new F(h, m))) + : (v[p] = x(A(v[p - 2]), v[p - 7], z(v[p - 15]), v[p - 16])), + (h = u(e, C(f), D(f, n, k), G[p], v[p])), + (m = t(B(d), E(d, l, b))), + (e = k), + (k = n), + (n = f), + (f = t(g, h)), + (g = b), + (b = l), + (l = d), + (d = t(h, m)); + a[0] = t(d, a[0]); + a[1] = t(l, a[1]); + a[2] = t(b, a[2]); + a[3] = t(g, a[3]); + a[4] = t(f, a[4]); + a[5] = t(n, a[5]); + a[6] = t(k, a[6]); + a[7] = t(e, a[7]); + return a; + } + var H; + H = [ + 1116352408, + 1899447441, + 3049323471, + 3921009573, + 961987163, + 1508970993, + 2453635748, + 2870763221, + 3624381080, + 310598401, + 607225278, + 1426881987, + 1925078388, + 2162078206, + 2614888103, + 3248222580, + 3835390401, + 4022224774, + 264347078, + 604807628, + 770255983, + 1249150122, + 1555081692, + 1996064986, + 2554220882, + 2821834349, + 2952996808, + 3210313671, + 3336571891, + 3584528711, + 113926993, + 338241895, + 666307205, + 773529912, + 1294757372, + 1396182291, + 1695183700, + 1986661051, + 2177026350, + 2456956037, + 2730485921, + 2820302411, + 3259730800, + 3345764771, + 3516065817, + 3600352804, + 4094571909, + 275423344, + 430227734, + 506948616, + 659060556, + 883997877, + 958139571, + 1322822218, + 1537002063, + 1747873779, + 1955562222, + 2024104815, + 2227730452, + 2361852424, + 2428436474, + 2756734187, + 3204031479, + 3329325298, + ]; + 'function' === typeof define && define.amd + ? define(function () { + return w; + }) + : 'undefined' !== typeof exports + ? ('undefined' !== typeof module && module.exports && (module.exports = w), + (exports = w)) + : (I.jsSHA = w); +})(this);