commit 05cb1eafe8a7c88990aa9d9072c917dc550fcb2c Author: Sven Slootweg Date: Sun Mar 29 16:19:22 2020 +0200 WIP diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..780a211 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +keys.txt +config.json +node_modules \ No newline at end of file diff --git a/blah.html b/blah.html new file mode 100644 index 0000000..3a7fc6d --- /dev/null +++ b/blah.html @@ -0,0 +1,864 @@ + + + + + + + + Digital Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+ + +
+
+ +
+
+ + + + + +
+
+
+ +
+ + + + + + + + Zoeken op: 8710654160037 + + + + + + + + +
+ +
+
+ + + +
+
+ + + + +
+ +
+ + +
+ + + + + + + + + + + + + + + + diff --git a/get-barcode.js b/get-barcode.js new file mode 100644 index 0000000..4e18a4e --- /dev/null +++ b/get-barcode.js @@ -0,0 +1,232 @@ +"use strict"; + +const Promise = require("bluebird"); +const bhttp = require("bhttp").session({ headers: { "user-agent": "barcodebot (problems: admin@cryto.net)" } }); +const dotty = require("dotty"); +const cheerio = require("cheerio"); +const url = require("url"); +const chalk = require("chalk"); + +const config = require("./config.json"); +const parseFoodbook = require("./parse-foodbook"); + +function log(barcode, message) { + console.log(`${chalk.cyan(`[${barcode}]`)} ${message}`); +} + +function mapCurrency(abbreviation) { + if (abbreviation === "USD") { + return "$"; + } else if (abbreviation === "EUR") { + return "€"; + } else { + throw new Error(`Unrecognized currency: ${abbreviation}`); + } +} + +function cleanValue(value) { + if(value != null) { + return value.replace(/\n/g, " ").replace(/\s+/, " ").trim(); + } +} + +let barcodeGetters = [ + getBarcode_coop, + getBarcode_bolCom, + getBarcode_buycott, + getBarcode_foodBook, + getBarcode_eanData, + getBarcode_openFoodFacts, +]; + +module.exports = function getBarcode(barcode) { + return Promise.try(() => { + return Promise.reduce(barcodeGetters, (lastResult, getter) => { + if (lastResult == null) { + return getter(barcode); + } else { + return lastResult; + } + }, null); + }).then((result) => { + if (result != null) { + return { + ... result, + image: (result.image !== "") ? result.image : null + }; + } else { + return null; + } + }) +}; + +function getBarcode_eanData(barcode) { + return Promise.try(() => { + log(barcode, "Trying EANData..."); + + return bhttp.get(`https://eandata.com/feed/?v=3&keycode=${config.apiKeys.eanData}&mode=json&find=${barcode}`); + }).then((response) => { + if (response.statusCode === 200) { + let productName = dotty.get(response.body, "product.attributes.product"); + + if (productName != null) { + + let data = { + name: cleanValue(productName), + image: dotty.get(response.body, "product.image") + }; + + let priceCurrency = dotty.get(response.body, "product.attributes.price_new_extra"); + let priceAmount = dotty.get(response.body, "product.attributes.price_new"); + + if (priceAmount != null) { + data.price = `${mapCurrency(priceCurrency)} ${priceAmount}`; + } + + return data; + } else { + return null; + } + } else { + return null; + } + }); +} + +let coop404Regex = /We kunnen de pagina die je zoekt niet vinden/; + +function getBarcode_coop(barcode) { + return Promise.try(() => { + log(barcode, "Trying Coop..."); + + return bhttp.get(`https://www.coop.nl/inventory/product/${barcode}`); + }).then((response) => { + if (response.statusCode === 200 && !coop404Regex.test(response.body.toString())) { + let $ = cheerio.load(response.body); + let $imageNoscript = cheerio.load($("picture noscript").html()); + + return { + name: cleanValue($(".detailHeader").text().trim().replace(/\n/g, " - ")), + // image: $('meta[property="og:image"]').attr("content"), + image: $imageNoscript('img').attr("src"), + price: `€ ${$(".mainActions ins.price").text()}` + }; + } else { + return null; + } + }); +} + +function getBarcode_foodBook(barcode) { + return Promise.try(() => { + log(barcode, "Trying FoodBook..."); + + return bhttp.post(`https://foodbook.psinfoodservice.com/prod/dc`, { + "SelectedFilterOptions.collapseFilterId": "filterkeywordPanelBody", + "SelectedFilterOptions.FreeText": "", + "SelectedFilterOptions.ProductGroupId": "", + "SelectedFilterOptions.BrandId": "", + "SelectedFilterOptions.GrossierId": "", + "SelectedFilterOptions.Ean": barcode, + "SelectedFilterOptions.ProducerNumber": "", + "SelectedFilterOptions.GrossierNumber": "", + "PS_brands_input": "", + "PS_brands": "" + }); + }).then((response) => { + let products = parseFoodbook.parseSearch(response.body); + + if (products.length > 0) { + return Promise.try(() => { + let productUrl = url.resolve("https://foodbook.psinfoodservice.com/prod/dc", products[0]); + + return bhttp.get(productUrl); + }).then((response) => { + if (response.statusCode === 200) { + return parseFoodbook.parseProduct(response.body); + } else { + return null; + } + }); + } else { + return null; + } + }); +} + +function getBarcode_openFoodFacts(barcode) { + return Promise.try(() => { + log(barcode, "Trying OpenFoodFacts..."); + + return bhttp.get(`https://world.openfoodfacts.org/api/v0/product/${encodeURIComponent(barcode)}.json`); + }).then((response) => { + if (response.statusCode === 200 && response.body.status === 1 && response.body.product.product_name != null) { + return { + name: cleanValue(response.body.product.product_name), + image: response.body.product.image_url + }; + } else { + return null; + } + }); +} + +function getBarcode_buycott(barcode) { + return Promise.try(() => { + log(barcode, "Trying Buycott..."); + + return bhttp.get(`https://www.buycott.com/upc/${encodeURIComponent(barcode)}`); + }).then((response) => { + if (response.statusCode === 200) { + let $ = cheerio.load(response.body); + + let product = cleanValue($("#container_header h2").text()); + + let tableData = $("table.product_info_table tr").get().map((row) => { + let $row = $(row); + + return [ + cleanValue($row.find("td:nth-child(1)").text()), + cleanValue($row.find("td:nth-child(2)").text()), + ]; + }); + + let brandRow = tableData.find(([key, value]) => (key === "GS1 Name")); + + let productName; + + if (brandRow != null) { + productName = `${brandRow[1]}, ${product}`; + } else { + productName = product; + } + + return { + name: productName, + image: $(".header_image img").attr("src") + }; + } + }); +} + +function getBarcode_bolCom(barcode) { + return Promise.try(() => { + log(barcode, "Trying bol.com..."); + + return bhttp.get(`https://www.bol.com/nl/s/algemeen/zoekresultaten/Ntt/${encodeURIComponent(barcode)}/N/0/Nty/1/search/true/searchType/qck/defaultSearchContext/media_all/sc/media_all/index.html`); + }).then((response) => { + if (response.statusCode === 200) { + let $ = cheerio.load(response.body); + + let productName = cleanValue($(".pdp-header__title").text()); + + if (productName.length > 0) { + return { + name: productName, + image: $(".js_product_img").attr("src"), + price: `€ ${cleanValue($(".promo-price").text())}` + }; + } + } + }); +} diff --git a/index.js b/index.js new file mode 100644 index 0000000..cc0491c --- /dev/null +++ b/index.js @@ -0,0 +1,82 @@ +"use strict"; + +const unhandledError = require("unhandled-error"); + +const config = require("./config.json"); +const shortenUrl = require("./shorten-url"); + +unhandledError((error) => { + console.error(error.stack); +}); + +const Promise = require("bluebird"); +const IRC = require("irc-framework"); + +const getBarcode = require("./get-barcode"); + +function cleanBarcode(barcode) { + return barcode.replace(/[^0-9]+/g, ""); +} + +let eanRegex = /^([0-9]{8}|[0-9]{13})$/; + +let bot = new IRC.Client(); + +bot.on("message", (event) => { + let match, barcode, explicit; + + if (eanRegex.test(event.message)) { + barcode = event.message; + explicit = false; + } else if ((match = /^!barcode (.+)$/.exec(event.message)) != null) { + if (true || eanRegex.test(match[1])) { + barcode = match[1]; + + explicit = true; + } else { + event.reply("Ongeldige barcode!"); + return; + } + } + + if (barcode != null) { + return Promise.try(() => { + console.log(`Looking up: ${barcode}`); + + return getBarcode(cleanBarcode(barcode)); + }).then((result) => { + console.log(result); + + if (result == null) { + if (explicit === true) { + event.reply("Barcode niet gevonden!") + } + } else { + let price = (result.price != null) + ? result.price + : "onbekend"; + + return Promise.try(() => { + if (result.image != null) { + return shortenUrl(result.image); + } else { + return "niet beschikbaar"; + } + }).then((image) => { + event.reply(`${result.name} -- Prijsindicatie: ${price} -- Productfoto: ${image}`); + }); + } + }); + } +}) + +bot.on("registered", () => { + console.log("Connected!"); + bot.join(config.irc.channel); +}); + +bot.connect({ + host: config.irc.host, + port: config.irc.port, + nick: config.irc.nick +}); diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..d8dfbd1 --- /dev/null +++ b/notes.txt @@ -0,0 +1,112 @@ +https://www.coop.nl/dr-oetker-big-americans-hawaii/product/4001724023876 + +https://eandata.com/feed/?v=3&keycode=&mode=json&find=0025192251344 + +{ + "status": { + "version": "3.1", + "code": "200", + "message": "free 0/15", + "find": "0025192251344", + "search": "normal", + "run": "0.2021", + "runtime": "0.2113" + }, + "product": { + "attributes": { + "product": "Jaws", + "url": "http://www.jaws25.com/", + "model": "29466797", + "price_new": "6.9400", + "price_new_extra": "USD", + "price_new_extra_long": "US Dollars", + "price_new_extra_id": "537", + "price_used": "4.9900", + "price_used_extra": "USD", + "price_used_extra_long": "US Dollars", + "price_used_extra_id": "537", + "asin_com": "B00MA5KL9I", + "category": "55", + "category_text": "Movie", + "category_text_long": "Electronics / Photography: A/V Media: Movie", + "width": "5.3000", + "width_extra": "in", + "width_extra_long": "inches", + "width_extra_id": "501", + "height": "0.3500", + "height_extra": "in", + "height_extra_long": "inches", + "height_extra_id": "501", + "length": "6.7500", + "length_extra": "in", + "length_extra_long": "inches", + "length_extra_id": "501", + "weight": "15.0000", + "weight_extra": "lb/100", + "weight_extra_long": "hundredths pounds", + "weight_extra_id": "765", + "long_desc": "*** only visible with paid data feed ***", + "features": "Shrink-wrapped", + "binding": "Blu-ray", + "published": "2016-01-26", + "similar": "0012569828476, 0025192092824, 0025192279218, 0025192347627, 0025192354595, 0025192354601, 0025192354618, 0032429134967, 0043396374003, 0043396496941, 0097361467641, 0191329029053, 0191329047200, 0709112696308, 5051368208930, 5051892007344, 5053083090555, 9780783282336", + "release_year": "1975.0000", + "movie_cast": "*** only visible with paid data feed ***", + "movie_aspect": "2.35:1", + "format": "Multiple Formats, Blu-ray, Ultraviolet, Color, Widescreen", + "movie_genre": "Action/Adventure", + "movie_rating": "743", + "movie_rating_text": "PG", + "movie_rating_text_long": "PG - Parental Guidance Suggested", + "runtime": "124.0000", + "runtime_extra": "minutes", + "runtime_extra_long": "minutes", + "runtime_extra_id": "753", + "movie_imdb": "*** only visible with paid data feed ***", + "movie_runtime": "124.0000", + "movie_runtime_extra": "minutes", + "movie_runtime_extra_long": "minutes", + "movie_runtime_extra_id": "753", + "music_runtime": "124.0000", + "music_runtime_extra": "minutes", + "music_runtime_extra_long": "minutes", + "music_runtime_extra_id": "753", + "movie_director": "Steven Spielberg", + "movie_imdb_trailer": "*** only visible with paid data feed ***" + }, + "EAN13": "0025192251344", + "UPCA": "025192251344", + "barcode": { + "EAN13": "https://eandata.com/image/0025192251344.png", + "UPCA": "https://eandata.com/image/025192251344.png" + }, + "locked": "0", + "modified": "2019-04-25 22:23:52", + "image": "https://eandata.com/image/products/002/519/225/0025192251344.jpg" + } +} + +POST https://foodbook.psinfoodservice.com/prod/dc + +"SelectedFilterOptions.collapseFilterId": "filterkeywordPanelBody", +"SelectedFilterOptions.FreeText": "", +"SelectedFilterOptions.ProductGroupId": "", +"SelectedFilterOptions.BrandId": "", +"SelectedFilterOptions.GrossierId": "", +"SelectedFilterOptions.Ean": "8710654160037", +"SelectedFilterOptions.ProducerNumber": "", +"SelectedFilterOptions.GrossierNumber": "", +"PS_brands_input": "", +"PS_brands": "" + +GET https://foodbook.psinfoodservice.com/prod/dc/nl/12345/ps/FilterBrands?text=&filter%5Blogic%5D=and + +curl 'https://foodbook.psinfoodservice.com/prod/dc#' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Referer: https://foodbook.psinfoodservice.com/prod/dc' -H 'Content-Type: application/x-www-form-urlencoded' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Cookie: ASP.NET_SessionId=tqcozq0zsc21wafsx5i4vgpk' -H 'Upgrade-Insecure-Requests: 1' --data 'SelectedFilterOptions.collapseFilterId=filterkeywordPanelBody&SelectedFilterOptions.FreeText=8710654160037&SelectedFilterOptions.ProductGroupId=&SelectedFilterOptions.BrandId=&SelectedFilterOptions.GrossierId=&SelectedFilterOptions.Ean=&SelectedFilterOptions.ProducerNumber=&SelectedFilterOptions.GrossierNumber=&PS_brands_input=&PS_brands=' + +blah.html + +curl 'https://foodbook.psinfoodservice.com/prod/dc/nl/12345/ps/FilterBrands?text=&filter%5Blogic%5D=and' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0' -H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Referer: https://foodbook.psinfoodservice.com/prod/dc' -H 'X-Requested-With: XMLHttpRequest' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Cookie: ASP.NET_SessionId=tqcozq0zsc21wafsx5i4vgpk' + +[{"Id":81,"Name":"de Molen\u0027s Banket","LogoUrl":null,"IsPubliclyVisible":true}] + +curl 'https://foodbook.psinfoodservice.com/prod/dc/nl/12345/ps/ProductDetailPartial/6682?_=1556280486040' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0' -H 'Accept: text/html, */*; q=0.01' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Referer: https://foodbook.psinfoodservice.com/prod/dc' -H 'X-Requested-With: XMLHttpRequest' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Cookie: ASP.NET_SessionId=tqcozq0zsc21wafsx5i4vgpk' \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..b5f25d4 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "barcodebot", + "description": "An IRC bot that looks up UPC barcodes", + "version": "1.0.0", + "main": "index.js", + "repository": "http://git.cryto.net/joepie91/barcodebot.git", + "author": "Sven Slootweg ", + "license": "WTFPL OR CC0-1.0", + "dependencies": { + "bhttp": "^1.2.4", + "bluebird": "^3.5.4", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.3", + "dotty": "^0.1.0", + "irc-framework": "^4.2.0", + "unhandled-error": "^1.0.0" + } +} diff --git a/parse-foodbook.js b/parse-foodbook.js new file mode 100644 index 0000000..6c38f95 --- /dev/null +++ b/parse-foodbook.js @@ -0,0 +1,55 @@ +"use strict"; + +const cheerio = require("cheerio"); + +let onclickRegex = /^loadDetailPage\('([^']+)'\);/; +let urlRegex = /url\('([^']+)'\)/; + +function getOnclickUrl(onclickText) { + let match = onclickRegex.exec(onclickText); + + if (match == null) { + throw new Error("Expected URL not found in onclick handler"); + } else { + return match[1]; + } +} + +function getUrl(cssText) { + let match = urlRegex.exec(cssText); + + if (match == null) { + return null; /* Sometimes there is no picture */ + } else { + return match[1]; + } +} + +module.exports = { + parseSearch: function (html) { + let $ = cheerio.load(html); + + let products = $(".productresult .media").get().map((row) => { + let $row = $(row); + let onclickValue = $row.attr("onclick"); + + return getOnclickUrl(onclickValue); + }); + + return products; + }, + parseProduct: function (html) { + let $ = cheerio.load(html); + + let brandTextElement = $(".section-data h1 a#brandlink"); + let brand = brandTextElement.text().trim(); + brandTextElement.remove(); + + let product = $(".section-data h1").text().trim(); + + return { + name: `${brand}, ${product}`, + image: getUrl($(".assetImageDefault").attr("style")) + } + } +}; diff --git a/shorten-url.js b/shorten-url.js new file mode 100644 index 0000000..ea0fdb1 --- /dev/null +++ b/shorten-url.js @@ -0,0 +1,12 @@ +"use strict"; + +const Promise = require("bluebird"); +const bhttp = require("bhttp"); + +module.exports = function shortenUrl(targetUrl) { + return Promise.try(() => { + return bhttp.get(`https://is.gd/create.php?format=simple&url=${encodeURIComponent(targetUrl)}`); + }).then((response) => { + return response.body.toString(); + }); +}; \ No newline at end of file diff --git a/test-foodbook.js b/test-foodbook.js new file mode 100644 index 0000000..6635ebd --- /dev/null +++ b/test-foodbook.js @@ -0,0 +1,1362 @@ +"use strict"; + +const parse = require("./parse-foodbook"); + +let searchHtml = ` + + + + + + + Digital Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+ + +
+
+ +
+
+ + + + + +
+
+
+ +
+ + + + + + + + Zoeken op: 8710654160037 + + + + + + + + +
+ +
+
+ + + +
+
+ + + + +
+ +
+ + +
+ + + + + + + + + + + + + + + + +`; + +let productHtml = ` + + +
+
+ + +
+ + +
+ +
+ + + + +
+
+ + + +
+ Stel een vraag over dit product +
+ +
+ + + +
+ + + + + +
+
+
+
+
+

+ Artikelnummer: + EAN: 8710654160037 +

+

+ Super appelkoeken +

+
+
+
+ +
+
+
+
+
+ + +
+
+
+
+
+
+

+ Super appelkoeken +
+ de Molen's Banket +
+

+
+
+ + brand +
+ +
+

Appelkoeken.

+ + EAN: + + 8710654160037 (CE) + , + 8710654000586 (HE) + + TM: NL + +
+
+
+
+ + +
+
+
+ + +
+ + +
+
+ +
+ +
+ + + + +
+
+
+ +
+
+
+
+ + + + + + + + + + + + + + + +
+

Ingrediënten

+
+
+
+ TARWEBLOEM, glucose-fructosestroop, suiker, plantaardige olie (palm, raap, zonnebloem), 10% appel, invertsuikerstroop, conserveermiddel (E202, E282), zout, rijsmiddelen (E450, E500), zuurteregelaar (E332, E333), verdikkingsmiddel (pectine), aroma, MELKEIWIT, voedingszuur (citroenzuur), lactose (MELK), emulgatoren (lecithine (SOJA, zonnebloem), E471), kleurstof (caroteen) +
+
+ +
+
+ + + +
+

Voedingswaarde

+
+
+

+ Product +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  + Per 100 (g) + +
+ Energie + + = 1620 kJ + + +
+ Energie + + = 380 kcal + + +
+ Vetten + + = 13 g + + +
+ Waarvan verzadigde vetzuren + + = 6.5 g + + +
+ Koolhydraten + + = 62 g + + +
+ Waarvan suikers + + = 36 g + + +
+ Vezels + + = 1.5 g + + +
+ Eiwitten + + = 4 g + + +
+ Zout + + = 0.43 g + + +
+
+
+
+
+

Wettelijke allergenen

+
+ + + + + + + + + + + + + + + + +
Receptuur bevatglutenbevattende granen, tarwe, soja, melk
Receptuur bevat niet, maar kan sporen bevatten vannoten, amandelen
Receptuur bevat nietrogge, gerst, haver, spelt, schaaldieren, ei, vis, pinda's, hazelnoten, walnoten, cashewnoten, pecannoten, paranoten, pistachenoten, macadamianoten, selderij, mosterd, sesam, sulfiet (E220 - E228), lupine, weekdieren
+ +
+
+
+ + + + + + + + + + + + +
+

+ +Deze specificatie komt uit de database van PS in foodservice.
De producent van dit product is verantwoordelijk voor de juistheid van de gegevens. Disclaimer.

+
+ + + v1.4.1 prodpp6682dl1ly1ln1 + +
+ + + + + +`; + +console.log(parse.parseSearch(searchHtml)); +console.log(parse.parseProduct(productHtml)); diff --git a/test-json.js b/test-json.js new file mode 100644 index 0000000..9dcf7ed --- /dev/null +++ b/test-json.js @@ -0,0 +1,34 @@ +"use strict"; + +const dotty = require("dotty"); + +let json = `{"status":{"version":"3.1","code":"200","message":"free 0\/15","find":"0025192251344","search":"normal","run":"0.2021","runtime":"0.2113"},"product":{"attributes":{"product":"Jaws","url":"http:\/\/www.jaws25.com\/","model":"29466797","price_new":"6.9400","price_new_extra":"USD","price_new_extra_long":"US Dollars","price_new_extra_id":"537","price_used":"4.9900","price_used_extra":"USD","price_used_extra_long":"US Dollars","price_used_extra_id":"537","asin_com":"B00MA5KL9I","category":"55","category_text":"Movie","category_text_long":"Electronics \/ Photography: A\/V Media: Movie","width":"5.3000","width_extra":"in","width_extra_long":"inches","width_extra_id":"501","height":"0.3500","height_extra":"in","height_extra_long":"inches","height_extra_id":"501","length":"6.7500","length_extra":"in","length_extra_long":"inches","length_extra_id":"501","weight":"15.0000","weight_extra":"lb\/100","weight_extra_long":"hundredths pounds","weight_extra_id":"765","long_desc":"*** only visible with paid data feed ***","features":"Shrink-wrapped","binding":"Blu-ray","published":"2016-01-26","similar":"0012569828476, 0025192092824, 0025192279218, 0025192347627, 0025192354595, 0025192354601, 0025192354618, 0032429134967, 0043396374003, 0043396496941, 0097361467641, 0191329029053, 0191329047200, 0709112696308, 5051368208930, 5051892007344, 5053083090555, 9780783282336","release_year":"1975.0000","movie_cast":"*** only visible with paid data feed ***","movie_aspect":"2.35:1","format":"Multiple Formats, Blu-ray, Ultraviolet, Color, Widescreen","movie_genre":"Action\/Adventure","movie_rating":"743","movie_rating_text":"PG","movie_rating_text_long":"PG - Parental Guidance Suggested","runtime":"124.0000","runtime_extra":"minutes","runtime_extra_long":"minutes","runtime_extra_id":"753","movie_imdb":"*** only visible with paid data feed ***","movie_runtime":"124.0000","movie_runtime_extra":"minutes","movie_runtime_extra_long":"minutes","movie_runtime_extra_id":"753","music_runtime":"124.0000","music_runtime_extra":"minutes","music_runtime_extra_long":"minutes","music_runtime_extra_id":"753","movie_director":"Steven Spielberg","movie_imdb_trailer":"*** only visible with paid data feed ***"},"EAN13":"0025192251344","UPCA":"025192251344","barcode":{"EAN13":"https:\/\/eandata.com\/image\/0025192251344.png","UPCA":"https:\/\/eandata.com\/image\/025192251344.png"},"locked":"0","modified":"2019-04-25 22:23:52","image":"https:\/\/eandata.com\/image\/products\/002\/519\/225\/0025192251344.jpg"}} +`; + + +let source = JSON.parse(json); + +function parse() { + let productName = dotty.get(source, "product.attributes.product"); + + if (productName != null) { + + let data = { + name: productName, + image: dotty.get(source, "product.image") + }; + + let priceCurrency = dotty.get(source, "product.attributes.price_new_extra"); + let priceAmount = dotty.get(source, "product.attributes.price_new"); + + if (priceAmount != null) { + data.price = `$ ${priceAmount}`; + } + + return data; + } else { + return null; + } +} + +console.log(parse()); diff --git a/test.js b/test.js new file mode 100644 index 0000000..70cfc63 --- /dev/null +++ b/test.js @@ -0,0 +1,11 @@ +"use strict"; + +const Promise = require("bluebird"); + +const getBarcode = require("./get-barcode"); + +Promise.try(() => { + return getBarcode("4002846034450"); +}).then((result) => { + console.log(result); +}) diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..ae39e75 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,490 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@*": + version "11.13.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.7.tgz#85dbb71c510442d00c0631f99dae957ce44fd104" + integrity sha512-suFHr6hcA9mp8vFrZTgrmqW2ZU3mbWsryQtQlY/QvwTISCw7nw/j+bCQPPohqmskhmqa5wLNuMHTTsc+xf1MQg== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +bhttp@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/bhttp/-/bhttp-1.2.4.tgz#fed0c24f765b35afc4940b08ab3214813e38f38f" + integrity sha1-/tDCT3ZbNa/ElAsIqzIUgT44848= + dependencies: + bluebird "^2.8.2" + concat-stream "^1.4.7" + debug "^2.1.1" + dev-null "^0.1.1" + errors "^0.2.0" + extend "^2.0.0" + form-data2 "^1.0.0" + form-fix-array "^1.0.0" + lodash "^2.4.1" + stream-length "^1.0.2" + string "^3.0.0" + through2-sink "^1.0.0" + through2-spy "^1.2.0" + tough-cookie "^2.3.1" + +bluebird@^2.6.2, bluebird@^2.8.1, bluebird@^2.8.2: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" + integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE= + +bluebird@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.4.tgz#d6cc661595de30d5b3af5fcedd3c0b3ef6ec5714" + integrity sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw== + +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +cheerio@^1.0.0-rc.3: + version "1.0.0-rc.3" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6" + integrity sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA== + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.1" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash "^4.15.0" + parse5 "^3.0.1" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +combined-stream2@^1.0.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/combined-stream2/-/combined-stream2-1.1.2.tgz#f6e14b7a015666f8c7b0a1fac506240164ac3570" + integrity sha1-9uFLegFWZvjHsKH6xQYkAWSsNXA= + dependencies: + bluebird "^2.8.1" + debug "^2.1.1" + stream-length "^1.0.1" + +concat-stream@^1.4.7: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +css-select@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +debug@^2.1.1, debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +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= + +dom-serializer@0, dom-serializer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + dependencies: + domelementtype "^1.3.0" + entities "^1.1.1" + +domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dotty@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dotty/-/dotty-0.1.0.tgz#da371ccd931a37282f8f7f77adada7d54539708a" + integrity sha512-VJzcXJZEckXowvj6yGJC2JH66DLEEm1d1QOB0hik1EvlbUpULvcYt411JeFuy8rNC96FG8V2N7pMkyjvK8LYwQ== + +entities@^1.1.1, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +errors@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/errors/-/errors-0.2.0.tgz#0f51e889daa3e11b19e7186d11f104aa66eb2403" + integrity sha1-D1Hoidqj4RsZ5xhtEfEEqmbrJAM= + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eventemitter3@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba" + integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo= + +extend@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-2.0.2.tgz#1b74985400171b85554894459c978de6ef453ab7" + integrity sha512-AgFD4VU+lVLP6vjnlNfF7OeInLTyeyckCNPEsuxz1vi786UuK/nk6ynPuhn/h+Ju9++TQyr5EpLRI14fc1QtTQ== + +form-data2@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/form-data2/-/form-data2-1.0.3.tgz#cba5e23601a6944d95ab7d7111ff9397a5cb2a4d" + integrity sha1-y6XiNgGmlE2Vq31xEf+Tl6XLKk0= + dependencies: + bluebird "^2.8.2" + combined-stream2 "^1.0.2" + debug "^2.1.1" + lodash "^2.4.1" + mime "^1.2.11" + uuid "^2.0.1" + +form-fix-array@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/form-fix-array/-/form-fix-array-1.0.0.tgz#a1347a47e53117ab7bcdbf3e2f3ec91c66769bc8" + integrity sha1-oTR6R+UxF6t7zb8+Lz7JHGZ2m8g= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +htmlparser2@^3.9.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +iconv-lite@^0.4.11: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ipaddr.js@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-0.1.3.tgz#27a9ca37f148d2102b0ef191ccbf2c51a8f025c6" + integrity sha1-J6nKN/FI0hArDvGRzL8sUajwJcY= + +irc-framework@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/irc-framework/-/irc-framework-4.2.0.tgz#74d3ea9a93a90f74ef3e3da23cc2ca2834f3e96f" + integrity sha512-BjCae59zAvMNKL55nn+VaolOBdouAPSDP9ZYlEI9QCqejbaGMQxQiFrDdbEy1KnfdwnAL9+R2xhycuqKALyBgA== + dependencies: + eventemitter3 "^2.0.2" + iconv-lite "^0.4.11" + lodash "^4.17.4" + middleware-handler "^0.2.0" + runes "^0.4.3" + socksjs "^0.5.0" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +lodash@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" + integrity sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4= + +lodash@^4.15.0, lodash@^4.17.4: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +middleware-handler@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/middleware-handler/-/middleware-handler-0.2.0.tgz#bf02af7e6b577c0230609b2ae58df0e446f3fd02" + integrity sha1-vwKvfmtXfAIwYJsq5Y3w5Ebz/QI= + +mime@^1.2.11: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +parse5@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" + integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== + dependencies: + "@types/node" "*" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +psl@^1.1.28: + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== + +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== + +readable-stream@^2.2.2: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.3.0.tgz#cb8011aad002eb717bf040291feba8569c986fb9" + integrity sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@~1.0.17: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +runes@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/runes/-/runes-0.4.3.tgz#32f7738844bc767b65cc68171528e3373c7bb355" + integrity sha512-K6p9y4ZyL9wPzA+PMDloNQPfoDGTiFYDvdlXznyGKgD10BJpcAosvATKrExRKOrNLgD8E7Um7WGW0lxsnOuNLg== + +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== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +socksjs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/socksjs/-/socksjs-0.5.0.tgz#77b005e32d1bfc96e560fedd5d7eedcf120f87e3" + integrity sha1-d7AF4y0b/JblYP7dXX7tzxIPh+M= + dependencies: + ipaddr.js "0.1.3" + +stream-length@^1.0.1, stream-length@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-length/-/stream-length-1.0.2.tgz#8277f3cbee49a4daabcfdb4e2f4a9b5e9f2c9f00" + integrity sha1-gnfzy+5JpNqrz9tOL0qbXp8snwA= + dependencies: + bluebird "^2.6.2" + +string@^3.0.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/string/-/string-3.3.3.tgz#5ea211cd92d228e184294990a6cc97b366a77cb0" + integrity sha1-XqIRzZLSKOGEKUmQpsyXs2anfLA= + +string_decoder@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +through2-sink@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/through2-sink/-/through2-sink-1.0.0.tgz#5f106bba1d7330dad3cba5c0ab1863923256c399" + integrity sha1-XxBruh1zMNrTy6XAqxhjkjJWw5k= + dependencies: + through2 "~0.5.1" + xtend "~3.0.0" + +through2-spy@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/through2-spy/-/through2-spy-1.2.0.tgz#9c891ca9ca40e1e1e4cf31e1ac57f94cc9d248cb" + integrity sha1-nIkcqcpA4eHkzzHhrFf5TMnSSMs= + dependencies: + through2 "~0.5.1" + xtend "~3.0.0" + +through2@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.5.1.tgz#dfdd012eb9c700e2323fd334f38ac622ab372da7" + integrity sha1-390BLrnHAOIyP9M084rGIqs3Lac= + dependencies: + readable-stream "~1.0.17" + xtend "~3.0.0" + +tough-cookie@^2.3.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +unhandled-error@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unhandled-error/-/unhandled-error-1.0.0.tgz#c53f7cc161d03f41a7db65b05bb645bb83c83fab" + integrity sha1-xT98wWHQP0Gn22WwW7ZFu4PIP6s= + dependencies: + unhandled-rejection "^1.0.0" + +unhandled-rejection@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unhandled-rejection/-/unhandled-rejection-1.0.0.tgz#16c97cb0d620135176559696bcc9222e0da40445" + integrity sha1-Fsl8sNYgE1F2VZaWvMkiLg2kBEU= + dependencies: + debug "^2.2.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +uuid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + integrity sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho= + +xtend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" + integrity sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=