diff --git a/index.js b/index.js index 01a62a0..8562a50 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,29 @@ "use strict"; const bhttp = require("bhttp"); +const got = require("got"); -const stScrapeCategory = require("./lib/st/task/scrape-category"); -const stFindCategories = require("./lib/st/task/find-categories"); -const stScrapeProduct = require("./lib/st/task/scrape-product"); -const stNormalizeProduct = require("./lib/st/task/normalize-product"); -const lcscFindCategories = require("./lib/lcsc/task/find-categories"); -const lcscScrapeCategory = require("./lib/lcsc/task/scrape-category"); -const lcscNormalizeProduct = require("./lib/lcsc/task/normalize-product"); +const assureResponse = require("./lib/shared/assure-response"); let state = { session: bhttp.session({ headers: { "user-agent": "seekseek.org beta crawler (contact/problems: admin@cryto.net)" } + }), + // For HTTP/2, until bhttp gains HTTP/2 support + gotSession: got.extend({ + http2: true, + headers: { + // "user-agent": "seekseek.org beta crawler (contact/problems: admin@cryto.net)" + "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0" + }, + hooks: { + afterResponse: [(response) => { + assureResponse(response); + return response; + }] + } }) }; @@ -39,6 +48,12 @@ module.exports = { id: "tme:sitemap:index", tags: [ "tme:sitemap" ], data: { url: "https://www.tme.eu/en/sitemap.xml" } + // TODO: Delete derived sitemap entries + }, { + id: "farnell:sitemap:index", + tags: [ "farnell:sitemap" ], + data: { url: "https://uk.farnell.com/sitemap.xml" } + // TODO: Delete derived sitemap entries }], tags: { "st:home": [ "st:findCategories" ], @@ -49,65 +64,90 @@ module.exports = { "lcsc:product": [ "lcsc:normalizeProduct" ], "tme:sitemap": [ "tme:scrapeSitemap" ], "tme:product": [ "tme:scrapeProduct", "tme:normalizeProduct" ], + "farnell:sitemap": [ "farnell:scrapeSitemap" ], + "farnell:product": [ "farnell:scrapeProduct", "farnell:normalizeProduct" ], }, tasks: { + // ST Microelectronics "st:findCategories": { ttl: "15d", - run: stFindCategories(state) + run: require("./lib/st/task/find-categories")(state) }, "st:scrapeCategory": { ttl: "1d", taskInterval: "60s", version: "2", - run: stScrapeCategory(state) + run: require("./lib/st/task/scrape-category")(state) }, "st:scrapeProduct": { ttl: "15d", taskInterval: "5s", - run: stScrapeProduct(state) + run: require("./lib/st/task/scrape-product")(state) }, "st:normalizeProduct": { dependsOn: [ "st:scrapeProduct" ], version: "8", parallelTasks: Infinity, - run: stNormalizeProduct(state) + run: require("./lib/st/task/normalize-product")(state) }, + + // LCSC "lcsc:findCategories": { ttl: "30d", taskVersion: "1", - run: lcscFindCategories(state) + run: require("./lib/lcsc/task/find-categories")(state) }, "lcsc:scrapeCategory": { ttl: "30d", taskInterval: "1m", - run: lcscScrapeCategory(state) + run: require("./lib/lcsc/task/scrape-category")(state) }, "lcsc:normalizeProduct": { version: "7", parallelTasks: Infinity, - run: lcscNormalizeProduct(state) + run: require("./lib/lcsc/task/normalize-product")(state) }, + + // Mouser "mouser:scrapeSitemap": { taskInterval: "30s", run: require("./lib/mouser/task/scrape-sitemap")(state) }, + + // TME.eu "tme:scrapeSitemap": { ttl: "3d", taskInterval: "30s", - taskVersion: "1", run: require("./lib/tme/task/scrape-sitemap")(state) }, "tme:scrapeProduct": { ttl: "60d", - taskInterval: "1s", - taskVersion: "1", + taskInterval: "500ms", run: require("./lib/tme/task/scrape-product")(state) }, "tme:normalizeProduct": { dependsOn: [ "tme:scrapeProduct" ], - version: "3", + version: "5", parallelTasks: Infinity, run: require("./lib/tme/task/normalize-product")(state) }, + + // Farnell + "farnell:scrapeSitemap": { + ttl: "3d", + taskInterval: "30s", + run: require("./lib/farnell/task/scrape-sitemap")(state) + }, + "farnell:scrapeProduct": { + ttl: "60d", + taskInterval: "500ms", + run: require("./lib/farnell/task/scrape-product")(state) + }, + "farnell:normalizeProduct": { + dependsOn: [ "farnell:scrapeProduct" ], + version: "1", + parallelTasks: Infinity, + run: require("./lib/farnell/task/normalize-product")(state) + }, } }; diff --git a/lib/farnell/task/normalize-product.js b/lib/farnell/task/normalize-product.js new file mode 100644 index 0000000..a6f94a6 --- /dev/null +++ b/lib/farnell/task/normalize-product.js @@ -0,0 +1,21 @@ +"use strict"; + +const createDatasheet = require("../../shared/create-datasheet"); + +module.exports = function farnellNormalizeProduct() { + return async function (api) { + let { data } = api; + + createDatasheet(api, { + priority: 0.65, + source: "farnell", + manufacturer: data.itemData.manufacturer, + productID: data.itemData.productID, + name: data.itemData.model, + description: data.itemData.description, + url: data.itemData.datasheetURL, + // Farnell also shows manufacturer names in ALL-CAPS + fixCasing: true + }); + }; +}; diff --git a/lib/farnell/task/scrape-product.js b/lib/farnell/task/scrape-product.js new file mode 100644 index 0000000..52eab28 --- /dev/null +++ b/lib/farnell/task/scrape-product.js @@ -0,0 +1,31 @@ +"use strict"; + +const surgeon = require("../../shared/surgeon-utils"); + +// https://uk.farnell.com/molex/51281-2694/fpc-connector-rcpt-26pos-0-3mm/dp/3051223 + +module.exports = function farnellScrapeProduct({ gotSession }) { + return async function ({ data, updateData, expireDependents }) { + let response = await gotSession(data.url, { timeout: 30000 }); + + let detailsTable = surgeon(`selectOne ".productDescription dl" | extractDefinitionList`, response.body); + + let itemData = surgeon({ + datasheetURL: [ () => detailsTable, `maybeCell "Technical Datasheet:" | selectOne a | readAttr href` ], + manufacturer: `selectOne .schemaOrg | text`, + model: `selectOne .ManufacturerPartNumber | text`, + productID: `selectOne .ManufacturerOrderCode | text`, + description: `selectOne .pdpAttributesName | text`, + alsoKnownAs: [ () => detailsTable, `maybeCell "Also Known As:" | text` ] + }, response.body); + + // TODO: Merge self into productID-normalized item to deal gracefully with changing URLs + + updateData((oldData) => ({ + ... oldData, + itemData: itemData + })); + + expireDependents(); + }; +}; diff --git a/lib/farnell/task/scrape-sitemap.js b/lib/farnell/task/scrape-sitemap.js new file mode 100644 index 0000000..f3a334c --- /dev/null +++ b/lib/farnell/task/scrape-sitemap.js @@ -0,0 +1,51 @@ +"use strict"; + +const assert = require("assert"); + +const pipe = require("@promistream/pipe"); +const simpleSink = require("@promistream/simple-sink"); +const fromNodeStream = require("@promistream/from-node-stream"); +const decodeString = require("@promistream/decode-string"); +const parseSitemap = require("@promistream/parse-sitemap"); + +module.exports = function farnellScrapeSitemap({ gotSession }) { + return async function ({ data, createItem }) { + let resultCount = 0; + + await pipe([ + fromNodeStream.fromReadable(gotSession.stream(data.url)), + // NOTE: The URL lies, Farnell's sitemaps are not gzipped + decodeString("utf8"), + parseSitemap(), + simpleSink((item) => { + assert(item.url); + + if (item.type === "sitemap") { + // NOTE: We are only interested in the sitemaps that enumerate components, not those that list categories etc. + if (/products_[0-9]+\.xml(\.gz)?/.test(item.url)) { + createItem({ + id: `farnell:sitemap:${item.url}`, + tags: [ "farnell:sitemap" ], + data: { url: item.url } + }); + + resultCount += 1; + } + } else if (item.type === "url") { + if (/\/dp\/[0-9]+$/.test(item.url)) { + createItem({ + id: `farnell:product:${item.url}`, + tags: [ "farnell:product" ], + data: { url: item.url } + }); + + resultCount += 1; + } + } + }) + ]).read(); + + // If we don't get at least *some* items out of a sitemap, something is wrong - eg. the URL format changed and we are no longer matching anything. + assert(resultCount > 0); + }; +}; diff --git a/lib/shared/create-datasheet.js b/lib/shared/create-datasheet.js index c032b37..43f2922 100644 --- a/lib/shared/create-datasheet.js +++ b/lib/shared/create-datasheet.js @@ -1,28 +1,48 @@ "use strict"; const assert = require("assert"); +const capitalize = require("capitalize"); const pickBestOption = require("./pick-best-option"); const mapManufacturer = require("./map-manufacturer"); const normalizeString = require("./normalize-string"); +const syncpipe = require("syncpipe"); + +function fixCasing(name) { + let normalized = normalizeString(name); + + // NOTE: We ignore <= 4 character manufacturer names, as those are likely to be abbreviations, and therefore should remain all-uppercase + if (normalized.length > 4 && normalized === normalized.toUpperCase()) { + // String is in all-caps + return capitalize.words(normalized); + } else { + return normalized; + } +} module.exports = function createDatasheet(api, data) { let { createItem, mergeItem } = api; - let productID = normalizeString(data.productID); - let manufacturer = normalizeString(data.manufacturer); - let model = normalizeString(data.name); - let description = normalizeString(data.description); let url = normalizeString(data.url); - let source = data.source; - let priority = data.priority; - - assert(manufacturer != null); - assert(model != null); - + if (url != null) { - let mappedManufacturer = mapManufacturer(manufacturer); + let productID = normalizeString(data.productID); + let model = normalizeString(data.name); + let description = normalizeString(data.description); + let source = data.source; + let priority = data.priority; + let manufacturer = normalizeString(data.manufacturer); + assert(manufacturer != null); + assert(model != null); + + let mappedManufacturer = syncpipe(manufacturer, [ + (_) => (data.fixCasing === true) + ? fixCasing(_) + : _, + (_) => mapManufacturer(_) + ]); + let mappedID = `datasheet:${mappedManufacturer}:${model}`; let unmappedID = `datasheet:${manufacturer}:${model}`; diff --git a/lib/shared/map-manufacturer/mapping.js b/lib/shared/map-manufacturer/mapping.js index cf55412..cb5348d 100644 --- a/lib/shared/map-manufacturer/mapping.js +++ b/lib/shared/map-manufacturer/mapping.js @@ -18,6 +18,19 @@ module.exports = { "shenzhen sunyuan tech": "Sunyuan", "txc corp": "TXC", "LITTELFUSE": "Littelfuse", + "NEXPERIA": "Nexperia", + "TOSHIBA": "Toshiba", + "DIODES INCORPORATED": "Diodes Incorporated", + "ALLEGRO MICROSYSTEMS": "Allegro MicroSystems", + "Allegro MicroSystems, LLC": "Allegro MicroSystems", + "ETIPOLAM": "ETI Polam", + "Eti Polam": "ETI Polam", + "Pce": "PCE", + "3m Gcs": "3M", + "Okw": "OKW", + "Amphenol ICC": "Amphenol", + "omron electronics": "Omron", + "ck tools": "C.K", // From https://git.cryto.net/seekseek/scrape-documentation/issues/1 "2Pai Semi": "2Pai Semi", diff --git a/lib/shared/parse-sitemap-response.js b/lib/shared/parse-sitemap-response.js index 5ed17b2..80a6ab8 100644 --- a/lib/shared/parse-sitemap-response.js +++ b/lib/shared/parse-sitemap-response.js @@ -7,10 +7,15 @@ const fromNodeStream = require("@promistream/from-node-stream"); const parseSitemap = require("@promistream/parse-sitemap"); const pipe = require("@promistream/pipe"); -module.exports = function parseSitemapResponse(response) { +module.exports = function parseSitemapResponse(response, url) { + // NOTE: Explicitly specifying the URL is meant only for cases where bhttp is not used + let requestURL = (url != null) + ? url + : response.request.url; + return pipe([ - fromNodeStream(response), - (response.request.url.endsWith(".gz")) + fromNodeStream.fromReadable(response), + (requestURL.endsWith(".gz")) ? fromNodeStream(zlib.createGunzip()) : null, decodeString("utf8"), diff --git a/lib/shared/surgeon-utils.js b/lib/shared/surgeon-utils.js new file mode 100644 index 0000000..c4e79d3 --- /dev/null +++ b/lib/shared/surgeon-utils.js @@ -0,0 +1,251 @@ +"use strict"; + +const surgeon = require("surgeon"); +const pianola = require("pianola"); +const url = require("url"); +const flipArray = require("flip-array"); +const unreachable = require("@joepie91/unreachable")("seekseek:scrape-documentation"); + +function stripLines(input) { + return input + .split("\n") + .map((line) => line.trim()) + .filter((line) => line.length > 0) + .join("\n"); +} + +function deduplicateSpaces(input) { + return input.replace(/\s{2,}/g, " "); +} + +function cleanText(input) { + return deduplicateSpaces(stripLines(input)); +} + +function extractCell({ optional }) { + return function (input, [index], _options) { + let numericIndex = (input.labels != null) + // FIXME: Auto-detect number usage? + // TODO: Improve performance by avoiding loops, via eg. a lookup Map? + ? input.labels.indexOf(index) + // FIXME: index parsing as number? + : index; + + // HACK, refactor so that this conditional only actually occurs for label-based lookups + if (numericIndex === -1) { + if (optional) { + return new pianola.FinalResultSentinel(undefined); + } else { + throw new Error(`Specified label '${index}' does not exist in table`); + } + } else if (numericIndex >= input.cells.length) { + if (optional) { + return new pianola.FinalResultSentinel(undefined); + } else { + throw new Error(`Tried to access cell ${numericIndex}, but record only has cells 0-${input.cells.length - 1}`); + } + } else { + return input.cells[numericIndex]; + } + }; +} + +module.exports = surgeon.default({ + subroutines: { + trace: function (input) { + console.log("TRACE:", input); + return input; + }, + strip: function (input) { + return input.trim(); + }, + stripLines: stripLines, + removeLines: function (input) { + return deduplicateSpaces(input.replace(/\n/g, " ")); + }, + text: function (input, _values, options) { + return cleanText(surgeon.readSubroutine(input, ["property", "textContent"], options)); + }, + readProp: function (input, [property], options) { + return surgeon.readSubroutine(input, ["property", property], options); + }, + readAttr: function (input, [property], options) { + return surgeon.readSubroutine(input, ["attribute", property], options); + }, + selectN: function (input, [selector, n], options) { + return surgeon.selectSubroutine(input, [selector, `{${parseInt(n)+1},}[${n}]`], options); + }, + selectOne: function (input, [...selectors], options) { + return surgeon.selectSubroutine(input, [selectors.join(" "), `{1}`], options); + }, + selectAny: function (input, [...selectors], options) { + return surgeon.selectSubroutine(input, [selectors.join(" "), `{0,}`], options); + }, + selectMany: function (input, [ ... selectors ], options) { + return surgeon.selectSubroutine(input, [selectors.join(" "), `{1,}`], options); + }, + pickOne: function (input) { + if (!Array.isArray(input)) { + throw new Error("Input must be an array"); + } else if (input.length > 0) { + throw new Error(`Input array must only contain one element, got ${input.length} elements instead`); + } else { + return input[0]; + } + }, + result: function (input, [result], _options) { + return result; + }, + index: function (input, [index]) { + return input.eq(index); + }, + extractTable: function (input, [direction], options) { + let {evaluator} = options; + + let cells = evaluator.querySelectorAll(input, "tr").map((row) => { + return evaluator.querySelectorAll(row, "td, th"); + }); + + let records; + + if (direction === "vertical") { + records = cells; + } else if (direction === "horizontal") { + records = flipArray(cells); + } else { + throw new Error("Invalid table record direction specified. Must be one of: horizontal, vertical"); + } + + return records.map((record) => { + return {cells: record}; + }); + }, + labelRow: function (input, [ index ], options) { + let parsedIndex = parseInt(index); + let normalizedIndex = (parsedIndex >= 0) + ? parsedIndex + : input.length - index + 1; + + if (normalizedIndex > input.length - 1) { + throw new Error(`Invalid index ${index} specified for label row`); + } else { + let labelRow = input[normalizedIndex]; + + let labels = labelRow.cells.map((cell) => { + // FIXME: Abstract this out in some way + return cleanText(surgeon.readSubroutine(cell, [ "property", "textContent" ], options)); + }); + + let dataRows = input + .slice(0, normalizedIndex) + .concat(input.slice(normalizedIndex + 1)); + + return dataRows.map((row) => { + return { + ... row, + labels: labels + }; + }); + } + }, + // TODO: `labelRow 0` to label stuff + extractDefinitionList: function (input, _, options) { + let { evaluator } = options; + + let definitions = []; + let currentTerm; + + evaluator + .querySelectorAll(input, "dt, dd") + .forEach((node) => { + // TODO: This appears to be a cheerio oddity? Need to double-check that this won't break in the future. Maybe should use a surgeon-specific API? + let firstNode = node[0]; + + if (firstNode.name === "dt") { + // Term + currentTerm = node; + } else if (firstNode.name === "dd") { + // Definition + if (currentTerm != null) { + definitions.push({ + // TODO: Support custom filters for terms (eg. to remove superscript text) + term: cleanText(surgeon.readSubroutine(currentTerm, ["property", "textContent"], options)), + definition: node + }); + + currentTerm = undefined; + } else { + // Ignore any superfluous definitions + } + } else { + throw unreachable(`Unknown node type ${firstNode.name}`); + } + }); + + // We conceptually represent a definition list as a single-row table with pre-labeled columns/cells + return { + labels: definitions.map((item) => item.term), + cells: definitions.map((item) => item.definition) + }; + }, + cell: extractCell({ optional: false }), + maybeCell: extractCell({ optional: true }), + isMatch: function (input, [regex], _options) { + let matcher = new RegExp(regex); + return matcher.test(input); + }, + binaryBytes: function (input) { + let matcher = new RegExp(`^(${regex.number})\s?([kKmMgGtTpP])i?[bB]$`); + let match = matcher.exec(input); + + if (match == null) { + throw new Error(`Not recognized as a binary byte amount: ${input}`); + } else { + let number = parseInt(match[1]); + let unit = match[2].toLowerCase(); + + if (unit === "k") { + return number * 1024; + } else if (unit === "m") { + return number * 1024 * 1024; + } else if (unit === "g") { + return number * 1024 * 1024 * 1024; + } else if (unit === "t") { + return number * 1024 * 1024 * 1024 * 1024; + } else if (unit === "p") { + return number * 1024 * 1024 * 1024 * 1024 * 1024; + } + } + }, + KiB: function (input) { + return parseInt(input) * 1024; + }, + MiB: function (input) { + return parseInt(input) * 1024 * 1024; + }, + GiB: function (input) { + return parseInt(input) * 1024 * 1024 * 1024; + }, + TiB: function (input) { + return parseInt(input) * 1024 * 1024 * 1024 * 1024; + }, + integer: function (input) { + return parseInt(input); + }, + number: function (input) { + return parseFloat(input); + }, + kbps: function (input) { + return parseInt(input) * 1000; + }, + mbps: function (input) { + return parseInt(input) * 1000 * 1000; + }, + gbps: function (input) { + return parseInt(input) * 1000 * 1000 * 1000; + }, + absoluteUrl: function (input, [base], _options) { + return url.resolve(base, input); + } + } +});; diff --git a/lib/tme/task/normalize-product.js b/lib/tme/task/normalize-product.js index a0ab51a..d92eceb 100644 --- a/lib/tme/task/normalize-product.js +++ b/lib/tme/task/normalize-product.js @@ -38,7 +38,9 @@ module.exports = function tmeNormalizeProduct() { productID: productID, name: modelName, description: description, - url: bestDocument.url + url: bestDocument.url, + // NOTE: Most (but not all!) manufacturers on TME are, incorrectly, in ALL-CAPS. This 'fixes' those cases through best-effort capitalization. Many (but less!) will still be wrong and need to be fixed later. + fixCasing: true }); } }; diff --git a/lib/tme/task/scrape-product.js b/lib/tme/task/scrape-product.js index 2a215ed..c01aee4 100644 --- a/lib/tme/task/scrape-product.js +++ b/lib/tme/task/scrape-product.js @@ -35,15 +35,26 @@ module.exports = function tmeScrapeProduct({ session }) { allMetaHeaders["TME Symbol:"] ), description: $(".c-pip__sub-name").eq(0).text().trim(), - documents: $("a.c-pip__downloads-file-link").toArray().map((link) => { - return { - description: $(link).text().trim(), - url: url.resolve( - data.url, - $(link).attr("href") - ) - }; - }), + documents: $("a.c-pip__downloads-file-link").toArray() + .map((link) => { + let relativeLink = $(link).attr("href"); + + if (relativeLink != null) { + return { + description: $(link).text().trim(), + url: url.resolve( + data.url, + relativeLink + ) + }; + } else { + // Probably a video popup + return null; + } + }) + .filter((item) => { + return item != null; + }), // TODO: Scrape prices }; diff --git a/package.json b/package.json index 22a7d86..5b1e245 100644 --- a/package.json +++ b/package.json @@ -6,17 +6,23 @@ "author": "Sven Slootweg ", "license": "WTFPL OR CC0-1.0", "dependencies": { + "@joepie91/unreachable": "^1.0.0", "@promistream/decode-string": "^0.1.0", "@promistream/from-node-stream": "^0.1.0", "@promistream/pipe": "^0.1.4", "@promistream/simple-sink": "^0.1.1", "bhttp": "^1.2.8", "bluebird": "^3.7.2", + "capitalize": "^2.0.3", "cheerio": "^1.0.0-rc.5", "default-value": "^1.0.0", + "flip-array": "^0.1.0", + "got": "^11.8.2", "html-entities": "^2.1.1", "map-obj": "^4.2.0", "match-value": "^1.1.0", + "pianola": "^2.2.1", + "surgeon": "^3.16.4", "syncpipe": "^1.0.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index bcff67f..0fc2de1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -204,6 +204,52 @@ bluebird "^3.7.2" error-chain "^0.1.0" +"@sindresorhus/is@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4" + integrity sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ== + +"@szmarczak/http-timer@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" + integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== + dependencies: + defer-to-connect "^2.0.0" + +"@types/cacheable-request@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" + integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "*" + "@types/node" "*" + "@types/responselike" "*" + +"@types/http-cache-semantics@*": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" + integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== + +"@types/keyv@*": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" + integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== + dependencies: + "@types/node" "*" + +"@types/node@*": + version "14.14.37" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" + integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== + +"@types/responselike@*", "@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + "@validatem/allow-extra-properties@^0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@validatem/allow-extra-properties/-/allow-extra-properties-0.1.0.tgz#e8c434818d6fd74b8cb237cfaa4d548295de13c1" @@ -494,7 +540,7 @@ acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -ajv@^6.10.0, ajv@^6.12.4: +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -605,6 +651,11 @@ boolbase@^1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= +boolean@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.3.tgz#0fee0c9813b66bef25a8a6a904bb46736d05f024" + integrity sha512-EqrTKXQX6Z3A2nRmMEIlAIfjQOgFnVO2nqZGpbcsPnYGWBwpFqzlrozU1dy+S2iqfYDLh26ef4KrgTxu9xQrxA== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -618,6 +669,24 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" + integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^2.0.0" + call-bind@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -631,6 +700,11 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +capitalize@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/capitalize/-/capitalize-2.0.3.tgz#ccfeb1046d2a054eb30f34af907a70c3e90f3b73" + integrity sha512-Qc5ksT1/zEJBbFYD05h99hCNEW0cgyD0zzE5WvkgisNnppJ+16zfaSk34evF0j6pGW8hejkRUeygJ5uN5k22SQ== + chalk@^2.0.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -659,7 +733,7 @@ cheerio-select-tmp@^0.1.0: domhandler "^4.0.0" domutils "^2.4.4" -cheerio@^1.0.0-rc.5: +cheerio@^1.0.0-rc.3, cheerio@^1.0.0-rc.5: version "1.0.0-rc.5" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.5.tgz#88907e1828674e8f9fee375188b27dadd4f0fa2f" integrity sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw== @@ -679,6 +753,13 @@ clone-regexp@^2.1.0: dependencies: is-regexp "^2.0.0" +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -712,6 +793,11 @@ combined-stream2@^1.0.2: debug "^2.1.1" stream-length "^1.0.1" +commander@^2.19.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -776,6 +862,13 @@ debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: dependencies: ms "2.1.2" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + deep-is@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -788,11 +881,33 @@ default-value@^1.0.0: dependencies: es6-promise-try "0.0.1" +defer-to-connect@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +detect-node@^2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" + integrity sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw== + dev-null@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/dev-null/-/dev-null-0.1.1.tgz#5a205ce3c2b2ef77b6238d6ba179eb74c6a0e818" integrity sha1-WiBc48Ky73e2I41roXnrdMag6Bg= +discontinuous-range@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" + integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo= + doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -835,6 +950,13 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enquirer@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -880,6 +1002,11 @@ errors@^0.2.0: resolved "https://registry.yarnpkg.com/errors/-/errors-0.2.0.tgz#0f51e889daa3e11b19e7186d11f104aa66eb2403" integrity sha1-D1Hoidqj4RsZ5xhtEfEEqmbrJAM= +es6-error@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + es6-promise-try@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/es6-promise-try/-/es6-promise-try-0.0.1.tgz#10f140dad27459cef949973e5d21a087f7274b20" @@ -1053,6 +1180,11 @@ flatten@^1.0.3: resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== +flip-array@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/flip-array/-/flip-array-0.1.0.tgz#0836c461a8d128272003106bf6721b7d7b93cb0c" + integrity sha1-CDbEYajRKCcgAxBr9nIbfXuTyww= + form-data2@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/form-data2/-/form-data2-1.0.4.tgz#9f91ebd83003f9e117f94f1ebd72665ae0b49a40" @@ -1098,6 +1230,13 @@ get-intrinsic@^1.0.2: has "^1.0.3" has-symbols "^1.0.1" +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + glob-parent@^5.0.0: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -1131,6 +1270,30 @@ globals@^13.6.0: dependencies: type-fest "^0.20.2" +globalthis@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b" + integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ== + dependencies: + define-properties "^1.1.3" + +got@^11.8.2: + version "11.8.2" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" + integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.1" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1168,6 +1331,19 @@ htmlparser2@^6.0.0: domutils "^2.4.4" entities "^2.0.0" +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -1288,6 +1464,11 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -1303,6 +1484,18 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= +json-stringify-safe@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +keyv@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" + integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== + dependencies: + json-buffer "3.0.1" + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -1326,6 +1519,11 @@ lodash@^4.17.20, lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -1348,6 +1546,16 @@ mime@^1.3.4: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -1355,6 +1563,11 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +moo@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.1.tgz#7aae7f384b9b09f620b6abf6f74ebbcd1b65dbc4" + integrity sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -1370,6 +1583,21 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +nearley@^2.19.0: + version "2.20.1" + resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.20.1.tgz#246cd33eff0d012faf197ff6774d7ac78acdd474" + integrity sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ== + dependencies: + commander "^2.19.0" + moo "^0.5.0" + railroad-diagrams "^1.0.0" + randexp "0.4.6" + +normalize-url@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + nth-check@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" @@ -1377,7 +1605,12 @@ nth-check@^2.0.0: dependencies: boolbase "^1.0.0" -once@^1.3.0: +object-keys@^1.0.12: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -1396,6 +1629,11 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +p-cancelable@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.0.tgz#4d51c3b91f483d02a0d300765321fca393d758dd" + integrity sha512-HAZyB3ZodPo+BDpb4/Iu7Jv4P6cSazBz9ZM0ChhEXp70scx834aWCEjQRwgt41UzzejUAPdbqqONfRWTPYrPAQ== + p-defer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-3.0.0.tgz#d1dceb4ee9b2b604b1d94ffec83760175d4e6f83" @@ -1456,6 +1694,16 @@ path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +pianola@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/pianola/-/pianola-2.2.1.tgz#c601237fb86e8b270ca31390c95e68733f1a08aa" + integrity sha512-hjsiNUZaZ69ePplDSKS1ifOt2ncXDnEywqSyz2piugQD5odTaoOGSmbMiVJS7XFMu9fw8100F8pYNZaYPIbSeQ== + dependencies: + ajv "^6.10.2" + es6-error "^4.1.1" + nearley "^2.19.0" + roarr "^2.14.6" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -1476,11 +1724,37 @@ psl@^1.1.28: resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +railroad-diagrams@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e" + integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234= + +randexp@0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3" + integrity sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ== + dependencies: + discontinuous-range "1.0.0" + ret "~0.1.10" + readable-stream@^2.2.2: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -1504,6 +1778,11 @@ readable-stream@~1.0.17: isarray "0.0.1" string_decoder "~0.10.x" +regex-parser@^2.2.10: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" @@ -1514,11 +1793,28 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +resolve-alpn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c" + integrity sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA== + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +responselike@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" + integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== + dependencies: + lowercase-keys "^2.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -1526,11 +1822,28 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +roarr@^2.14.6, roarr@^2.15.3: + version "2.15.4" + resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd" + integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A== + dependencies: + boolean "^3.0.1" + detect-node "^2.0.4" + globalthis "^1.0.1" + json-stringify-safe "^5.0.1" + semver-compare "^1.0.0" + sprintf-js "^1.1.2" + safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + semver@^7.2.1: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" @@ -1569,6 +1882,11 @@ split-filter@^1.1.3: resolved "https://registry.yarnpkg.com/split-filter/-/split-filter-1.1.3.tgz#c68cc598783d88f60d16e7b452dacfe95ba60539" integrity sha512-2xXwhWeJUFrYE8CL+qoy9mCohu5/E+uglvpqL1FVXz1XbvTwivafVC6oTDeg/9ksOAxg6DvyCF44Dvf5crFU0w== +sprintf-js@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -1628,6 +1946,17 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +surgeon@^3.16.4: + version "3.16.4" + resolved "https://registry.yarnpkg.com/surgeon/-/surgeon-3.16.4.tgz#058c1b5cdeb440dfb52b58040d67b157ce57863d" + integrity sha512-EU/3MI7Pznh+Z9y+QRz6RE8UEMcf46RTmXyWR5vpq39nSw83stTDMegF+pLV9YYJ5FjKwEG1BkoV7n4VhKYfHA== + dependencies: + cheerio "^1.0.0-rc.3" + es6-error "^4.1.1" + pianola "^2.2.1" + regex-parser "^2.2.10" + roarr "^2.15.3" + syncpipe@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/syncpipe/-/syncpipe-1.0.0.tgz#170340f813150bc8fcb8878b1b9c71ea0ccd3727"