├── .gitattributes ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── index.js ├── package.json ├── src ├── gallery.js ├── get.js └── parse.js ├── test └── index.js └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | 75 | # FuseBox cache 76 | .fusebox/ 77 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /test 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 神代綺凜 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nhentai-api-js 2 | 3 | > This package is deprecated and no longer maintained, please use [nhentai-js](https://www.npmjs.com/package/nhentai-js) instead. 4 | 5 | **This is an unofficial API.** 6 | 7 | It was developed because [official API has been suspended indefinitely](https://twitter.com/fuckmaou/status/1084550608097603585). 8 | 9 | But now you don't need it anymore, [official API is re-enabled](https://twitter.com/fuckmaou/status/1113868849500303363). 10 | 11 | ## Example 12 | 13 | ```javascript 14 | const nHentaiAPI = require('nhentai-api-js'); 15 | let api = new nHentaiAPI(); 16 | 17 | // Details of https://nhentai.net/g/263492/ 18 | api.g(263492).then(gallery => { 19 | console.log(JSON.stringify(gallery)); // (1) 20 | console.log(gallery.getPages()); // (2) 21 | console.log(gallery.getPagesThumbnail()); // (3) 22 | console.log(gallery.getCover()); // (4) 23 | console.log(gallery.getCoverThumbnail()); // (5) 24 | }); 25 | 26 | // Search "艦隊これくしょん" 27 | api.search('艦隊これくしょん').then(data => console.log(JSON.stringify(data))); // (6) 28 | ``` 29 | 30 | There are what you will get (formatted): 31 | 32 | ### (1) Doujin details (same as the official original API) 33 | 34 | ```javascript 35 | { 36 | "id": 263492, 37 | "media_id": "1367250", 38 | "title": { 39 | "english": "(C95) [Sawayaka Tokunou Milk (Arumamai Ayuka+)] Hibiki-chan no Fuwafuwa Tsuihoshuu! (Kantai Collection -KanColle-) [Chinese] [山樱汉化]", 40 | "japanese": "(C95) [爽やか特濃みるく (在誠舞あゆか+)] 響ちゃんのふわふわ追補習! (艦隊これくしょん -艦これ-) [中国翻訳]", 41 | "pretty": "Hibiki-chan no Fuwafuwa Tsuihoshuu!" 42 | }, 43 | "images": { 44 | "pages": [ 45 | { 46 | "t": "p", 47 | "w": 1280, 48 | "h": 1803 49 | }, 50 | ... 51 | ], 52 | "cover": { 53 | "t": "p", 54 | "w": 350, 55 | "h": 493 56 | }, 57 | "thumbnail": { 58 | "t": "p", 59 | "w": 250, 60 | "h": 352 61 | } 62 | }, 63 | "scanlator": "", 64 | "upload_date": 1550445627, 65 | "tags": [ 66 | { 67 | "id": 1841, 68 | "type": "parody", 69 | "name": "kantai collection", 70 | "url": "/parody/kantai-collection/", 71 | "count": 11888 72 | }, 73 | ... 74 | ], 75 | "num_pages": 24, 76 | "num_favorites": 0 77 | } 78 | ``` 79 | 80 | ### (2) Pages `string[]` 81 | 82 | ```javascript 83 | [ 84 | 'https://i.nhentai.net/galleries/1367250/1.png', 85 | 'https://i.nhentai.net/galleries/1367250/2.png', 86 | 'https://i.nhentai.net/galleries/1367250/3.png', 87 | ... 88 | 'https://i.nhentai.net/galleries/1367250/24.png' 89 | ] 90 | ``` 91 | 92 | ### (3) Pages thumbnail `string[]` 93 | 94 | ```javascript 95 | [ 96 | 'https://t.nhentai.net/galleries/1367250/1t.png', 97 | 'https://t.nhentai.net/galleries/1367250/2t.png', 98 | 'https://t.nhentai.net/galleries/1367250/3t.png', 99 | ... 100 | 'https://t.nhentai.net/galleries/1367250/24t.png' 101 | ] 102 | ``` 103 | 104 | ### (4) Cover `string` 105 | 106 | ```text 107 | https://t.nhentai.net/galleries/1367250/cover.png 108 | ``` 109 | 110 | ### (5) Cover thumbnail `string` 111 | 112 | ```text 113 | https://t.nhentai.net/galleries/1367250/thumb.png 114 | ``` 115 | 116 | ### (6) Search 117 | 118 | \* Some old doujin may have no `thumbnail.w` and `thumbnail.h` 119 | 120 | ```javascript 121 | { 122 | "num_results": 11706, 123 | "num_pages": 469, 124 | "results": [ 125 | { 126 | "id": "263511", 127 | "title": "(C87) [Hiroshikidou (Hiroshiki)] Yuudachi Satte Hi ga Shizumu (Kantai Collection -KanColle-)[Chinese][基德漢化組]", 128 | "language": "chinese", 129 | "thumbnail": { 130 | "s": "https://t.nhentai.net/galleries/1367411/thumb.jpg", 131 | "w": "250", 132 | "h": "353" 133 | } 134 | }, 135 | ... 136 | ] 137 | } 138 | ``` 139 | 140 | ## APIs 141 | 142 | ### nHentaiAPI 143 | 144 | - `constructor nHentaiAPI(baseURL?: string): nHentaiAPI` 145 | - `baseURL` — Default is `'https://nhentai.net'` 146 | - `nHentaiAPI.g(id: string | number): Promise` — Get doujin details 147 | - `id` — Gallery ID 148 | - `nHentaiAPI.homepage(page?: number): Promise` — Get doujin list from homepage 149 | - `page` — Page num 150 | - `nHentaiAPI.random(): Promise` — Get a random doujin 151 | - `nHentaiAPI.search(keyword: string, page?: number, sort?: string): Promise` 152 | - `keyword` — Keyword [(learn more)](https://nhentai.net/info/) 153 | - `page` — Page num (default is `1`) 154 | - `sort` — `'date'` (default) or `'popular'` 155 | - `nHentaiAPI.tag(name: string, page?: number, sort?: string): Promise` 156 | `nHentaiAPI.artist` 157 | `nHentaiAPI.character` 158 | `nHentaiAPI.parody` 159 | `nHentaiAPI.group` 160 | - `name` — Name of tag / artist / character / parody / group 161 | - `page` — Page num (default is `1`) 162 | - `sort` — `'date'` (default) or `'popular'` 163 | 164 | ### nHentaiGallery 165 | 166 | - `nHentaiGallery.getPages(baseURL?: string): string[]` — Get a URL list of pages 167 | - `baseURL` — Default is `'https://i.nhentai.net'` 168 | - `nHentaiGallery.getPagesThumbnail(baseURL?: string): string[]` — Get a URL list of pages thumbnail 169 | `nHentaiGallery.getCover(baseURL?: string): string` — Get a URL of cover 170 | `nHentaiGallery.getCoverThumbnail(baseURL?: string): string` — Get a URL of cover thumbnail 171 | - `baseURL` — Default is `'https://t.nhentai.net'` 172 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: Jindai Kirin 3 | * @Date: 2019-02-18 16:33:33 4 | * @Last Modified by: Jindai Kirin 5 | * @Last Modified time: 2019-02-24 15:31:59 6 | */ 7 | 8 | const getHTML = require('./src/get'); 9 | const Parse = require('./src/parse'); 10 | const nHentaiGallery = require('./src/gallery'); 11 | const Qs = require('qs'); 12 | 13 | async function parseDetailsHTML(url) { 14 | return Parse.details(await getHTML(url).catch(e => { 15 | if (e.response.status == 404) throw new Error('Doujin Not Found'); 16 | else throw e; 17 | })); 18 | } 19 | 20 | async function parseListHTML(url) { 21 | return Parse.list(await getHTML(url).catch(e => { 22 | if (e.response.status == 404) throw new Error('Parameter Error'); 23 | else throw e; 24 | })); 25 | } 26 | 27 | /** 28 | * nHentai API 29 | * 30 | * @class nHentaiAPI 31 | */ 32 | class nHentaiAPI { 33 | /** 34 | * Creates an instance of nHentaiAPI. 35 | * @param {string} [baseURL='https://nhentai.net'] nHentai base URL 36 | * @memberof nHentaiAPI 37 | */ 38 | constructor(baseURL = 'https://nhentai.net') { 39 | this.baseURL = baseURL; 40 | } 41 | 42 | /** 43 | * Get doujin details 44 | * 45 | * @param {string|number} id Gallery ID 46 | * @returns nHentaiGallery object 47 | * @memberof nHentaiAPI 48 | */ 49 | async g(id) { 50 | return new nHentaiGallery(await parseDetailsHTML(`${this.baseURL}/g/${id}/`)); 51 | } 52 | 53 | /** 54 | * Search doujin 55 | * 56 | * @param {string} keyword Keyword 57 | * @param {number} [page=1] Page num 58 | * @param {string} [sort='date'] "date" (default) or "popular" 59 | * @returns Doujin list object 60 | * @memberof nHentaiAPI 61 | */ 62 | search(keyword, page = 1, sort = 'date') { 63 | let query = Qs.stringify({ 64 | q: keyword, 65 | page, 66 | sort 67 | }); 68 | return parseListHTML(`${this.baseURL}/search/?${query}`); 69 | } 70 | 71 | 72 | /** 73 | * Get doujin list from homepage 74 | * 75 | * @param {number} [page=1] Page num 76 | * @returns Doujin list object 77 | * @memberof nHentaiAPI 78 | */ 79 | homepage(page = 1) { 80 | let query = Qs.stringify({ 81 | page 82 | }); 83 | return parseListHTML(`${this.baseURL}/?${query}`); 84 | } 85 | 86 | /** 87 | * Get a random doujin 88 | * 89 | * @returns Doujin details object 90 | * @memberof nHentaiAPI 91 | */ 92 | random() { 93 | return parseDetailsHTML(`${this.baseURL}/random/`); 94 | } 95 | 96 | /** 97 | * Get doujin list by tag 98 | * 99 | * @param {string} name Tag name 100 | * @param {number} [page=1] Page num 101 | * @param {string} [sort='date'] "date" (default) or "popular" 102 | * @returns Doujin list object 103 | * @memberof nHentaiAPI 104 | */ 105 | tag(name, page = 1, sort = 'date') { 106 | let query = Qs.stringify({ 107 | page 108 | }); 109 | return parseListHTML(`${this.baseURL}/tag/${name.replace(' ','-')}/${sort=='date'?'':sort}?${query}`); 110 | } 111 | 112 | /** 113 | * Get doujin list by artist 114 | * 115 | * @param {string} name Artist name 116 | * @param {number} [page=1] Page num 117 | * @param {string} [sort='date'] "date" (default) or "popular" 118 | * @returns Doujin list object 119 | * @memberof nHentaiAPI 120 | */ 121 | artist(name, page = 1, sort = 'date') { 122 | let query = Qs.stringify({ 123 | page 124 | }); 125 | return parseListHTML(`${this.baseURL}/tag/${name.replace(' ','-')}/${sort=='date'?'':sort}?${query}`); 126 | } 127 | 128 | /** 129 | * Get doujin list by character 130 | * 131 | * @param {string} name Character name 132 | * @param {number} [page=1] Page num 133 | * @param {string} [sort='date'] "date" (default) or "popular" 134 | * @returns Doujin list object 135 | * @memberof nHentaiAPI 136 | */ 137 | character(name, page = 1, sort = 'date') { 138 | let query = Qs.stringify({ 139 | page 140 | }); 141 | return parseListHTML(`${this.baseURL}/tag/${name.replace(' ','-')}/${sort=='date'?'':sort}?${query}`); 142 | } 143 | 144 | /** 145 | * Get doujin list by parody 146 | * 147 | * @param {string} name Parody name 148 | * @param {number} [page=1] Page num 149 | * @param {string} [sort='date'] "date" (default) or "popular" 150 | * @returns Doujin list object 151 | * @memberof nHentaiAPI 152 | */ 153 | parody(name, page = 1, sort = 'date') { 154 | let query = Qs.stringify({ 155 | page 156 | }); 157 | return parseListHTML(`${this.baseURL}/tag/${name.replace(' ','-')}/${sort=='date'?'':sort}?${query}`); 158 | } 159 | 160 | /** 161 | * Get doujin list by group 162 | * 163 | * @param {string} name Group name 164 | * @param {number} [page=1] Page num 165 | * @param {string} [sort='date'] "date" (default) or "popular" 166 | * @returns Doujin list object 167 | * @memberof nHentaiAPI 168 | */ 169 | group(name, page = 1, sort = 'date') { 170 | let query = Qs.stringify({ 171 | page 172 | }); 173 | return parseListHTML(`${this.baseURL}/tag/${name.replace(' ','-')}/${sort=='date'?'':sort}?${query}`); 174 | } 175 | } 176 | 177 | module.exports = nHentaiAPI; 178 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nhentai-api-js", 3 | "version": "1.1.4", 4 | "description": "Unofficial API for nHentai", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test/index.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Tsuk1ko/nhentai-api-js.git" 12 | }, 13 | "keywords": [ 14 | "nhentai", 15 | "api" 16 | ], 17 | "author": "Jindai Kirin", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/Tsuk1ko/nhentai-api-js/issues" 21 | }, 22 | "homepage": "https://github.com/Tsuk1ko/nhentai-api-js", 23 | "dependencies": { 24 | "axios": "^0.19.2", 25 | "cheerio": "^1.0.0-rc.3", 26 | "qs": "^6.9.4" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/gallery.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: Jindai Kirin 3 | * @Date: 2019-02-24 13:42:14 4 | * @Last Modified by: Jindai Kirin 5 | * @Last Modified time: 2019-02-24 15:00:37 6 | */ 7 | 8 | const TYPE = { 9 | j: 'jpg', 10 | p: 'png', 11 | g: 'gif' 12 | }; 13 | 14 | class nHentaiGallery { 15 | /** 16 | * Creates an instance of nHentaiGallery. 17 | * @param {*} obj Doujin details object 18 | * @memberof nHentaiGallery 19 | */ 20 | constructor(obj) { 21 | for (let key in obj) { 22 | this[key] = obj[key]; 23 | } 24 | } 25 | 26 | /** 27 | * Get a URL list of pages 28 | * 29 | * @param {string} [baseURL='https://i.nhentai.net'] Base URL 30 | * @returns URL list 31 | * @memberof nHentaiGallery 32 | */ 33 | getPages(baseURL = 'https://i.nhentai.net') { 34 | let pages = []; 35 | this.images.pages.forEach((page, i) => { 36 | pages.push(`${baseURL}/galleries/${this.media_id}/${i+1}.${TYPE[page.t]}`); 37 | }); 38 | return pages; 39 | } 40 | 41 | /** 42 | * Get a URL list of pages thumbnail 43 | * 44 | * @param {string} [baseURL='https://t.nhentai.net'] Base URL 45 | * @returns URL list 46 | * @memberof nHentaiGallery 47 | */ 48 | getPagesThumbnail(baseURL = 'https://t.nhentai.net') { 49 | let pages = []; 50 | this.images.pages.forEach((page, i) => { 51 | pages.push(`${baseURL}/galleries/${this.media_id}/${i+1}t.${TYPE[page.t]}`); 52 | }); 53 | return pages; 54 | } 55 | 56 | /** 57 | * Get a URL of cover 58 | * 59 | * @param {string} [baseURL='https://t.nhentai.net'] Base URL 60 | * @returns URL 61 | * @memberof nHentaiGallery 62 | */ 63 | getCover(baseURL = 'https://t.nhentai.net') { 64 | return `${baseURL}/galleries/${this.media_id}/cover.${TYPE[this.images.cover.t]}`; 65 | } 66 | 67 | /** 68 | * Get a URL of cover thumbnail 69 | * 70 | * @param {string} [baseURL='https://t.nhentai.net'] Base URL 71 | * @returns URL 72 | * @memberof nHentaiGallery 73 | */ 74 | getCoverThumbnail(baseURL = 'https://t.nhentai.net') { 75 | return `${baseURL}/galleries/${this.media_id}/thumb.${TYPE[this.images.cover.t]}`; 76 | } 77 | } 78 | 79 | 80 | 81 | module.exports = nHentaiGallery; 82 | -------------------------------------------------------------------------------- /src/get.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: Jindai Kirin 3 | * @Date: 2019-02-18 13:28:24 4 | * @Last Modified by: Jindai Kirin 5 | * @Last Modified time: 2019-02-18 18:14:11 6 | */ 7 | 8 | const Axios = require('axios'); 9 | 10 | /** 11 | * Get nHentai HTML 12 | * 13 | * @param {string} url URL 14 | * @returns Axios promise 15 | */ 16 | module.exports = (url) => Axios.get(url).then(ret => ret.data); 17 | -------------------------------------------------------------------------------- /src/parse.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: Jindai Kirin 3 | * @Date: 2019-02-18 14:49:30 4 | * @Last Modified by: Jindai Kirin 5 | * @Last Modified time: 2019-03-25 18:22:02 6 | */ 7 | 8 | const Cheerio = require('cheerio'); 9 | const Qs = require('qs'); 10 | 11 | /** 12 | * Parse details page 13 | * 14 | * @param {string} html 15 | * @returns Object 16 | */ 17 | function details(html) { 18 | let json = /(?<=gallery\()\{.+\}(?=\);)/.exec(html)[0]; 19 | let obj = JSON.parse(json); 20 | // For consistency such as https://nhentai.net/g/66/ 21 | if (typeof obj.id == 'string') obj.id = parseInt(obj.id); 22 | return obj; 23 | } 24 | 25 | /** 26 | * Parse list page 27 | * 28 | * @param {string} html 29 | * @returns Object 30 | */ 31 | function list(html) { 32 | const $ = Cheerio.load(html, { 33 | decodeEntities: false 34 | }); 35 | 36 | let results = []; 37 | $('.gallery').each((i, e) => { 38 | let $this = $(e); 39 | let $thumb = $this.find('.cover>img'); 40 | 41 | let language = ''; 42 | let dataTags = $this.attr('data-tags').split(' '); 43 | if (dataTags.includes('6346')) language = 'japanese'; 44 | else if (dataTags.includes('12227')) language = 'english'; 45 | else if (dataTags.includes('29963')) language = 'chinese'; 46 | 47 | results.push({ 48 | id: /(?<=\/g\/).+(?=\/)/.exec($this.find('.cover').attr('href'))[0], 49 | title: $this.find('.caption').html(), 50 | language, 51 | thumbnail: { 52 | s: $thumb.attr('data-src') || $thumb.attr('src').replace(/^\/\//, 'https://'), 53 | w: $thumb.attr('width'), 54 | h: $thumb.attr('height') 55 | } 56 | }); 57 | }); 58 | 59 | let addon = {}; 60 | if ($('#content>h2').length > 0) addon.num_results = parseInt($('#content>h2').html().replace(',', '')) || 0; 61 | if ($('.pagination').length > 0) addon.num_pages = parseInt(Qs.parse($(`.pagination>${$('.pagination>.last').length>0?'.last':'.current'}`).attr('href').substring(1)).page); 62 | 63 | return { 64 | ...addon, 65 | results 66 | }; 67 | } 68 | 69 | module.exports = { 70 | details, 71 | list 72 | }; 73 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | const nHentaiAPI = require('..'); 2 | 3 | let api = new nHentaiAPI(); 4 | 5 | async function log(promise) { 6 | console.log(JSON.stringify(await promise, null, 4)); 7 | } 8 | 9 | // log(api.g(263492)); 10 | // log(api.search('艦隊これくしょん')); 11 | // log(api.search('艦隊これくしょん',2,'popular')); 12 | // log(api.homepage()); 13 | // log(api.random()); 14 | // log(api.tag('anal')); 15 | // log(api.tag('anal', 2, 'popular')); 16 | 17 | // api.g(263492).then(gallery => { 18 | // console.log(gallery.getPages()); 19 | // console.log(gallery.getPagesThumbnail()); 20 | // console.log(gallery.getCover()); 21 | // console.log(gallery.getCoverThumbnail()); 22 | // }); 23 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/node@*": 6 | version "14.0.5" 7 | resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.5.tgz#3d03acd3b3414cf67faf999aed11682ed121f22b" 8 | integrity sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA== 9 | 10 | axios@^0.19.2: 11 | version "0.19.2" 12 | resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" 13 | integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== 14 | dependencies: 15 | follow-redirects "1.5.10" 16 | 17 | boolbase@~1.0.0: 18 | version "1.0.0" 19 | resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" 20 | integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= 21 | 22 | cheerio@^1.0.0-rc.3: 23 | version "1.0.0-rc.3" 24 | resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6" 25 | integrity sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA== 26 | dependencies: 27 | css-select "~1.2.0" 28 | dom-serializer "~0.1.1" 29 | entities "~1.1.1" 30 | htmlparser2 "^3.9.1" 31 | lodash "^4.15.0" 32 | parse5 "^3.0.1" 33 | 34 | css-select@~1.2.0: 35 | version "1.2.0" 36 | resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" 37 | integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= 38 | dependencies: 39 | boolbase "~1.0.0" 40 | css-what "2.1" 41 | domutils "1.5.1" 42 | nth-check "~1.0.1" 43 | 44 | css-what@2.1: 45 | version "2.1.3" 46 | resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" 47 | integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== 48 | 49 | debug@=3.1.0: 50 | version "3.1.0" 51 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 52 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 53 | dependencies: 54 | ms "2.0.0" 55 | 56 | dom-serializer@0: 57 | version "0.2.2" 58 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" 59 | integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== 60 | dependencies: 61 | domelementtype "^2.0.1" 62 | entities "^2.0.0" 63 | 64 | dom-serializer@~0.1.1: 65 | version "0.1.1" 66 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" 67 | integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== 68 | dependencies: 69 | domelementtype "^1.3.0" 70 | entities "^1.1.1" 71 | 72 | domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: 73 | version "1.3.1" 74 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" 75 | integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== 76 | 77 | domelementtype@^2.0.1: 78 | version "2.0.1" 79 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" 80 | integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== 81 | 82 | domhandler@^2.3.0: 83 | version "2.4.2" 84 | resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" 85 | integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== 86 | dependencies: 87 | domelementtype "1" 88 | 89 | domutils@1.5.1: 90 | version "1.5.1" 91 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" 92 | integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= 93 | dependencies: 94 | dom-serializer "0" 95 | domelementtype "1" 96 | 97 | domutils@^1.5.1: 98 | version "1.7.0" 99 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" 100 | integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== 101 | dependencies: 102 | dom-serializer "0" 103 | domelementtype "1" 104 | 105 | entities@^1.1.1, entities@~1.1.1: 106 | version "1.1.2" 107 | resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" 108 | integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== 109 | 110 | entities@^2.0.0: 111 | version "2.0.2" 112 | resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.2.tgz#ac74db0bba8d33808bbf36809c3a5c3683531436" 113 | integrity sha512-dmD3AvJQBUjKpcNkoqr+x+IF0SdRtPz9Vk0uTy4yWqga9ibB6s4v++QFWNohjiUGoMlF552ZvNyXDxz5iW0qmw== 114 | 115 | follow-redirects@1.5.10: 116 | version "1.5.10" 117 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" 118 | integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== 119 | dependencies: 120 | debug "=3.1.0" 121 | 122 | htmlparser2@^3.9.1: 123 | version "3.10.1" 124 | resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" 125 | integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== 126 | dependencies: 127 | domelementtype "^1.3.1" 128 | domhandler "^2.3.0" 129 | domutils "^1.5.1" 130 | entities "^1.1.1" 131 | inherits "^2.0.1" 132 | readable-stream "^3.1.1" 133 | 134 | inherits@^2.0.1, inherits@^2.0.3: 135 | version "2.0.4" 136 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 137 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 138 | 139 | lodash@^4.15.0: 140 | version "4.17.15" 141 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" 142 | integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== 143 | 144 | ms@2.0.0: 145 | version "2.0.0" 146 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 147 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 148 | 149 | nth-check@~1.0.1: 150 | version "1.0.2" 151 | resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" 152 | integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== 153 | dependencies: 154 | boolbase "~1.0.0" 155 | 156 | parse5@^3.0.1: 157 | version "3.0.3" 158 | resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" 159 | integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== 160 | dependencies: 161 | "@types/node" "*" 162 | 163 | qs@^6.9.4: 164 | version "6.9.4" 165 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" 166 | integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ== 167 | 168 | readable-stream@^3.1.1: 169 | version "3.6.0" 170 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" 171 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 172 | dependencies: 173 | inherits "^2.0.3" 174 | string_decoder "^1.1.1" 175 | util-deprecate "^1.0.1" 176 | 177 | safe-buffer@~5.2.0: 178 | version "5.2.1" 179 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 180 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 181 | 182 | string_decoder@^1.1.1: 183 | version "1.3.0" 184 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 185 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 186 | dependencies: 187 | safe-buffer "~5.2.0" 188 | 189 | util-deprecate@^1.0.1: 190 | version "1.0.2" 191 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 192 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 193 | --------------------------------------------------------------------------------