From 56669168bf1e912aafedf32955a1d4dd263699d8 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Mon, 26 Nov 2018 19:23:28 -0500 Subject: [PATCH 01/24] initial support for EMF file format thanks to Inkscape --- README.md | 27 ++- bin/args.js | 6 + bin/graph.js | 3 +- bin/serve.js | 3 +- package-lock.json | 247 ++++++++++++------------ package.json | 1 + src/component/plotly-graph/constants.js | 3 +- src/component/plotly-graph/convert.js | 25 +++ src/component/plotly-graph/render.js | 9 +- src/util/inkscape.js | 151 +++++++++++++++ test/unit/inkscape_test.js | 80 ++++++++ 11 files changed, 419 insertions(+), 136 deletions(-) create mode 100644 src/util/inkscape.js create mode 100644 test/unit/inkscape_test.js diff --git a/README.md b/README.md index 29811839..4a47fa6e 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ $ npm install -g electron@1.8.4 orca which makes the `orca` executable available in your path. -### Method 3: Standalone binaries +### Method 3: Standalone binaries Alternatively, you can download the standalone Orca binaries corresponding to your operating system from the @@ -52,7 +52,7 @@ your operating system from the - A password dialog will appear asking for permission to add orca to your system `PATH`. - Enter you password and click _OK_. - This should open an _Installation Succeeded_ window. -- Open a new terminal and verify that the orca executable is available on your `PATH`. +- Open a new terminal and verify that the orca executable is available on your `PATH`. ``` $ which orca @@ -100,7 +100,7 @@ to the AppImage. $ ln -s /path/to/orca-X.Y.Z-x86_64.AppImage /somewhere/on/PATH/orca ``` -- Open a new terminal and verify that the orca executable is available on your `PATH`. +- Open a new terminal and verify that the orca executable is available on your `PATH`. ``` $ which orca @@ -112,7 +112,7 @@ Plotly's image-exporting utilities Usage: orca [--version] [--help] [] ... ``` - + ##### Linux Troubleshooting: Cannot open shared object The Electron runtime depends a several common system libraries. These libraries are pre-installed in most desktop Linux distributions @@ -157,7 +157,7 @@ Name this shell script `orca` and place it somewhere or your system `PATH`. - How to add directory to system path in Linux: https://www.computerhope.com/issues/ch001647.htm - AppImage: https://appimage.org/ - Xvfb: https://en.wikipedia.org/wiki/Xvfb - + ## Quick start From the command line: @@ -286,14 +286,14 @@ Plotly's image server is dockerized and deployed here. See the `deployment/` ## System dependencies -**If you don't care about exporting EPS you can skip this section.** +**If you don't care about exporting EPS or EMF you can skip this section.** -The environment you're installing this into may require Poppler for EPS exports. +The environment you're installing this into may require Poppler for EPS exports and Inkscape for EMF exports. #### Poppler installation via Aptitude (used by some \*nix/BSD, e.g. Ubuntu) ``` -$ apt-get poppler-utils (requires `sudo` or root privileges) +$ apt-get install poppler-utils (requires `sudo` or root privileges) ``` #### Poppler installation via Homebrew (third-party package manager for Mac OS X) @@ -302,6 +302,17 @@ $ apt-get poppler-utils (requires `sudo` or root privileges) $ brew install poppler ``` +#### Inkscape installation via Aptitude (used by some \*nix/BSD, e.g. Ubuntu) + +``` +$ apt-get install inkscape (requires `sudo` or root privileges) +``` + +#### Inkscape installation via Homebrew (third-party package manager for Mac OS X) + +``` +$ brew install inkscape +``` ## Contributing See diff --git a/bin/args.js b/bin/args.js index 136a1a6a..6fc87bb2 100644 --- a/bin/args.js +++ b/bin/args.js @@ -28,6 +28,12 @@ exports.PLOTLYJS_OPTS_META = [{ alias: ['MathJax'], dflt: '', description: `Sets path to MathJax files. Required to export LaTeX characters.` +}, { + name: 'inkscape', + type: 'string', + alias: ['Inkscape'], + dflt: '', + description: `Sets path to Inkscape executable. Required to export WMF and EMF formats.` }, { name: 'safe-mode', type: 'boolean', diff --git a/bin/graph.js b/bin/graph.js index fcb2728c..70c14fe6 100644 --- a/bin/graph.js +++ b/bin/graph.js @@ -145,7 +145,8 @@ function main (args) { scale: opts.scale, width: opts.width, height: opts.height, - safeMode: opts.safeMode + safeMode: opts.safeMode, + inkscape: opts.inkscape } } }) diff --git a/bin/serve.js b/bin/serve.js index aad32b11..f2112002 100755 --- a/bin/serve.js +++ b/bin/serve.js @@ -73,7 +73,8 @@ function main (args) { mapboxAccessToken: opts['mapbox-access-token'], mathjax: opts.mathjax, topojson: opts.topojson, - safeMode: opts.safeMode + safeMode: opts.safeMode, + inkscape: opts.inkscape } function launch () { diff --git a/package-lock.json b/package-lock.json index bdff6b87..a1c01d36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -143,7 +143,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -164,7 +164,7 @@ "ansi-escapes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "integrity": "sha1-9zIHu4EgfXX9bIPxJa8m7qN4yjA=", "dev": true }, "ansi-regex": { @@ -176,7 +176,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -369,7 +369,7 @@ "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=", "requires": { "safer-buffer": "~2.1.0" } @@ -382,7 +382,7 @@ "async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "integrity": "sha1-skWiPKcZMAROxT+kaqAKPofGphA=", "dev": true, "requires": { "lodash": "^4.17.10" @@ -391,7 +391,7 @@ "async-exit-hook": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", - "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "integrity": "sha1-i9iwJLDsmxwBzMua+dspvXF9+vM=", "dev": true }, "asynckit": { @@ -413,7 +413,7 @@ "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "integrity": "sha1-8OAD2cqef1nHpQiUXXsu+aBKVC8=" }, "babel-code-frame": { "version": "6.26.0", @@ -486,13 +486,13 @@ "bind-obj-methods": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.0.tgz", - "integrity": "sha512-3/qRXczDi2Cdbz6jE+W3IflJOutRVica8frpBn14de1mBOkzDo+6tY33kNhvkw54Kn3PzRRD2VnGbGPcTAk4sw==", + "integrity": "sha1-AXgUDb57e7Z9x0iSrOWbwCR/BvA=", "dev": true }, "bl": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "integrity": "sha1-oWCRFxcQPAdBDO9j71Gzl8Alr5w=", "dev": true, "requires": { "readable-stream": "^2.3.5", @@ -566,7 +566,7 @@ "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "integrity": "sha1-VcbDmouljZxhrSLNh3Uy3rZlogs=", "dev": true, "requires": { "ansi-align": "^2.0.0", @@ -625,7 +625,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -674,7 +674,7 @@ "buffer-alloc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "integrity": "sha1-iQ3ZDZI6hz4I4Q5f1RpX5bfM4Ow=", "dev": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", @@ -684,7 +684,7 @@ "buffer-alloc-unsafe": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "integrity": "sha1-vX3CauKXLQ7aJTvgYdupkjScGfA=", "dev": true }, "buffer-crc32": { @@ -702,7 +702,7 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=", "dev": true }, "builder-util": { @@ -852,7 +852,7 @@ "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -892,7 +892,7 @@ "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=", "dev": true }, "clean-yaml-object": { @@ -948,7 +948,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -995,7 +995,7 @@ "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "integrity": "sha1-k4NDeaHMmgxh+C9S8NBDIiUb1aI=", "dev": true }, "combined-stream": { @@ -1113,7 +1113,7 @@ "configstore": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "integrity": "sha1-xvJd767vJt8S3TNBSwAf6BpUP48=", "dev": true, "requires": { "dot-prop": "^4.1.0", @@ -1138,7 +1138,7 @@ "core-js": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "integrity": "sha1-+XJgj/DOrWi4QaFqky0LGDeRgU4=", "dev": true }, "core-util-is": { @@ -1149,7 +1149,7 @@ "coveralls": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.2.tgz", - "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==", + "integrity": "sha1-9aC82Qyk5k4Ii3EPqN2mQK6kiE8=", "dev": true, "requires": { "growl": "~> 1.10.0", @@ -1163,7 +1163,7 @@ "crc": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "integrity": "sha1-rWAmnCyFb4wpnixMwN5FVpFAVsY=", "dev": true, "requires": { "buffer": "^5.1.0" @@ -1313,7 +1313,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -1340,7 +1340,7 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "integrity": "sha1-xPp8lUBKF6nD6Mp+FTcxK3NjMKw=", "dev": true }, "deep-is": { @@ -1352,7 +1352,7 @@ "deepmerge": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.0.1.tgz", - "integrity": "sha512-VIPwiMJqJ13ZQfaCsIFnp5Me9tnjURiaIFxfz7EH0Ci0dTSQpZtSLrqOicXqEd/z2r+z+Klk9GzmnRsgpgbOsQ==", + "integrity": "sha1-JcHCTxEPuRT4AAG5JSZN138/QxI=", "dev": true }, "define-properties": { @@ -1368,7 +1368,7 @@ "object-keys": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "integrity": "sha1-CcU4VTd1dTEMymL1W7M0q/97PtI=", "dev": true } } @@ -1376,7 +1376,7 @@ "deglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.1.tgz", - "integrity": "sha512-2kjwuGGonL7gWE1XU4Fv79+vVzpoQCl0V+boMwWtOQJV2AGDabCwez++nB1Nli/8BabAfZQ/UuHPlp6AymKdWw==", + "integrity": "sha1-0mjhaHJ3mYYujqwHBC4WWVfB874=", "dev": true, "requires": { "find-root": "^1.0.0", @@ -1427,7 +1427,7 @@ "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", "dev": true }, "dmg-builder": { @@ -1460,7 +1460,7 @@ "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", "dev": true, "requires": { "esutils": "^2.0.2" @@ -1469,7 +1469,7 @@ "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", "dev": true, "requires": { "is-obj": "^1.0.0" @@ -1709,7 +1709,7 @@ "electron-chromedriver": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-1.8.0.tgz", - "integrity": "sha512-m1f3nle5MaGp94bcDTtMZZMMOgPO54+TXoPBlTbBSUjfINR5SJ46yQXLfuE79/qsFfJKslZB1UzWURDDFIRmpQ==", + "integrity": "sha1-kBcUEzz29gk9Nl4fRKUtmWJNgkE=", "dev": true, "requires": { "electron-download": "^4.1.0", @@ -1763,7 +1763,7 @@ "electron-debug": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/electron-debug/-/electron-debug-1.5.0.tgz", - "integrity": "sha512-23CLHQXW+gMgdlJbeW1EinPX7DpwuLtfdzSuFL0OnsqEhKGJVJufAZTyq2hc3sr+R53rr3P+mJiYoR5VzAHKJQ==", + "integrity": "sha1-2IwCFG77f8WuGyHqxW++SYfq5Qw=", "dev": true, "requires": { "electron-is-dev": "^0.3.0", @@ -1802,7 +1802,7 @@ "electron-localshortcut": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-3.1.0.tgz", - "integrity": "sha512-MgL/j5jdjW7iA0R6cI7S045B0GlKXWM1FjjujVPjlrmyXRa6yH0bGSaIAfxXAF9tpJm3pLEiQzerYHkRh9JG/A==", + "integrity": "sha1-EMH/1Te405FwqvbhVRNB93gN0s4=", "dev": true, "requires": { "debug": "^2.6.8", @@ -1893,7 +1893,7 @@ "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "integrity": "sha1-7SljTRm6ukY7bOa4CjchPqtx7EM=", "dev": true, "requires": { "once": "^1.4.0" @@ -1926,7 +1926,7 @@ "es-abstract": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "integrity": "sha1-nbvdJ8aFbwABQhyhh4LXhr+KYWU=", "dev": true, "requires": { "es-to-primitive": "^1.1.1", @@ -1962,7 +1962,7 @@ "eslint": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz", - "integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==", + "integrity": "sha1-D4EmetEBLn0gUeGGqQBMwiZ7jUU=", "dev": true, "requires": { "ajv": "^5.3.0", @@ -2060,19 +2060,19 @@ "eslint-config-standard": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz", - "integrity": "sha512-oDdENzpViEe5fwuRCWla7AXQd++/oyIp8zP+iP9jiUPG6NBj3SHgdgtl/kTn00AjeN+1HNvavTKmYbMo+xMOlw==", + "integrity": "sha1-h+4NPJ2VOC3HYZWMuyPanuox4Lo=", "dev": true }, "eslint-config-standard-jsx": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-5.0.0.tgz", - "integrity": "sha512-rLToPAEqLMPBfWnYTu6xRhm2OWziS2n40QFqJ8jAM8NSVzeVKTa3nclhsU4DpPJQRY60F34Oo1wi/71PN/eITg==", + "integrity": "sha1-Sr+sVU84Zo4AeMZkVp57I4Tl0qo=", "dev": true }, "eslint-import-resolver-node": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "integrity": "sha1-WPFfuDm40FdsqYBBNHaqskcttmo=", "dev": true, "requires": { "debug": "^2.6.9", @@ -2185,7 +2185,7 @@ "eslint-plugin-node": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz", - "integrity": "sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw==", + "integrity": "sha1-vxlkIpgGQ3kxXXpLKnWTc3b6BeQ=", "dev": true, "requires": { "ignore": "^3.3.6", @@ -2197,13 +2197,13 @@ "eslint-plugin-promise": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.7.0.tgz", - "integrity": "sha512-2WO+ZFh7vxUKRfR0cOIMrWgYKdR6S1AlOezw6pC52B6oYpd5WFghN+QHxvrRdZMtbo8h3dfUZ2o1rWb0UPbKtg==", + "integrity": "sha1-9L3lwsd83WlVeo9pok0a08/J5n4=", "dev": true }, "eslint-plugin-react": { "version": "7.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz", - "integrity": "sha512-KC7Snr4YsWZD5flu6A5c0AcIZidzW3Exbqp7OT67OaD2AppJtlBr/GuPrW/vaQM/yfZotEvKAdrxrO+v8vwYJA==", + "integrity": "sha1-9gbHGdvYoaKz0lwWKZgTh4zKAWA=", "dev": true, "requires": { "doctrine": "^2.0.2", @@ -2221,7 +2221,7 @@ "eslint-scope": { "version": "3.7.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "integrity": "sha1-u1ByANPRf2AkdjYWC0gmKEsQhTU=", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -2231,13 +2231,13 @@ "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "integrity": "sha1-PzGA+y4pEBdxastMnW1bXDSmqB0=", "dev": true }, "espree": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "integrity": "sha1-sPRHGHyKi+2US4FaZgvd9d610ac=", "dev": true, "requires": { "acorn": "^5.5.0", @@ -2253,7 +2253,7 @@ "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=", "dev": true, "requires": { "estraverse": "^4.0.0" @@ -2262,7 +2262,7 @@ "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", "dev": true, "requires": { "estraverse": "^4.1.0" @@ -2317,12 +2317,12 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=" }, "external-editor": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "integrity": "sha1-BFURz9jRM/OEZnPRBHwVTiFK09U=", "dev": true, "requires": { "chardet": "^0.4.0", @@ -2399,12 +2399,12 @@ "file-type": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", - "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==" + "integrity": "sha1-po1a0H9IZBTfssiGb3MWGUZxShg=" }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "integrity": "sha1-q8/Iunb3CMQql7PWhbfpRQv7nOQ=", "dev": true }, "find-up": { @@ -2475,7 +2475,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "integrity": "sha1-a+Dem+mYzhavivwkSXue6bfM2a0=", "dev": true }, "fs-exists-cached": { @@ -2537,7 +2537,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", "dev": true }, "function-loop": { @@ -2555,7 +2555,7 @@ "gaze": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "integrity": "sha1-xEFzPhO5J6yMD/C0w7Az8ogSkko=", "dev": true, "requires": { "globule": "^1.0.0" @@ -2631,7 +2631,7 @@ "globule": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", - "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", + "integrity": "sha1-Xf+xsZHyLSB5epNptJ6rTpg5aW0=", "dev": true, "requires": { "glob": "~7.1.1", @@ -2667,7 +2667,7 @@ "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=", "dev": true }, "har-schema": { @@ -2700,7 +2700,7 @@ "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", "dev": true, "requires": { "function-bind": "^1.1.1" @@ -2767,19 +2767,19 @@ "ieee754": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "integrity": "sha1-UL8k5bnIu5ivSWTJQc2wkY2ntgs=", "dev": true }, "ignore": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=", "dev": true }, "image-size": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", - "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==", + "integrity": "sha1-5+XGW7U0vXzc7dbLUWYnKoX3X7I=", "dev": true }, "import-lazy": { @@ -2820,13 +2820,13 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=", "dev": true }, "inquirer": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "integrity": "sha1-ndLyrXZdyrH/BEO0kUQqILoifck=", "dev": true, "requires": { "ansi-escapes": "^3.0.0", @@ -2860,7 +2860,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -2902,7 +2902,7 @@ "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "integrity": "sha1-HhrfIZ4e62hNaR+dagX/DTCiTXU=", "dev": true }, "is-ci": { @@ -3013,7 +3013,7 @@ "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=", "dev": true }, "is-retry-allowed": { @@ -3042,7 +3042,7 @@ "is-url": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" + "integrity": "sha1-BKTfRtKMTP89c9Af8Gq+sxihqlI=" }, "is-utf8": { "version": "0.2.1", @@ -3053,7 +3053,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", "dev": true }, "isarray": { @@ -3104,7 +3104,7 @@ "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "integrity": "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk=", "dev": true }, "json-schema": { @@ -3172,13 +3172,13 @@ "keyboardevent-from-electron-accelerator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-1.1.0.tgz", - "integrity": "sha512-VDC4vKWGrR3VgIKCE4CsXnvObGgP8C2idnTKEMUkuEuvDGE1GEBX9FtNdJzrD00iQlhI3xFxRaeItsUmlERVng==", + "integrity": "sha1-MkYU9uM0kMN//Fvlh2s+hf4iPIQ=", "dev": true }, "keyboardevents-areequal": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz", - "integrity": "sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==", + "integrity": "sha1-iBkexzjOn3WRwl6QVt6Si0AncZQ=", "dev": true }, "klaw": { @@ -3202,7 +3202,7 @@ "lazy-val": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.3.tgz", - "integrity": "sha512-pjCf3BYk+uv3ZcPzEVM0BFvO9Uw58TmlrU0oG5tTrr9Kcid3+kdKxapH8CjdYmVa2nO5wOoZn2rdvZx2PKj/xg==", + "integrity": "sha1-u5eyAO8AgB2UwxfincbtOeMcXtw=", "dev": true }, "lazystream": { @@ -3323,7 +3323,7 @@ "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "integrity": "sha1-Y7lQIfBwL+36LJuwok53l9cYcdg=", "dev": true }, "lolex": { @@ -3335,7 +3335,7 @@ "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "integrity": "sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=", "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -3354,7 +3354,7 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "integrity": "sha1-b54wtHCE2XGnyCD/FabFFnt0wm8=", "dev": true }, "lru-cache": { @@ -3445,7 +3445,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "requires": { "brace-expansion": "^1.1.7" } @@ -3530,7 +3530,7 @@ "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", "dev": true, "requires": { "hosted-git-info": "^2.1.4", @@ -6217,7 +6217,7 @@ "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=" }, "object-assign": { "version": "4.1.1", @@ -6326,7 +6326,7 @@ "own-or-env": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", - "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", + "integrity": "sha1-VM5gHTv3gjbFxlYzqhyOwD+AB+Q=", "dev": true, "requires": { "own-or": "^1.0.0" @@ -6420,7 +6420,7 @@ "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=", "dev": true }, "path-to-regexp": { @@ -6553,7 +6553,7 @@ "plist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", - "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", + "integrity": "sha1-qbkx0XwwTokS7wujvdYYK68uH4w=", "dev": true, "requires": { "base64-js": "^1.2.3", @@ -6578,9 +6578,14 @@ "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=", "dev": true }, + "pngjs": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.3.tgz", + "integrity": "sha512-1n3Z4p3IOxArEs1VRXnZ/RXdfEniAUS9jb68g58FIXMNkPJeZd+Qh4Uq7/e0LVxAQGos1eIUrqrt4FpjdnEd+Q==" + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -6636,7 +6641,7 @@ "prop-types": { "version": "15.6.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", - "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", + "integrity": "sha1-BdXKd7RFPphdYPx/+MhZCUpJcQI=", "dev": true, "requires": { "loose-envify": "^1.3.1", @@ -6652,7 +6657,7 @@ "psl": { "version": "1.1.29", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" + "integrity": "sha1-YPWA02AXC7cip5fMcEQR5tqFDGc=" }, "punycode": { "version": "1.4.1", @@ -6668,7 +6673,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=" }, "querystring": { "version": "0.2.0", @@ -6688,7 +6693,7 @@ "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "integrity": "sha1-zZJL9SAKB1uDwYjNa54hG3/A0+0=", "dev": true, "requires": { "deep-extend": "^0.6.0", @@ -6784,13 +6789,13 @@ "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "integrity": "sha1-vgWtf5v30i4Fb5cmzuUBf78Z4uk=", "dev": true }, "registry-auth-token": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "integrity": "sha1-hR/UkDjuy1hpERFa+EUmDuyYPyA=", "dev": true, "requires": { "rc": "^1.1.6", @@ -6824,7 +6829,7 @@ "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "integrity": "sha1-nC/KT301tZLv5Xx/ClXoEFIST+8=", "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -6880,7 +6885,7 @@ "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "integrity": "sha1-gvHsGaQjrB+9CAsLqwa6NuhKeiY=", "dev": true, "requires": { "path-parse": "^1.0.5" @@ -6911,13 +6916,13 @@ "rgb2hex": { "version": "0.1.9", "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.9.tgz", - "integrity": "sha512-32iuQzhOjyT+cv9aAFRBJ19JgHwzQwbjUhH3Fj2sWW2EEGAW8fpFrDFP5ndoKDxJaLO06x1hE3kyuIFrUQtybQ==", + "integrity": "sha1-XT4OFLAXe1aObw1bQ+NPv9tnA0Y=", "dev": true }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", "dev": true, "requires": { "glob": "^7.0.5" @@ -6935,17 +6940,17 @@ "run-parallel": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" + "integrity": "sha1-yd06fPn0ssS2JE4XOm7YZuYd1nk=" }, "run-parallel-limit": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.0.5.tgz", - "integrity": "sha512-NsY+oDngvrvMxKB3G8ijBzIema6aYbQMD2bHOamvN52BysbIGTnEY2xsNyfrcr9GhY995/t/0nQN3R3oZvaDlg==" + "integrity": "sha1-wppP0XtN81jLUqiml4EaY8mE8bc=" }, "run-series": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.8.tgz", - "integrity": "sha512-+GztYEPRpIsQoCSraWHDBs9WVy4eVME16zhOtDB4H9J4xN0XRhknnmLOl+4gRgZtu8dpp9N/utSPjKH/xmDzXg==" + "integrity": "sha1-LEVY9JIh4BzWNx/04KHiA+Rg/DY=" }, "rx-lite": { "version": "4.0.8", @@ -6975,7 +6980,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" }, "samsam": { "version": "1.3.0", @@ -6995,7 +7000,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", "dev": true }, "semver": { @@ -7079,7 +7084,7 @@ "slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "integrity": "sha1-BE8aSdiEL/MHqta1Be0Xi9lQE00=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" @@ -7096,7 +7101,7 @@ "snazzy": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/snazzy/-/snazzy-7.1.1.tgz", - "integrity": "sha512-gJ46s+jcwOeRhO9uEkTyzcREFZ0c5LZOgcVakLxTPIvhRIywKvbvArvMg5e8bBbpWe4InC/8eyEQOGXgJVNOfw==", + "integrity": "sha1-JmObGacsTVQsdiBJ+CnRShrRaHk=", "dev": true, "requires": { "chalk": "^2.3.0", @@ -7208,7 +7213,7 @@ "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "integrity": "sha1-cuLMNAlVQ+Q7LGKyxMENSpBU8lk=", "dev": true, "requires": { "atob": "^2.1.1", @@ -7265,7 +7270,7 @@ "spectron": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/spectron/-/spectron-3.8.0.tgz", - "integrity": "sha512-fQ7gFp6UuEaONjXFLifLeIUI022pOsm3b+NFAm696r2umUkSZ9IbnEgHwrvBX+pJ3QUDyCEs5bPHUieYU7FvaQ==", + "integrity": "sha1-Eiw1Yv1+krfN9vlAlKpJWxUN+lE=", "dev": true, "requires": { "dev-null": "^0.1.1", @@ -7284,7 +7289,7 @@ "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", "dev": true, "requires": { "through": "2" @@ -7321,7 +7326,7 @@ "standard": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/standard/-/standard-11.0.1.tgz", - "integrity": "sha512-nu0jAcHiSc8H+gJCXeiziMVZNDYi8MuqrYJKxTgjP4xKXZMKm311boqQIzDrYI/ktosltxt2CbDjYQs9ANC8IA==", + "integrity": "sha1-Sb5Ax28dVklksiu/cwmSmtAzXik=", "dev": true, "requires": { "eslint": "~4.18.0", @@ -7338,7 +7343,7 @@ "standard-engine": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-8.0.1.tgz", - "integrity": "sha512-LA531C3+nljom/XRvdW/hGPXwmilRkaRkENhO3FAGF1Vtq/WtCXzgmnc5S6vUHHsgv534MRy02C1ikMwZXC+tw==", + "integrity": "sha1-C3e+jXq5Y2dXF9vqwe8dZnX7YvA=", "dev": true, "requires": { "deglob": "^2.1.0", @@ -7350,7 +7355,7 @@ "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "integrity": "sha1-ngm/cSs2CrkiXoEgSPcf3pyJZXs=", "dev": true } } @@ -7378,7 +7383,7 @@ "string-to-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string-to-stream/-/string-to-stream-1.1.1.tgz", - "integrity": "sha512-QySF2+3Rwq0SdO3s7BAp4x+c3qsClpPQ6abAmb0DGViiSBAkT5kL6JT2iyzEVP+T1SmzHrQD1TwlP9QAHCc+Sw==", + "integrity": "sha1-q6ePc+cGYbEw7j4cAZK+T+9stZk=", "requires": { "inherits": "^2.0.1", "readable-stream": "^2.1.0" @@ -7511,7 +7516,7 @@ "table": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "integrity": "sha1-ozRHN1OR52atNNNIbm4q7chNLjY=", "dev": true, "requires": { "ajv": "^5.2.3", @@ -7549,7 +7554,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -7640,7 +7645,7 @@ "tap-mocha-reporter": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-3.0.7.tgz", - "integrity": "sha512-GHVXJ38C3oPRpM3YUc43JlGdpVZYiKeT1fmAd3HH2+J+ZWwsNAUFvRRdoGsXLw9+gU9o+zXpBqhS/oXyRQYwlA==", + "integrity": "sha1-I15XiTtQCGHqXQkkll2t+y8F6qc=", "dev": true, "requires": { "color-support": "^1.1.0", @@ -7703,7 +7708,7 @@ "tap-parser": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-5.4.0.tgz", - "integrity": "sha512-BIsIaGqv7uTQgTW1KLTMNPSEQf4zDDPgYOBRdgOfuB+JFOLRBfEu6cLa/KvMvmqggu1FKXDfitjLwsq4827RvA==", + "integrity": "sha1-aQfolyXXt/pq5B7ixGTD20MYiuw=", "dev": true, "requires": { "events-to-array": "^1.0.1", @@ -7716,7 +7721,7 @@ "tap-parser": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz", - "integrity": "sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA==", + "integrity": "sha1-VNs1MC/aLCzMIZVK074issukJyE=", "dev": true, "requires": { "events-to-array": "^1.0.1", @@ -7852,13 +7857,13 @@ "tmatch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-4.0.0.tgz", - "integrity": "sha512-Ynn2Gsp+oCvYScQXeV+cCs7citRDilq0qDXA6tuvFwDgiYyyaq7D5vKUlAPezzZR5NDobc/QMeN6e5guOYmvxg==", + "integrity": "sha1-uheAB/ML9qcPN8ZD/KUEX7L4xEg=", "dev": true }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -7867,13 +7872,13 @@ "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "integrity": "sha1-STvUj2LXxD/N7TE6A9ytsuEhOoA=", "dev": true }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "integrity": "sha1-U/Nto/R3g7CSWvoG/587FlKA94E=", "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -7932,7 +7937,7 @@ "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw=", "dev": true }, "typedarray": { @@ -7981,7 +7986,7 @@ "update-notifier": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "integrity": "sha1-0HRFk+E/Fh5AassdlAi3LK0Ir/Y=", "dev": true, "requires": { "boxen": "^1.2.1", @@ -8097,7 +8102,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "integrity": "sha1-G0r0lV6zB3xQHCOHL8ZROBFYcTE=" }, "validate-npm-package-license": { "version": "3.0.1", @@ -8122,7 +8127,7 @@ "wdio-dot-reporter": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.10.tgz", - "integrity": "sha512-A0TCk2JdZEn3M1DSG9YYbNRcGdx/YRw19lTiRpgwzH4qqWkO/oRDZRmi3Snn4L2j54KKTfPalBhlOtc8fojVgg==", + "integrity": "sha1-+s+3ycWYQUmVH1nLw80HUhAc8OA=", "dev": true }, "webdriverio": { @@ -8216,7 +8221,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -8284,7 +8289,7 @@ "write-file-atomic": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "integrity": "sha1-H/YVdcLipOjlENb6TiQ8zhg5mas=", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -8377,7 +8382,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", diff --git a/package.json b/package.json index 4ef0d019..f4521ffe 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "is-plain-obj": "^1.1.0", "is-url": "^1.2.4", "minimist": "^1.2.0", + "pngjs": "^3.3.3", "read-chunk": "^2.1.0", "request": "^2.88.0", "run-parallel": "^1.1.9", diff --git a/src/component/plotly-graph/constants.js b/src/component/plotly-graph/constants.js index 168ac77f..6b15d229 100644 --- a/src/component/plotly-graph/constants.js +++ b/src/component/plotly-graph/constants.js @@ -5,7 +5,8 @@ module.exports = { webp: 'image/webp', svg: 'image/svg+xml', pdf: 'application/pdf', - eps: 'application/postscript' + eps: 'application/postscript', + emf: 'image/emf' }, statusMsg: { diff --git a/src/component/plotly-graph/convert.js b/src/component/plotly-graph/convert.js index 2dfc05c4..0e6505eb 100644 --- a/src/component/plotly-graph/convert.js +++ b/src/component/plotly-graph/convert.js @@ -1,4 +1,5 @@ const Pdftops = require('../../util/pdftops') +const Inkscape = require('../../util/inkscape') const cst = require('./constants') /** plotly-graph convert @@ -55,6 +56,21 @@ function convert (info, opts, reply) { }) } + const svg2emf = (svg, cb) => { + const inkscape = opts.inkscape instanceof Inkscape + ? opts.inkscape + : new Inkscape(opts.inkscape) + + inkscape.svg2emf(svg, {id: info.id}, (err, emf) => { + if (err) { + errorCode = 530 + result.error = err + return done() + } + cb(emf) + }) + } + switch (format) { case 'png': case 'jpeg': @@ -84,6 +100,15 @@ function convert (info, opts, reply) { return done() }) break + case 'emf': + svg2emf(imgData, (emf) => { + body = encoded + ? `data:${cst.contentFormat.emf};base64,${emf.toString('base64')}` + : Buffer.from(emf, 'base64') + bodyLength = body.length + return done() + }) + break } } diff --git a/src/component/plotly-graph/render.js b/src/component/plotly-graph/render.js index 0979d178..b795e3e8 100644 --- a/src/component/plotly-graph/render.js +++ b/src/component/plotly-graph/render.js @@ -41,6 +41,7 @@ function render (info, opts, sendToMain) { } const PRINT_TO_PDF = (format === 'pdf' || format === 'eps') + const PRINT_TO_EMF = (format === 'emf') // stash `paper_bgcolor` here in order to set the pdf window bg color let bgColor @@ -50,15 +51,15 @@ function render (info, opts, sendToMain) { } const imgOpts = { - format: PRINT_TO_PDF ? 'svg' : format, + format: (PRINT_TO_PDF || PRINT_TO_EMF) ? 'svg' : format, width: info.width, height: info.height, // only works as of plotly.js v1.31.0 scale: info.scale, // return image data w/o the leading 'data:image' spec - imageDataOnly: !PRINT_TO_PDF && !encoded, - // blend jpeg background color as jpeg does not support transparency - setBackground: format === 'jpeg' ? 'opaque' + imageDataOnly: PRINT_TO_EMF || (!PRINT_TO_PDF && !encoded), + // blend (emf|jpeg) background color as (emf|jpeg) does not support transparency + setBackground: (format === 'jpeg' || format === 'emf') ? 'opaque' : PRINT_TO_PDF ? pdfBackground : '' } diff --git a/src/util/inkscape.js b/src/util/inkscape.js new file mode 100644 index 00000000..6aad6921 --- /dev/null +++ b/src/util/inkscape.js @@ -0,0 +1,151 @@ +const fs = require('fs') +const path = require('path') +const childProcess = require('child_process') +const parallel = require('run-parallel') +const series = require('run-series') +const uuid = require('uuid/v4') +const os = require('os') +const PNG = require('pngjs').PNG + +const PATH_TO_BUILD = path.join(os.tmpdir(), 'orca-build') +try { + fs.mkdirSync(PATH_TO_BUILD) +} catch (e) {} + +const fullyTransparentColorbarRegexp = //g +const fullyTransparentRectRegexp = //g +const transparentFillRectRegexp = //g +const transparentStrokeRectRegexp = //g +const imgRegexp = /]*>/ +const colorbarRegexp = /]*\/>/ +const xlinkHrefDataImageRegexp = /xlink:href="data:image\/png;base64,([^"]*)"/ + +/** Node wrapper for Inkscape + * + * $ apt-get install inkscape + * ... or on OS X: + * $ brew install inkscape + * + * See: + * - https://linux.die.net/man/1/inkscape + * - https://en.wikipedia.org/wiki/Inkscape + */ +class Inkscape { + constructor (pathToInkscape) { + this.cmdBase = pathToInkscape || 'inkscape' + } + + /** Convert SVG to EMF + * + * @param {buffer} svg : svg data buffer + * @param {object} opts + * - id {string} + * @param {function} cb + * - err {null || error} + * - result {buffer} + */ + svg2emf (svg, opts, cb) { + const id = opts.id || uuid() + const inPath = path.join(PATH_TO_BUILD, id + '-svg') + const outPath = path.join(PATH_TO_BUILD, id + '-emf') + const cmd = `${this.cmdBase} --file ${inPath} --export-emf ${outPath}` + + const destroyTmpFiles = (cb) => parallel([ + (cb) => fs.unlink(inPath, cb), + (cb) => fs.unlink(outPath, cb) + ], cb) + + svg = this.cleanSvg(svg) + + series([ + (cb) => fs.writeFile(inPath, svg, 'utf-8', cb), + (cb) => childProcess.exec(cmd, cb), + (cb) => fs.readFile(outPath, cb) + ], (err, result) => { + destroyTmpFiles(() => { + cb(err, result[2]) + }) + }) + } + + cleanSvg (svg) { + var bgColor = [255, 255, 255] + + // Fix black legends by removing rect.legendtoggle + svg = svg.replace(/]+>/g, '') + + // Remove colorbar background if it's transparent + + svg = svg.replace(fullyTransparentColorbarRegexp, '') + // Remove annotation's background if it's compleletely transparent + svg = svg.replace(fullyTransparentRectRegexp, '') + + // Set fill color to background color if its opacity is 0 + svg = svg.replace(transparentFillRectRegexp, function (match, p) { + return match.replace(/fill: [^;]*;/, `fill: rgb(${bgColor[0]},${bgColor[1]},${bgColor[2]});`) + }) + // Set stroke color to background color if its opacity is 0 + svg = svg.replace(transparentStrokeRectRegexp, function (match, p) { + return match.replace(/stroke: [^;]*;/, `stroke: rgb(${bgColor[0]},${bgColor[1]},${bgColor[2]});`) + }) + + // Fix black background in rasterized images + svg = svg.replace(imgRegexp, function (match, base64png) { + var pngBuffer = Buffer.from(base64png, 'base64') + var image = PNG.sync.read(pngBuffer) + + for (var y = 0; y < image.height; y++) { + for (var x = 0; x < image.width; x++) { + var idx = (image.width * y + x) << 2 + + var alpha = image.data[idx + 3] + if (alpha < 255) { + // Manually do alpha composition (https://en.wikipedia.org/wiki/Alpha_compositing) + image.data[idx] = image.data[idx] * alpha / 255 + bgColor[0] * (1 - alpha / 255) + image.data[idx + 1] = image.data[idx + 1] * alpha / 255 + bgColor[1] * (1 - alpha / 255) + image.data[idx + 2] = image.data[idx + 2] * alpha / 255 + bgColor[2] * (1 - alpha / 255) + + image.data[idx + 3] = 255 + } + } + } + var pngOpaqueBuffer = PNG.sync.write(image) + return match.replace(xlinkHrefDataImageRegexp, `xlink:href="data:image/png;base64,${pngOpaqueBuffer.toString('base64')}"`) + }) + + // Inkscape doesn't convert well gradientUnits="objectBoundingBox" into EMF + svg.replace(colorbarRegexp, function (match) { + // var width = match.match(/width="(\d+)"/)[1] + var height = match.match(/height="(\d+)"/)[1] + var gradientId = match.match(/url\('#([^']*)'\)/) + + if (gradientId) { + gradientId = gradientId[1] + var gradientIdRegexp = new RegExp(`]*id="${gradientId}"[^>]*>`) + svg = svg.replace(gradientIdRegexp, function (m) { + return `` + }) + } + + return false + }) + + return svg + } + + /** Is Inkscape installed? + * @return {boolean} + */ + static isInkscapeInstalled () { + try { + childProcess.execSync(`${this.cmdBase} --version`, { + stdio: 'ignore' + }) + } catch (e) { + return false + } + return true + } +} + +module.exports = Inkscape diff --git a/test/unit/inkscape_test.js b/test/unit/inkscape_test.js new file mode 100644 index 00000000..1ccd27bd --- /dev/null +++ b/test/unit/inkscape_test.js @@ -0,0 +1,80 @@ +const tap = require('tap') +const sinon = require('sinon') +const path = require('path') +const fs = require('fs') +const childProcess = require('child_process') +const Inkscape = require('../../src/util/inkscape') + +const { paths, mocks } = require('../common') + +tap.test('inkscape.svg2emf', t => { + t.test('should convert svg to emf', t => { + const inkscape = new Inkscape() + const outPath = path.join(paths.build, 'inkscape-test.emf') + + inkscape.svg2emf(mocks.svg, {}, (err, result) => { + if (err) t.fail(err) + t.type(result, Buffer) + + fs.writeFile(outPath, result, (err) => { + if (err) t.fail(err) + + const size = fs.statSync(outPath).size + t.ok(size > 9e4, 'min emf file size') + t.end() + }) + }) + }) + + t.test('should remove tmp files after conversion', t => { + const inkscape = new Inkscape() + const tmpOutPath = path.join(paths.build, 'tmp-emf') + const tmpSvgPath = path.join(paths.build, 'tmp-svg') + + inkscape.svg2emf(mocks.svg, {id: 'tmp'}, (err, result) => { + if (err) t.fail(err) + + t.type(result, Buffer) + t.notOk(fs.existsSync(tmpOutPath), 'clears tmp emf file') + t.notOk(fs.existsSync(tmpSvgPath), 'clears tmp svg file') + t.end() + }) + }) + + t.test('should error out when inkscape command fails', t => { + const inkscape = new Inkscape('not gonna work') + + const tmpOutPath = path.join(paths.build, 'tmp-emf') + const tmpSvgPath = path.join(paths.build, 'tmp-svg') + + inkscape.svg2emf(mocks.svg, {id: 'tmp'}, (err) => { + t.throws(() => { throw err }, /Command failed/) + t.notOk(fs.existsSync(tmpOutPath), 'clears tmp emf file') + t.notOk(fs.existsSync(tmpSvgPath), 'clears tmp svg file') + t.end() + }) + }) + + t.end() +}) + +tap.test('isInkscapeInstalled', t => { + t.afterEach((done) => { + childProcess.execSync.restore() + done() + }) + + t.test('should return true when binary execute correctly', t => { + sinon.stub(childProcess, 'execSync').returns(true) + t.ok(Inkscape.isInkscapeInstalled()) + t.end() + }) + + t.test('should return false when binary does not execute correctly', t => { + sinon.stub(childProcess, 'execSync').throws() + t.notOk(Inkscape.isInkscapeInstalled()) + t.end() + }) + + t.end() +}) From e82327413a14e4fca3572b4ed8de5c37ab854b36 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Mon, 26 Nov 2018 22:07:23 -0500 Subject: [PATCH 02/24] remove PATCH version from docker image name to get updates --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ae4f2df2..c2c9f463 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -83,16 +83,16 @@ jobs: test-node-v6: <<: *base docker: - - image: circleci/node:6.14.1-browsers + - image: circleci/node:6.14-browsers test-node-v8: <<: *base docker: - - image: circleci/node:8.11.1-browsers + - image: circleci/node:8.11-browsers docker-build-and-push: docker: - - image: circleci/node:8.11.1-browsers + - image: circleci/node:8.11-browsers steps: - setup_remote_docker: reusable: true @@ -138,7 +138,7 @@ jobs: electron-pack-and-release: docker: - - image: circleci/node:8.11.1-browsers + - image: circleci/node:8.11-browsers steps: - restore_cache: key: v1-source-{{ .Branch }}-{{ .Revision }} From 035ed22c2212a8def53ccf283c2f8615d69e31bd Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Tue, 27 Nov 2018 13:52:50 -0500 Subject: [PATCH 03/24] fix regular expression to match svg attributes with dash --- src/util/inkscape.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/util/inkscape.js b/src/util/inkscape.js index 6aad6921..bb4ae844 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -12,12 +12,12 @@ try { fs.mkdirSync(PATH_TO_BUILD) } catch (e) {} -const fullyTransparentColorbarRegexp = //g -const fullyTransparentRectRegexp = //g -const transparentFillRectRegexp = //g -const transparentStrokeRectRegexp = //g +const fullyTransparentColorbarRegexp = //g +const fullyTransparentRectRegexp = //g +const transparentFillRectRegexp = //g +const transparentStrokeRectRegexp = //g const imgRegexp = /]*>/ -const colorbarRegexp = /]*\/>/ +const colorbarFillRegexp = /]*\/>/ const xlinkHrefDataImageRegexp = /xlink:href="data:image\/png;base64,([^"]*)"/ /** Node wrapper for Inkscape @@ -75,7 +75,6 @@ class Inkscape { svg = svg.replace(/]+>/g, '') // Remove colorbar background if it's transparent - svg = svg.replace(fullyTransparentColorbarRegexp, '') // Remove annotation's background if it's compleletely transparent svg = svg.replace(fullyTransparentRectRegexp, '') @@ -114,7 +113,7 @@ class Inkscape { }) // Inkscape doesn't convert well gradientUnits="objectBoundingBox" into EMF - svg.replace(colorbarRegexp, function (match) { + svg.replace(colorbarFillRegexp, function (match) { // var width = match.match(/width="(\d+)"/)[1] var height = match.match(/height="(\d+)"/)[1] var gradientId = match.match(/url\('#([^']*)'\)/) @@ -129,7 +128,7 @@ class Inkscape { return false }) - + return svg } From 40437c444ba3864ef5745e09205cf27428b5d92d Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Tue, 27 Nov 2018 15:28:57 -0500 Subject: [PATCH 04/24] circleci: debian-jessie -> debien-strecth to get inkscape 0.9x --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c2c9f463..cac10904 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -61,7 +61,7 @@ jobs: name: Install deps command: | npm install - sudo apt-get install poppler-utils libgconf-2-4 + sudo apt-get install inkscape poppler-utils libgconf-2-4 - run: name: List deps command: | @@ -83,16 +83,16 @@ jobs: test-node-v6: <<: *base docker: - - image: circleci/node:6.14-browsers + - image: circleci/node:6.14-stretch-browsers test-node-v8: <<: *base docker: - - image: circleci/node:8.11-browsers + - image: circleci/node:8.11-stretch-browsers docker-build-and-push: docker: - - image: circleci/node:8.11-browsers + - image: circleci/node:8.11-stretch-browsers steps: - setup_remote_docker: reusable: true From 25f0bb6e7906ee56c38146cf6ff49bb5dde18e9c Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Tue, 27 Nov 2018 15:42:32 -0500 Subject: [PATCH 05/24] properly check test-mock.emf size and fix lint --- src/util/inkscape.js | 2 +- test/unit/inkscape_test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/inkscape.js b/src/util/inkscape.js index bb4ae844..4f3c2890 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -128,7 +128,7 @@ class Inkscape { return false }) - + return svg } diff --git a/test/unit/inkscape_test.js b/test/unit/inkscape_test.js index 1ccd27bd..28011e2a 100644 --- a/test/unit/inkscape_test.js +++ b/test/unit/inkscape_test.js @@ -20,7 +20,7 @@ tap.test('inkscape.svg2emf', t => { if (err) t.fail(err) const size = fs.statSync(outPath).size - t.ok(size > 9e4, 'min emf file size') + t.ok(size > 2e4, 'min emf file size') t.end() }) }) From e2f2be7c6fbf96fddaa6919ea4b365155e9e84b3 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Tue, 27 Nov 2018 15:50:34 -0500 Subject: [PATCH 06/24] missing deps, need to update package lists --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cac10904..bb637133 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -61,7 +61,7 @@ jobs: name: Install deps command: | npm install - sudo apt-get install inkscape poppler-utils libgconf-2-4 + sudo apt-get update && sudo apt-get install inkscape poppler-utils libgconf-2-4 - run: name: List deps command: | @@ -138,7 +138,7 @@ jobs: electron-pack-and-release: docker: - - image: circleci/node:8.11-browsers + - image: circleci/node:8.11-stretch-browsers steps: - restore_cache: key: v1-source-{{ .Branch }}-{{ .Revision }} From 5ed1198eb1686239b8f9171f5ac16844526cd03f Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Thu, 29 Nov 2018 13:17:20 -0500 Subject: [PATCH 07/24] minor code style fix --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bb637133..0465c9bf 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -61,7 +61,8 @@ jobs: name: Install deps command: | npm install - sudo apt-get update && sudo apt-get install inkscape poppler-utils libgconf-2-4 + sudo apt-get update + sudo apt-get install inkscape poppler-utils libgconf-2-4 - run: name: List deps command: | From fc8c755566b6ebbc476258524cef57e18bbb59b8 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Thu, 29 Nov 2018 20:07:44 -0500 Subject: [PATCH 08/24] check Inkscape's version, provide meaning error message when --verbose --- src/component/plotly-graph/convert.js | 8 +++++++ src/util/inkscape.js | 27 ++++++++++++++++++++- test/unit/inkscape_test.js | 34 ++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/component/plotly-graph/convert.js b/src/component/plotly-graph/convert.js index 0e6505eb..685c9c96 100644 --- a/src/component/plotly-graph/convert.js +++ b/src/component/plotly-graph/convert.js @@ -61,6 +61,14 @@ function convert (info, opts, reply) { ? opts.inkscape : new Inkscape(opts.inkscape) + try { + inkscape.CheckInstallation() + } catch (e) { + errorCode = 530 + result.error = e + return done() + } + inkscape.svg2emf(svg, {id: info.id}, (err, emf) => { if (err) { errorCode = 530 diff --git a/src/util/inkscape.js b/src/util/inkscape.js index 4f3c2890..b2b2d7fa 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -6,6 +6,7 @@ const series = require('run-series') const uuid = require('uuid/v4') const os = require('os') const PNG = require('pngjs').PNG +const semver = require('semver') const PATH_TO_BUILD = path.join(os.tmpdir(), 'orca-build') try { @@ -135,7 +136,7 @@ class Inkscape { /** Is Inkscape installed? * @return {boolean} */ - static isInkscapeInstalled () { + isInstalled () { try { childProcess.execSync(`${this.cmdBase} --version`, { stdio: 'ignore' @@ -145,6 +146,30 @@ class Inkscape { } return true } + + /** Returns inkscape version + * @return {string} + */ + Version () { + try { + var out = childProcess.execSync(`${this.cmdBase} --version`) + out = out.toString() + var found = out.match(/Inkscape (\d+\.\d+\.\d+)/) + return found[1] + } catch (e) { + return '' + } + } + + CheckInstallation () { + if (!this.isInstalled()) { + throw new Error('Inkscape is not installed') + } + + if (!this.Version() || !semver.gte(this.Version(), '0.92.3')) { + throw new Error('Inkscape version should be greater than or equal to 0.92.3') + } + } } module.exports = Inkscape diff --git a/test/unit/inkscape_test.js b/test/unit/inkscape_test.js index 28011e2a..65e7278e 100644 --- a/test/unit/inkscape_test.js +++ b/test/unit/inkscape_test.js @@ -58,7 +58,7 @@ tap.test('inkscape.svg2emf', t => { t.end() }) -tap.test('isInkscapeInstalled', t => { +tap.test('Inkscape installation', t => { t.afterEach((done) => { childProcess.execSync.restore() done() @@ -66,13 +66,41 @@ tap.test('isInkscapeInstalled', t => { t.test('should return true when binary execute correctly', t => { sinon.stub(childProcess, 'execSync').returns(true) - t.ok(Inkscape.isInkscapeInstalled()) + var inkscape = new Inkscape() + t.ok(inkscape.isInstalled()) t.end() }) t.test('should return false when binary does not execute correctly', t => { sinon.stub(childProcess, 'execSync').throws() - t.notOk(Inkscape.isInkscapeInstalled()) + var inkscape = new Inkscape() + t.notOk(inkscape.isInstalled()) + t.end() + }) + + t.test('should return Inkscape version', t => { + var inkscape = new Inkscape() + sinon.stub(childProcess, 'execSync').returns('Inkscape 0.92.3 (2405546, 2018-03-11)') + t.ok(inkscape.Version() === '0.92.3') + + childProcess.execSync.restore() + sinon.stub(childProcess, 'execSync').returns('Inkscape 0.48.5 r10040 (Oct 7 2014)') + t.ok(inkscape.Version() === '0.48.5') + + t.end() + }) + + t.test('CheckInstallation() should throw error with older version of Inkscape', t => { + var inkscape = new Inkscape() + sinon.stub(childProcess, 'execSync').returns('Inkscape 0.48.5 r10040 (Oct 7 2014)') + t.throws(function () { inkscape.CheckInstallation() }) + t.end() + }) + + t.test('CheckInstallation() should NOT throw error with newer version of Inkscape', t => { + var inkscape = new Inkscape() + sinon.stub(childProcess, 'execSync').returns('Inkscape 0.92.3 (2405546, 2018-03-11)') + t.doesNotThrow(function () { inkscape.CheckInstallation() }) t.end() }) From 1ecb2f41fe9396a69738c99ead3171f38cb0b8c8 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Mon, 3 Dec 2018 14:45:00 -0500 Subject: [PATCH 09/24] parse SVG using jsdom instead of regexes --- package-lock.json | 314 ++++++++++++++++++++++++++++++++++++++++--- package.json | 1 + src/util/inkscape.js | 102 +++++++++----- 3 files changed, 367 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index a1c01d36..4452f7f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,6 +66,11 @@ "integrity": "sha512-BvcUxNZe9JgiiUVivtiQt3NrPVu9OAQzkxR1Ko9ESftCYU7V6Np5kpDzQwxd+34lsop7SNRdL292Flv52OvCaw==", "dev": true }, + "abab": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", + "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==" + }, "accessibility-developer-tools": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/accessibility-developer-tools/-/accessibility-developer-tools-2.12.0.tgz", @@ -78,6 +83,22 @@ "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", "dev": true }, + "acorn-globals": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz", + "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==", + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz", + "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==" + } + } + }, "acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", @@ -95,6 +116,11 @@ } } }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==" + }, "ajv": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz", @@ -329,6 +355,11 @@ "sprintf-js": "~1.0.2" } }, + "array-equal": { + "version": "1.0.0", + "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -394,6 +425,11 @@ "integrity": "sha1-i9iwJLDsmxwBzMua+dspvXF9+vM=", "dev": true }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -661,6 +697,11 @@ "concat-map": "0.0.1" } }, + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" + }, "buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.0.tgz", @@ -1293,6 +1334,19 @@ "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=", "dev": true }, + "cssom": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.4.tgz", + "integrity": "sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==" + }, + "cssstyle": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.1.1.tgz", + "integrity": "sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==", + "requires": { + "cssom": "0.3.x" + } + }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -1310,6 +1364,16 @@ "assert-plus": "^1.0.0" } }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1346,8 +1410,7 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "deepmerge": { "version": "2.0.1", @@ -1466,6 +1529,14 @@ "esutils": "^2.0.2" } }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "requires": { + "webidl-conversions": "^4.0.2" + } + }, "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -1959,6 +2030,31 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "escodegen": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", + "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + } + } + }, "eslint": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz", @@ -2271,14 +2367,12 @@ "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, "events-to-array": { "version": "1.1.2", @@ -2365,8 +2459,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fd-slicer": { "version": "1.0.1", @@ -2739,6 +2832,14 @@ "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", "dev": true }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -3101,6 +3202,46 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "optional": true }, + "jsdom": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-13.0.0.tgz", + "integrity": "sha512-Kmq4ASMNkgpY+YufE322EnIKoiz0UWY2DRkKlU7d5YrIW4xiVRhWFrZV1fr6w/ZNxQ50wGAH5gGRzydgnmkkvw==", + "requires": { + "abab": "^2.0.0", + "acorn": "^6.0.2", + "acorn-globals": "^4.3.0", + "array-equal": "^1.0.0", + "cssom": "^0.3.4", + "cssstyle": "^1.1.1", + "data-urls": "^1.0.1", + "domexception": "^1.0.1", + "escodegen": "^1.11.0", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.0.9", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "saxes": "^3.1.3", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.4.3", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.0.0", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0", + "ws": "^6.1.0", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz", + "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==" + } + } + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -3271,7 +3412,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -3311,8 +3451,7 @@ "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" }, "lodash.get": { "version": "4.4.2", @@ -3320,6 +3459,11 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", @@ -3584,6 +3728,11 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, + "nwsapi": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.9.tgz", + "integrity": "sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ==" + }, "nyc": { "version": "11.9.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.9.0.tgz", @@ -6276,7 +6425,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -6289,8 +6437,7 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" } } }, @@ -6391,6 +6538,11 @@ "error-ex": "^1.2.0" } }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -6581,6 +6733,11 @@ "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=", "dev": true }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + }, "pngjs": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.3.tgz", @@ -6589,8 +6746,7 @@ "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "prepend-http": { "version": "1.0.4", @@ -6860,6 +7016,24 @@ } } }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "requires": { + "lodash": "^4.13.1" + } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "^1.1.0", + "tough-cookie": ">=2.3.3" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7003,6 +7177,14 @@ "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", "dev": true }, + "saxes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.4.tgz", + "integrity": "sha512-GVZmLJnkS4Vl8Pe9o4nc5ALZ615VOVxCmea8Cs0l+8GZw3RQ5XGOSUomIUfuZuk4Todo44v4y+HY1EATkDDiZg==", + "requires": { + "xmlchars": "^1.3.1" + } + }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", @@ -7375,6 +7557,11 @@ "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=", "dev": true }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, "string-template": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", @@ -7513,6 +7700,11 @@ } } }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" + }, "table": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", @@ -7884,6 +8076,21 @@ "punycode": "^1.4.1" } }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + } + } + }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", @@ -7929,7 +8136,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, "requires": { "prelude-ls": "~1.1.2" } @@ -8124,6 +8330,24 @@ "extsprintf": "^1.2.0" } }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "w3c-xmlserializer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.0.0.tgz", + "integrity": "sha512-0et1+9uXYiIRAecx1D5Z1nk60+vimniGdIKl4XjeqkWi6acoHNlXMv1VR5jV+jF4ooeO08oWbYxeAJOcon1oMA==", + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, "wdio-dot-reporter": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.10.tgz", @@ -8176,12 +8400,50 @@ } } }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, "wgxpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wgxpath/-/wgxpath-1.0.0.tgz", "integrity": "sha1-7vikudVYzEla06mit1FZfs2a9pA=", "dev": true }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "which": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", @@ -8297,18 +8559,36 @@ "signal-exit": "^3.0.2" } }, + "ws": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.2.tgz", + "integrity": "sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==", + "requires": { + "async-limiter": "~1.0.0" + } + }, "xdg-basedir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, "xmlbuilder": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz", "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=", "dev": true }, + "xmlchars": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-1.3.1.tgz", + "integrity": "sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==" + }, "xmldom": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", diff --git a/package.json b/package.json index f4521ffe..03eca719 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "glob": "^7.1.2", "is-plain-obj": "^1.1.0", "is-url": "^1.2.4", + "jsdom": "^13.0.0", "minimist": "^1.2.0", "pngjs": "^3.3.3", "read-chunk": "^2.1.0", diff --git a/src/util/inkscape.js b/src/util/inkscape.js index b2b2d7fa..155eda23 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -7,20 +7,23 @@ const uuid = require('uuid/v4') const os = require('os') const PNG = require('pngjs').PNG const semver = require('semver') +const jsdom = require('jsdom') +const { JSDOM } = jsdom const PATH_TO_BUILD = path.join(os.tmpdir(), 'orca-build') try { fs.mkdirSync(PATH_TO_BUILD) } catch (e) {} -const fullyTransparentColorbarRegexp = //g -const fullyTransparentRectRegexp = //g -const transparentFillRectRegexp = //g -const transparentStrokeRectRegexp = //g const imgRegexp = /]*>/ -const colorbarFillRegexp = /]*\/>/ const xlinkHrefDataImageRegexp = /xlink:href="data:image\/png;base64,([^"]*)"/ +const fillUrl = /(^|; )fill: url\('#([^']*)'\);/ +const fillRgbaColor = /(^|; )fill: rgba\(([^)]*)\);/ +const fillOpacityZero = /(^|\s*)fill-opacity: 0;/ +const strokeOpacityZero = /(^|; )stroke-opacity: 0;/ +const opacityZero = /(^|; )opacity: 0;/ + /** Node wrapper for Inkscape * * $ apt-get install inkscape @@ -71,25 +74,75 @@ class Inkscape { cleanSvg (svg) { var bgColor = [255, 255, 255] + const fragment = JSDOM.fragment(svg) + + // Remove path and rectangles that are compleletely transparent + fragment.querySelectorAll('rect, path').forEach(function (node) { + var style = node.getAttribute('style') + if (style && ( + (style.match(fillOpacityZero) && style.match(strokeOpacityZero)) || + style.match(opacityZero) + )) node.remove() + }) + + // Set fill color to background color if its fill-opacity is 0 but stroke-opacity isn't 0 + fragment.querySelectorAll('rect').forEach(function (node) { + var style = node.getAttribute('style') + if (!style) return + var m = style.match(fillOpacityZero) + + if (m) { + var rgbFill = m[1] + `fill: rgb(${bgColor[0]},${bgColor[1]},${bgColor[2]});` + style = style.replace(m[0], rgbFill) + node.setAttribute('style', style) + } + }) // Fix black legends by removing rect.legendtoggle - svg = svg.replace(/]+>/g, '') + // regexp: svg = svg.replace(/]+>/g, '') + fragment.querySelectorAll('rect.legendtoggle').forEach(node => node.remove()) // Remove colorbar background if it's transparent - svg = svg.replace(fullyTransparentColorbarRegexp, '') - // Remove annotation's background if it's compleletely transparent - svg = svg.replace(fullyTransparentRectRegexp, '') + fragment.querySelectorAll('rect.cbbg').forEach(function (node) { + var style = node.getAttribute('style') + if (style && style.match(fillOpacityZero)) node.remove() + }) - // Set fill color to background color if its opacity is 0 - svg = svg.replace(transparentFillRectRegexp, function (match, p) { - return match.replace(/fill: [^;]*;/, `fill: rgb(${bgColor[0]},${bgColor[1]},${bgColor[2]});`) + // Fix fill in colorbars + fragment.querySelectorAll('rect.cbfill').forEach(function (node) { + var style = node.getAttribute('style') + if (style && style.match(fillUrl)) { + var gradientId = style.match(fillUrl)[2] + + var el = fragment.getElementById(gradientId) + // Inkscape doesn't deal well with gradientUnits="objectBoundingBox" + el.setAttribute('gradientUnits', 'userSpaceOnUse') + var height = node.getAttribute('height') + el.setAttribute('y1', height) + } }) - // Set stroke color to background color if its opacity is 0 - svg = svg.replace(transparentStrokeRectRegexp, function (match, p) { - return match.replace(/stroke: [^;]*;/, `stroke: rgb(${bgColor[0]},${bgColor[1]},${bgColor[2]});`) + + // Fix path with rgba color for fill + fragment.querySelectorAll('path').forEach(function (node) { + var style = node.getAttribute('style') + if (!style) return + var m = style.match(fillRgbaColor) + if (m) { + var sep = m[1] + var rgba = m[2].split(',') + if (rgba[3] === 0) { + node.remove() + } else { + var rgbFill = sep + 'fill: rgb(' + rgba.slice(0, 3) + ')' + style = style.replace(m[0], rgbFill) + node.setAttribute('style', style) + } + } }) - // Fix black background in rasterized images + svg = fragment.firstChild.outerHTML + + // Fix black background in rasterized images (WebGL) svg = svg.replace(imgRegexp, function (match, base64png) { var pngBuffer = Buffer.from(base64png, 'base64') var image = PNG.sync.read(pngBuffer) @@ -113,23 +166,6 @@ class Inkscape { return match.replace(xlinkHrefDataImageRegexp, `xlink:href="data:image/png;base64,${pngOpaqueBuffer.toString('base64')}"`) }) - // Inkscape doesn't convert well gradientUnits="objectBoundingBox" into EMF - svg.replace(colorbarFillRegexp, function (match) { - // var width = match.match(/width="(\d+)"/)[1] - var height = match.match(/height="(\d+)"/)[1] - var gradientId = match.match(/url\('#([^']*)'\)/) - - if (gradientId) { - gradientId = gradientId[1] - var gradientIdRegexp = new RegExp(`]*id="${gradientId}"[^>]*>`) - svg = svg.replace(gradientIdRegexp, function (m) { - return `` - }) - } - - return false - }) - return svg } From 7dddce534b0996e49c8ee9a06c196fd67ca65cb6 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Mon, 3 Dec 2018 16:25:43 -0500 Subject: [PATCH 10/24] jsdom 13.0.0 -> 11.12.0 to support node.js v6 --- package-lock.json | 109 ++++++++++++++++++++-------------------------- package.json | 2 +- 2 files changed, 48 insertions(+), 63 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4452f7f2..6efed68b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -80,8 +80,7 @@ "acorn": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", - "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", - "dev": true + "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==" }, "acorn-globals": { "version": "4.3.0", @@ -1372,6 +1371,18 @@ "abab": "^2.0.0", "whatwg-mimetype": "^2.2.0", "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } } }, "debug": { @@ -3203,43 +3214,36 @@ "optional": true }, "jsdom": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-13.0.0.tgz", - "integrity": "sha512-Kmq4ASMNkgpY+YufE322EnIKoiz0UWY2DRkKlU7d5YrIW4xiVRhWFrZV1fr6w/ZNxQ50wGAH5gGRzydgnmkkvw==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", "requires": { "abab": "^2.0.0", - "acorn": "^6.0.2", - "acorn-globals": "^4.3.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", "array-equal": "^1.0.0", - "cssom": "^0.3.4", - "cssstyle": "^1.1.1", - "data-urls": "^1.0.1", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", "domexception": "^1.0.1", - "escodegen": "^1.11.0", + "escodegen": "^1.9.1", "html-encoding-sniffer": "^1.0.2", - "nwsapi": "^2.0.9", - "parse5": "5.1.0", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", "pn": "^1.1.0", - "request": "^2.88.0", + "request": "^2.87.0", "request-promise-native": "^1.0.5", - "saxes": "^3.1.3", + "sax": "^1.2.4", "symbol-tree": "^3.2.2", - "tough-cookie": "^2.4.3", + "tough-cookie": "^2.3.4", "w3c-hr-time": "^1.0.1", - "w3c-xmlserializer": "^1.0.0", "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0", - "ws": "^6.1.0", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz", - "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==" - } } }, "json-parse-better-errors": { @@ -3408,6 +3412,11 @@ "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", "dev": true }, + "left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -6539,9 +6548,9 @@ } }, "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" }, "path-exists": { "version": "2.1.0", @@ -7174,16 +7183,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", - "dev": true - }, - "saxes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.4.tgz", - "integrity": "sha512-GVZmLJnkS4Vl8Pe9o4nc5ALZ615VOVxCmea8Cs0l+8GZw3RQ5XGOSUomIUfuZuk4Todo44v4y+HY1EATkDDiZg==", - "requires": { - "xmlchars": "^1.3.1" - } + "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=" }, "semver": { "version": "5.5.0", @@ -8338,16 +8338,6 @@ "browser-process-hrtime": "^0.1.2" } }, - "w3c-xmlserializer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.0.0.tgz", - "integrity": "sha512-0et1+9uXYiIRAecx1D5Z1nk60+vimniGdIKl4XjeqkWi6acoHNlXMv1VR5jV+jF4ooeO08oWbYxeAJOcon1oMA==", - "requires": { - "domexception": "^1.0.1", - "webidl-conversions": "^4.0.2", - "xml-name-validator": "^3.0.0" - } - }, "wdio-dot-reporter": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.10.tgz", @@ -8435,9 +8425,9 @@ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" }, "whatwg-url": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", - "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", "requires": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", @@ -8560,9 +8550,9 @@ } }, "ws": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.2.tgz", - "integrity": "sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", "requires": { "async-limiter": "~1.0.0" } @@ -8584,11 +8574,6 @@ "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=", "dev": true }, - "xmlchars": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-1.3.1.tgz", - "integrity": "sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==" - }, "xmldom": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", diff --git a/package.json b/package.json index 03eca719..fc071017 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "glob": "^7.1.2", "is-plain-obj": "^1.1.0", "is-url": "^1.2.4", - "jsdom": "^13.0.0", + "jsdom": "11.12.0", "minimist": "^1.2.0", "pngjs": "^3.3.3", "read-chunk": "^2.1.0", From 6b1a1fcd2d63c06b1dcf7e1e0e937856164968d1 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Tue, 4 Dec 2018 12:59:04 -0500 Subject: [PATCH 11/24] find image elements using jsdom --- src/util/inkscape.js | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/util/inkscape.js b/src/util/inkscape.js index 155eda23..8b6f8aef 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -140,31 +140,35 @@ class Inkscape { } }) - svg = fragment.firstChild.outerHTML - // Fix black background in rasterized images (WebGL) - svg = svg.replace(imgRegexp, function (match, base64png) { - var pngBuffer = Buffer.from(base64png, 'base64') - var image = PNG.sync.read(pngBuffer) - - for (var y = 0; y < image.height; y++) { - for (var x = 0; x < image.width; x++) { - var idx = (image.width * y + x) << 2 - - var alpha = image.data[idx + 3] - if (alpha < 255) { - // Manually do alpha composition (https://en.wikipedia.org/wiki/Alpha_compositing) - image.data[idx] = image.data[idx] * alpha / 255 + bgColor[0] * (1 - alpha / 255) - image.data[idx + 1] = image.data[idx + 1] * alpha / 255 + bgColor[1] * (1 - alpha / 255) - image.data[idx + 2] = image.data[idx + 2] * alpha / 255 + bgColor[2] * (1 - alpha / 255) - - image.data[idx + 3] = 255 + fragment.querySelectorAll('image').forEach(function (node) { + var dataType = 'data:image/png;base64' + var href = node.getAttribute('xlink:href') + var parts = href.split(',') + if(parts[0] === dataType) { + var pngBuffer = Buffer.from(parts[1], 'base64') + var image = PNG.sync.read(pngBuffer) + + for (var y = 0; y < image.height; y++) { + for (var x = 0; x < image.width; x++) { + var idx = (image.width * y + x) << 2 + + var alpha = image.data[idx + 3] + if (alpha < 255) { + // Manually do alpha composition (https://en.wikipedia.org/wiki/Alpha_compositing) + image.data[idx] = image.data[idx] * alpha / 255 + bgColor[0] * (1 - alpha / 255) + image.data[idx + 1] = image.data[idx + 1] * alpha / 255 + bgColor[1] * (1 - alpha / 255) + image.data[idx + 2] = image.data[idx + 2] * alpha / 255 + bgColor[2] * (1 - alpha / 255) + + image.data[idx + 3] = 255 + } } } + var pngOpaqueBuffer = PNG.sync.write(image) + node.setAttribute('xlink:href', dataType + ',' + pngOpaqueBuffer.toString('base64')) } - var pngOpaqueBuffer = PNG.sync.write(image) - return match.replace(xlinkHrefDataImageRegexp, `xlink:href="data:image/png;base64,${pngOpaqueBuffer.toString('base64')}"`) }) + svg = fragment.firstChild.outerHTML return svg } From d4a1bfa003362d90a9c55d1d9a7e49c640e4117e Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Tue, 4 Dec 2018 13:46:31 -0500 Subject: [PATCH 12/24] gl3d: use bg color from figure.layout if provided --- package-lock.json | 5 +++++ package.json | 1 + src/component/plotly-graph/convert.js | 3 ++- src/util/inkscape.js | 14 +++++++++++--- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6efed68b..0294559b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8046,6 +8046,11 @@ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", "dev": true }, + "tinycolor2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", + "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" + }, "tmatch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-4.0.0.tgz", diff --git a/package.json b/package.json index fc071017..84906368 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "run-series": "^1.1.8", "semver": "^5.4.1", "string-to-stream": "^1.1.1", + "tinycolor2": "^1.4.1", "uuid": "^3.3.2" }, "devDependencies": { diff --git a/src/component/plotly-graph/convert.js b/src/component/plotly-graph/convert.js index 685c9c96..eab2ca8f 100644 --- a/src/component/plotly-graph/convert.js +++ b/src/component/plotly-graph/convert.js @@ -10,6 +10,7 @@ const cst = require('./constants') * - imgData {string} (from render) * @param {object} opts : component options * - pdftops {string or instance of Pdftops) + * - inkscape {string or instance of Inkscape) * @param {function} reply * - errorCode {number or null} * - result {object} @@ -69,7 +70,7 @@ function convert (info, opts, reply) { return done() } - inkscape.svg2emf(svg, {id: info.id}, (err, emf) => { + inkscape.svg2emf(svg, {id: info.id, figure: info.figure}, (err, emf) => { if (err) { errorCode = 530 result.error = err diff --git a/src/util/inkscape.js b/src/util/inkscape.js index 8b6f8aef..a624535f 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -9,6 +9,7 @@ const PNG = require('pngjs').PNG const semver = require('semver') const jsdom = require('jsdom') const { JSDOM } = jsdom +const tinycolor = require("tinycolor2"); const PATH_TO_BUILD = path.join(os.tmpdir(), 'orca-build') try { @@ -59,7 +60,15 @@ class Inkscape { (cb) => fs.unlink(outPath, cb) ], cb) - svg = this.cleanSvg(svg) + var bgColor + if(opts.figure.layout.paper_bgcolor) { + var color = tinycolor(opts.figure.layout.paper_bgcolor) + color = color.toRgb() + bgColor = [color.r, color.g, color.b] + } else { + bgColor = [255, 255, 255] + } + svg = this.cleanSvg(svg, bgColor) series([ (cb) => fs.writeFile(inPath, svg, 'utf-8', cb), @@ -72,8 +81,7 @@ class Inkscape { }) } - cleanSvg (svg) { - var bgColor = [255, 255, 255] + cleanSvg (svg, bgColor) { const fragment = JSDOM.fragment(svg) // Remove path and rectangles that are compleletely transparent From 5432b59214bf03ca1706094f07ed448ad1fc3fc9 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Tue, 4 Dec 2018 13:47:03 -0500 Subject: [PATCH 13/24] fix lint --- src/util/inkscape.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/util/inkscape.js b/src/util/inkscape.js index a624535f..86b15ee5 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -9,16 +9,13 @@ const PNG = require('pngjs').PNG const semver = require('semver') const jsdom = require('jsdom') const { JSDOM } = jsdom -const tinycolor = require("tinycolor2"); +const tinycolor = require('tinycolor2') const PATH_TO_BUILD = path.join(os.tmpdir(), 'orca-build') try { fs.mkdirSync(PATH_TO_BUILD) } catch (e) {} -const imgRegexp = /]*>/ -const xlinkHrefDataImageRegexp = /xlink:href="data:image\/png;base64,([^"]*)"/ - const fillUrl = /(^|; )fill: url\('#([^']*)'\);/ const fillRgbaColor = /(^|; )fill: rgba\(([^)]*)\);/ const fillOpacityZero = /(^|\s*)fill-opacity: 0;/ @@ -61,7 +58,7 @@ class Inkscape { ], cb) var bgColor - if(opts.figure.layout.paper_bgcolor) { + if (opts.figure.layout.paper_bgcolor) { var color = tinycolor(opts.figure.layout.paper_bgcolor) color = color.toRgb() bgColor = [color.r, color.g, color.b] @@ -153,7 +150,7 @@ class Inkscape { var dataType = 'data:image/png;base64' var href = node.getAttribute('xlink:href') var parts = href.split(',') - if(parts[0] === dataType) { + if (parts[0] === dataType) { var pngBuffer = Buffer.from(parts[1], 'base64') var image = PNG.sync.read(pngBuffer) From 212ed21fcab67aeda4cef2fa8462ad9bbe8d83f8 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Tue, 4 Dec 2018 15:44:35 -0500 Subject: [PATCH 14/24] fix Inkscape unit test --- src/util/inkscape.js | 1 + test/common.js | 1 + test/pretest.js | 2 ++ test/unit/inkscape_test.js | 6 +++--- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/util/inkscape.js b/src/util/inkscape.js index 86b15ee5..2451d47f 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -57,6 +57,7 @@ class Inkscape { (cb) => fs.unlink(outPath, cb) ], cb) + // Get background color from figure's definition var bgColor if (opts.figure.layout.paper_bgcolor) { var color = tinycolor(opts.figure.layout.paper_bgcolor) diff --git a/test/common.js b/test/common.js index 28b18f7d..8cfbadcb 100644 --- a/test/common.js +++ b/test/common.js @@ -18,6 +18,7 @@ urls.dummy = 'http://dummy.url' urls.plotlyGraphMock = 'https://raw.githubusercontent.com/plotly/plotly.js/master/test/image/mocks/20.json' try { + mocks.figure = JSON.parse(fs.readFileSync(path.join(paths.build, 'test-mock.json'), 'utf-8')) mocks.svg = fs.readFileSync(path.join(paths.build, 'test-mock.svg'), 'utf-8') mocks.pdf = fs.readFileSync(path.join(paths.build, 'test-mock.pdf')) } catch (e) {} diff --git a/test/pretest.js b/test/pretest.js index c016f640..cc401617 100644 --- a/test/pretest.js +++ b/test/pretest.js @@ -1,5 +1,6 @@ const { execSync } = require('child_process') const { paths } = require('./common') +const fs = require('fs') const mock = JSON.stringify({ data: [{ @@ -10,6 +11,7 @@ const mock = JSON.stringify({ } }) +fs.writeFileSync(`${paths.build}/test-mock.json`, mock) // https://stackoverflow.com/a/31104898/392162 – "Use child_process.execSync but keep output in console" const execSyncArgs = { stdio: [0, 1, 2] } diff --git a/test/unit/inkscape_test.js b/test/unit/inkscape_test.js index 65e7278e..e7ff5a05 100644 --- a/test/unit/inkscape_test.js +++ b/test/unit/inkscape_test.js @@ -12,7 +12,7 @@ tap.test('inkscape.svg2emf', t => { const inkscape = new Inkscape() const outPath = path.join(paths.build, 'inkscape-test.emf') - inkscape.svg2emf(mocks.svg, {}, (err, result) => { + inkscape.svg2emf(mocks.svg, {figure: mocks.figure}, (err, result) => { if (err) t.fail(err) t.type(result, Buffer) @@ -31,7 +31,7 @@ tap.test('inkscape.svg2emf', t => { const tmpOutPath = path.join(paths.build, 'tmp-emf') const tmpSvgPath = path.join(paths.build, 'tmp-svg') - inkscape.svg2emf(mocks.svg, {id: 'tmp'}, (err, result) => { + inkscape.svg2emf(mocks.svg, {id: 'tmp', figure: mocks.figure}, (err, result) => { if (err) t.fail(err) t.type(result, Buffer) @@ -47,7 +47,7 @@ tap.test('inkscape.svg2emf', t => { const tmpOutPath = path.join(paths.build, 'tmp-emf') const tmpSvgPath = path.join(paths.build, 'tmp-svg') - inkscape.svg2emf(mocks.svg, {id: 'tmp'}, (err) => { + inkscape.svg2emf(mocks.svg, {id: 'tmp', figure: mocks.figure}, (err) => { t.throws(() => { throw err }, /Command failed/) t.notOk(fs.existsSync(tmpOutPath), 'clears tmp emf file') t.notOk(fs.existsSync(tmpSvgPath), 'clears tmp svg file') From 37747b1248d8be7705045c77728ecdfdcec481d8 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Wed, 5 Dec 2018 17:50:38 -0500 Subject: [PATCH 15/24] relax constraint for Inkscape's version: now requires gte 0.92.x --- src/util/inkscape.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/inkscape.js b/src/util/inkscape.js index 2451d47f..a0fa52f3 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -212,8 +212,8 @@ class Inkscape { throw new Error('Inkscape is not installed') } - if (!this.Version() || !semver.gte(this.Version(), '0.92.3')) { - throw new Error('Inkscape version should be greater than or equal to 0.92.3') + if (!this.Version() || !semver.gte(this.Version(), '0.92.0')) { + throw new Error('Inkscape version should be greater than or equal to 0.92.0') } } } From 315a7d6c9d6a6d1e5979148b528c79c28b491adf Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Wed, 5 Dec 2018 18:50:34 -0500 Subject: [PATCH 16/24] use different port for orca_serve_graph-only_test.js --- test/integration/orca_serve_graph-only_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/orca_serve_graph-only_test.js b/test/integration/orca_serve_graph-only_test.js index f2330a18..e4342029 100644 --- a/test/integration/orca_serve_graph-only_test.js +++ b/test/integration/orca_serve_graph-only_test.js @@ -3,7 +3,7 @@ const Application = require('spectron').Application const request = require('request') const { paths } = require('../common') -const PORT = 9109 +const PORT = 9110 const SERVER_URL = `http://localhost:${PORT}` const app = new Application({ From 48e1e11129136327df4f025109cdd4ff59363fcc Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Wed, 5 Dec 2018 18:50:47 -0500 Subject: [PATCH 17/24] npm install with latest npm version --- package-lock.json | 242 +++++++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0294559b..85cf16d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -168,7 +168,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -189,7 +189,7 @@ "ansi-escapes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha1-9zIHu4EgfXX9bIPxJa8m7qN4yjA=", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", "dev": true }, "ansi-regex": { @@ -201,7 +201,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -399,7 +399,7 @@ "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "requires": { "safer-buffer": "~2.1.0" } @@ -412,7 +412,7 @@ "async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha1-skWiPKcZMAROxT+kaqAKPofGphA=", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { "lodash": "^4.17.10" @@ -421,7 +421,7 @@ "async-exit-hook": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", - "integrity": "sha1-i9iwJLDsmxwBzMua+dspvXF9+vM=", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", "dev": true }, "async-limiter": { @@ -448,7 +448,7 @@ "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha1-8OAD2cqef1nHpQiUXXsu+aBKVC8=" + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "babel-code-frame": { "version": "6.26.0", @@ -521,13 +521,13 @@ "bind-obj-methods": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.0.tgz", - "integrity": "sha1-AXgUDb57e7Z9x0iSrOWbwCR/BvA=", + "integrity": "sha512-3/qRXczDi2Cdbz6jE+W3IflJOutRVica8frpBn14de1mBOkzDo+6tY33kNhvkw54Kn3PzRRD2VnGbGPcTAk4sw==", "dev": true }, "bl": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha1-oWCRFxcQPAdBDO9j71Gzl8Alr5w=", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "dev": true, "requires": { "readable-stream": "^2.3.5", @@ -601,7 +601,7 @@ "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha1-VcbDmouljZxhrSLNh3Uy3rZlogs=", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", "dev": true, "requires": { "ansi-align": "^2.0.0", @@ -660,7 +660,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -714,7 +714,7 @@ "buffer-alloc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha1-iQ3ZDZI6hz4I4Q5f1RpX5bfM4Ow=", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", @@ -724,7 +724,7 @@ "buffer-alloc-unsafe": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha1-vX3CauKXLQ7aJTvgYdupkjScGfA=", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", "dev": true }, "buffer-crc32": { @@ -742,7 +742,7 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "builder-util": { @@ -892,7 +892,7 @@ "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -932,7 +932,7 @@ "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", "dev": true }, "clean-yaml-object": { @@ -988,7 +988,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -1035,7 +1035,7 @@ "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha1-k4NDeaHMmgxh+C9S8NBDIiUb1aI=", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, "combined-stream": { @@ -1153,7 +1153,7 @@ "configstore": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha1-xvJd767vJt8S3TNBSwAf6BpUP48=", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", "dev": true, "requires": { "dot-prop": "^4.1.0", @@ -1178,7 +1178,7 @@ "core-js": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha1-+XJgj/DOrWi4QaFqky0LGDeRgU4=", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", "dev": true }, "core-util-is": { @@ -1189,7 +1189,7 @@ "coveralls": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.2.tgz", - "integrity": "sha1-9aC82Qyk5k4Ii3EPqN2mQK6kiE8=", + "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==", "dev": true, "requires": { "growl": "~> 1.10.0", @@ -1203,7 +1203,7 @@ "crc": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha1-rWAmnCyFb4wpnixMwN5FVpFAVsY=", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", "dev": true, "requires": { "buffer": "^5.1.0" @@ -1388,7 +1388,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -1415,7 +1415,7 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha1-xPp8lUBKF6nD6Mp+FTcxK3NjMKw=", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, "deep-is": { @@ -1426,7 +1426,7 @@ "deepmerge": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.0.1.tgz", - "integrity": "sha1-JcHCTxEPuRT4AAG5JSZN138/QxI=", + "integrity": "sha512-VIPwiMJqJ13ZQfaCsIFnp5Me9tnjURiaIFxfz7EH0Ci0dTSQpZtSLrqOicXqEd/z2r+z+Klk9GzmnRsgpgbOsQ==", "dev": true }, "define-properties": { @@ -1442,7 +1442,7 @@ "object-keys": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha1-CcU4VTd1dTEMymL1W7M0q/97PtI=", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", "dev": true } } @@ -1450,7 +1450,7 @@ "deglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.1.tgz", - "integrity": "sha1-0mjhaHJ3mYYujqwHBC4WWVfB874=", + "integrity": "sha512-2kjwuGGonL7gWE1XU4Fv79+vVzpoQCl0V+boMwWtOQJV2AGDabCwez++nB1Nli/8BabAfZQ/UuHPlp6AymKdWw==", "dev": true, "requires": { "find-root": "^1.0.0", @@ -1501,7 +1501,7 @@ "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "dmg-builder": { @@ -1534,7 +1534,7 @@ "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -1551,7 +1551,7 @@ "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", "dev": true, "requires": { "is-obj": "^1.0.0" @@ -1791,7 +1791,7 @@ "electron-chromedriver": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-1.8.0.tgz", - "integrity": "sha1-kBcUEzz29gk9Nl4fRKUtmWJNgkE=", + "integrity": "sha512-m1f3nle5MaGp94bcDTtMZZMMOgPO54+TXoPBlTbBSUjfINR5SJ46yQXLfuE79/qsFfJKslZB1UzWURDDFIRmpQ==", "dev": true, "requires": { "electron-download": "^4.1.0", @@ -1845,7 +1845,7 @@ "electron-debug": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/electron-debug/-/electron-debug-1.5.0.tgz", - "integrity": "sha1-2IwCFG77f8WuGyHqxW++SYfq5Qw=", + "integrity": "sha512-23CLHQXW+gMgdlJbeW1EinPX7DpwuLtfdzSuFL0OnsqEhKGJVJufAZTyq2hc3sr+R53rr3P+mJiYoR5VzAHKJQ==", "dev": true, "requires": { "electron-is-dev": "^0.3.0", @@ -1884,7 +1884,7 @@ "electron-localshortcut": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-3.1.0.tgz", - "integrity": "sha1-EMH/1Te405FwqvbhVRNB93gN0s4=", + "integrity": "sha512-MgL/j5jdjW7iA0R6cI7S045B0GlKXWM1FjjujVPjlrmyXRa6yH0bGSaIAfxXAF9tpJm3pLEiQzerYHkRh9JG/A==", "dev": true, "requires": { "debug": "^2.6.8", @@ -1975,7 +1975,7 @@ "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha1-7SljTRm6ukY7bOa4CjchPqtx7EM=", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "dev": true, "requires": { "once": "^1.4.0" @@ -2008,7 +2008,7 @@ "es-abstract": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha1-nbvdJ8aFbwABQhyhh4LXhr+KYWU=", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", "dev": true, "requires": { "es-to-primitive": "^1.1.1", @@ -2069,7 +2069,7 @@ "eslint": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz", - "integrity": "sha1-D4EmetEBLn0gUeGGqQBMwiZ7jUU=", + "integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==", "dev": true, "requires": { "ajv": "^5.3.0", @@ -2167,19 +2167,19 @@ "eslint-config-standard": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz", - "integrity": "sha1-h+4NPJ2VOC3HYZWMuyPanuox4Lo=", + "integrity": "sha512-oDdENzpViEe5fwuRCWla7AXQd++/oyIp8zP+iP9jiUPG6NBj3SHgdgtl/kTn00AjeN+1HNvavTKmYbMo+xMOlw==", "dev": true }, "eslint-config-standard-jsx": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-5.0.0.tgz", - "integrity": "sha1-Sr+sVU84Zo4AeMZkVp57I4Tl0qo=", + "integrity": "sha512-rLToPAEqLMPBfWnYTu6xRhm2OWziS2n40QFqJ8jAM8NSVzeVKTa3nclhsU4DpPJQRY60F34Oo1wi/71PN/eITg==", "dev": true }, "eslint-import-resolver-node": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha1-WPFfuDm40FdsqYBBNHaqskcttmo=", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", "dev": true, "requires": { "debug": "^2.6.9", @@ -2292,7 +2292,7 @@ "eslint-plugin-node": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz", - "integrity": "sha1-vxlkIpgGQ3kxXXpLKnWTc3b6BeQ=", + "integrity": "sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw==", "dev": true, "requires": { "ignore": "^3.3.6", @@ -2304,13 +2304,13 @@ "eslint-plugin-promise": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.7.0.tgz", - "integrity": "sha1-9L3lwsd83WlVeo9pok0a08/J5n4=", + "integrity": "sha512-2WO+ZFh7vxUKRfR0cOIMrWgYKdR6S1AlOezw6pC52B6oYpd5WFghN+QHxvrRdZMtbo8h3dfUZ2o1rWb0UPbKtg==", "dev": true }, "eslint-plugin-react": { "version": "7.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz", - "integrity": "sha1-9gbHGdvYoaKz0lwWKZgTh4zKAWA=", + "integrity": "sha512-KC7Snr4YsWZD5flu6A5c0AcIZidzW3Exbqp7OT67OaD2AppJtlBr/GuPrW/vaQM/yfZotEvKAdrxrO+v8vwYJA==", "dev": true, "requires": { "doctrine": "^2.0.2", @@ -2328,7 +2328,7 @@ "eslint-scope": { "version": "3.7.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha1-u1ByANPRf2AkdjYWC0gmKEsQhTU=", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -2338,13 +2338,13 @@ "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha1-PzGA+y4pEBdxastMnW1bXDSmqB0=", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", "dev": true }, "espree": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha1-sPRHGHyKi+2US4FaZgvd9d610ac=", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { "acorn": "^5.5.0", @@ -2360,7 +2360,7 @@ "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { "estraverse": "^4.0.0" @@ -2369,7 +2369,7 @@ "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { "estraverse": "^4.1.0" @@ -2422,12 +2422,12 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "external-editor": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha1-BFURz9jRM/OEZnPRBHwVTiFK09U=", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", "dev": true, "requires": { "chardet": "^0.4.0", @@ -2503,12 +2503,12 @@ "file-type": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", - "integrity": "sha1-po1a0H9IZBTfssiGb3MWGUZxShg=" + "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==" }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha1-q8/Iunb3CMQql7PWhbfpRQv7nOQ=", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", "dev": true }, "find-up": { @@ -2579,7 +2579,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha1-a+Dem+mYzhavivwkSXue6bfM2a0=", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "dev": true }, "fs-exists-cached": { @@ -2641,7 +2641,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "function-loop": { @@ -2659,7 +2659,7 @@ "gaze": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha1-xEFzPhO5J6yMD/C0w7Az8ogSkko=", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", "dev": true, "requires": { "globule": "^1.0.0" @@ -2735,7 +2735,7 @@ "globule": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", - "integrity": "sha1-Xf+xsZHyLSB5epNptJ6rTpg5aW0=", + "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", "dev": true, "requires": { "glob": "~7.1.1", @@ -2771,7 +2771,7 @@ "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "har-schema": { @@ -2804,7 +2804,7 @@ "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { "function-bind": "^1.1.1" @@ -2879,19 +2879,19 @@ "ieee754": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha1-UL8k5bnIu5ivSWTJQc2wkY2ntgs=", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", "dev": true }, "ignore": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, "image-size": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", - "integrity": "sha1-5+XGW7U0vXzc7dbLUWYnKoX3X7I=", + "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==", "dev": true }, "import-lazy": { @@ -2932,13 +2932,13 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, "inquirer": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha1-ndLyrXZdyrH/BEO0kUQqILoifck=", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "requires": { "ansi-escapes": "^3.0.0", @@ -2972,7 +2972,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -3014,7 +3014,7 @@ "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha1-HhrfIZ4e62hNaR+dagX/DTCiTXU=", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", "dev": true }, "is-ci": { @@ -3125,7 +3125,7 @@ "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, "is-retry-allowed": { @@ -3154,7 +3154,7 @@ "is-url": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha1-BKTfRtKMTP89c9Af8Gq+sxihqlI=" + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" }, "is-utf8": { "version": "0.2.1", @@ -3165,7 +3165,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "isarray": { @@ -3249,7 +3249,7 @@ "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk=", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "json-schema": { @@ -3317,13 +3317,13 @@ "keyboardevent-from-electron-accelerator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-1.1.0.tgz", - "integrity": "sha1-MkYU9uM0kMN//Fvlh2s+hf4iPIQ=", + "integrity": "sha512-VDC4vKWGrR3VgIKCE4CsXnvObGgP8C2idnTKEMUkuEuvDGE1GEBX9FtNdJzrD00iQlhI3xFxRaeItsUmlERVng==", "dev": true }, "keyboardevents-areequal": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz", - "integrity": "sha1-iBkexzjOn3WRwl6QVt6Si0AncZQ=", + "integrity": "sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==", "dev": true }, "klaw": { @@ -3347,7 +3347,7 @@ "lazy-val": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.3.tgz", - "integrity": "sha1-u5eyAO8AgB2UwxfincbtOeMcXtw=", + "integrity": "sha512-pjCf3BYk+uv3ZcPzEVM0BFvO9Uw58TmlrU0oG5tTrr9Kcid3+kdKxapH8CjdYmVa2nO5wOoZn2rdvZx2PKj/xg==", "dev": true }, "lazystream": { @@ -3476,7 +3476,7 @@ "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha1-Y7lQIfBwL+36LJuwok53l9cYcdg=", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", "dev": true }, "lolex": { @@ -3488,7 +3488,7 @@ "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -3507,7 +3507,7 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha1-b54wtHCE2XGnyCD/FabFFnt0wm8=", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "dev": true }, "lru-cache": { @@ -3598,7 +3598,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "^1.1.7" } @@ -3683,7 +3683,7 @@ "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", @@ -6375,7 +6375,7 @@ "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=" + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, "object-assign": { "version": "4.1.1", @@ -6482,7 +6482,7 @@ "own-or-env": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", - "integrity": "sha1-VM5gHTv3gjbFxlYzqhyOwD+AB+Q=", + "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", "dev": true, "requires": { "own-or": "^1.0.0" @@ -6581,7 +6581,7 @@ "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, "path-to-regexp": { @@ -6714,7 +6714,7 @@ "plist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", - "integrity": "sha1-qbkx0XwwTokS7wujvdYYK68uH4w=", + "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", "dev": true, "requires": { "base64-js": "^1.2.3", @@ -6739,7 +6739,7 @@ "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "pn": { @@ -6806,7 +6806,7 @@ "prop-types": { "version": "15.6.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", - "integrity": "sha1-BdXKd7RFPphdYPx/+MhZCUpJcQI=", + "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", "dev": true, "requires": { "loose-envify": "^1.3.1", @@ -6822,7 +6822,7 @@ "psl": { "version": "1.1.29", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha1-YPWA02AXC7cip5fMcEQR5tqFDGc=" + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" }, "punycode": { "version": "1.4.1", @@ -6838,7 +6838,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=" + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "querystring": { "version": "0.2.0", @@ -6858,7 +6858,7 @@ "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha1-zZJL9SAKB1uDwYjNa54hG3/A0+0=", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "requires": { "deep-extend": "^0.6.0", @@ -6954,13 +6954,13 @@ "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha1-vgWtf5v30i4Fb5cmzuUBf78Z4uk=", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", "dev": true }, "registry-auth-token": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha1-hR/UkDjuy1hpERFa+EUmDuyYPyA=", + "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", "dev": true, "requires": { "rc": "^1.1.6", @@ -6994,7 +6994,7 @@ "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha1-nC/KT301tZLv5Xx/ClXoEFIST+8=", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -7068,7 +7068,7 @@ "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha1-gvHsGaQjrB+9CAsLqwa6NuhKeiY=", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", "dev": true, "requires": { "path-parse": "^1.0.5" @@ -7099,13 +7099,13 @@ "rgb2hex": { "version": "0.1.9", "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.9.tgz", - "integrity": "sha1-XT4OFLAXe1aObw1bQ+NPv9tnA0Y=", + "integrity": "sha512-32iuQzhOjyT+cv9aAFRBJ19JgHwzQwbjUhH3Fj2sWW2EEGAW8fpFrDFP5ndoKDxJaLO06x1hE3kyuIFrUQtybQ==", "dev": true }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { "glob": "^7.0.5" @@ -7123,17 +7123,17 @@ "run-parallel": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha1-yd06fPn0ssS2JE4XOm7YZuYd1nk=" + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" }, "run-parallel-limit": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.0.5.tgz", - "integrity": "sha1-wppP0XtN81jLUqiml4EaY8mE8bc=" + "integrity": "sha512-NsY+oDngvrvMxKB3G8ijBzIema6aYbQMD2bHOamvN52BysbIGTnEY2xsNyfrcr9GhY995/t/0nQN3R3oZvaDlg==" }, "run-series": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.8.tgz", - "integrity": "sha1-LEVY9JIh4BzWNx/04KHiA+Rg/DY=" + "integrity": "sha512-+GztYEPRpIsQoCSraWHDBs9WVy4eVME16zhOtDB4H9J4xN0XRhknnmLOl+4gRgZtu8dpp9N/utSPjKH/xmDzXg==" }, "rx-lite": { "version": "4.0.8", @@ -7163,7 +7163,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "samsam": { "version": "1.3.0", @@ -7183,7 +7183,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=" + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "semver": { "version": "5.5.0", @@ -7266,7 +7266,7 @@ "slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha1-BE8aSdiEL/MHqta1Be0Xi9lQE00=", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" @@ -7283,7 +7283,7 @@ "snazzy": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/snazzy/-/snazzy-7.1.1.tgz", - "integrity": "sha1-JmObGacsTVQsdiBJ+CnRShrRaHk=", + "integrity": "sha512-gJ46s+jcwOeRhO9uEkTyzcREFZ0c5LZOgcVakLxTPIvhRIywKvbvArvMg5e8bBbpWe4InC/8eyEQOGXgJVNOfw==", "dev": true, "requires": { "chalk": "^2.3.0", @@ -7395,7 +7395,7 @@ "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha1-cuLMNAlVQ+Q7LGKyxMENSpBU8lk=", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { "atob": "^2.1.1", @@ -7452,7 +7452,7 @@ "spectron": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/spectron/-/spectron-3.8.0.tgz", - "integrity": "sha1-Eiw1Yv1+krfN9vlAlKpJWxUN+lE=", + "integrity": "sha512-fQ7gFp6UuEaONjXFLifLeIUI022pOsm3b+NFAm696r2umUkSZ9IbnEgHwrvBX+pJ3QUDyCEs5bPHUieYU7FvaQ==", "dev": true, "requires": { "dev-null": "^0.1.1", @@ -7471,7 +7471,7 @@ "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, "requires": { "through": "2" @@ -7508,7 +7508,7 @@ "standard": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/standard/-/standard-11.0.1.tgz", - "integrity": "sha1-Sb5Ax28dVklksiu/cwmSmtAzXik=", + "integrity": "sha512-nu0jAcHiSc8H+gJCXeiziMVZNDYi8MuqrYJKxTgjP4xKXZMKm311boqQIzDrYI/ktosltxt2CbDjYQs9ANC8IA==", "dev": true, "requires": { "eslint": "~4.18.0", @@ -7525,7 +7525,7 @@ "standard-engine": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-8.0.1.tgz", - "integrity": "sha1-C3e+jXq5Y2dXF9vqwe8dZnX7YvA=", + "integrity": "sha512-LA531C3+nljom/XRvdW/hGPXwmilRkaRkENhO3FAGF1Vtq/WtCXzgmnc5S6vUHHsgv534MRy02C1ikMwZXC+tw==", "dev": true, "requires": { "deglob": "^2.1.0", @@ -7537,7 +7537,7 @@ "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha1-ngm/cSs2CrkiXoEgSPcf3pyJZXs=", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", "dev": true } } @@ -7570,7 +7570,7 @@ "string-to-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string-to-stream/-/string-to-stream-1.1.1.tgz", - "integrity": "sha1-q6ePc+cGYbEw7j4cAZK+T+9stZk=", + "integrity": "sha512-QySF2+3Rwq0SdO3s7BAp4x+c3qsClpPQ6abAmb0DGViiSBAkT5kL6JT2iyzEVP+T1SmzHrQD1TwlP9QAHCc+Sw==", "requires": { "inherits": "^2.0.1", "readable-stream": "^2.1.0" @@ -7708,7 +7708,7 @@ "table": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha1-ozRHN1OR52atNNNIbm4q7chNLjY=", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { "ajv": "^5.2.3", @@ -7746,7 +7746,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -7837,7 +7837,7 @@ "tap-mocha-reporter": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-3.0.7.tgz", - "integrity": "sha1-I15XiTtQCGHqXQkkll2t+y8F6qc=", + "integrity": "sha512-GHVXJ38C3oPRpM3YUc43JlGdpVZYiKeT1fmAd3HH2+J+ZWwsNAUFvRRdoGsXLw9+gU9o+zXpBqhS/oXyRQYwlA==", "dev": true, "requires": { "color-support": "^1.1.0", @@ -7900,7 +7900,7 @@ "tap-parser": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-5.4.0.tgz", - "integrity": "sha1-aQfolyXXt/pq5B7ixGTD20MYiuw=", + "integrity": "sha512-BIsIaGqv7uTQgTW1KLTMNPSEQf4zDDPgYOBRdgOfuB+JFOLRBfEu6cLa/KvMvmqggu1FKXDfitjLwsq4827RvA==", "dev": true, "requires": { "events-to-array": "^1.0.1", @@ -7913,7 +7913,7 @@ "tap-parser": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz", - "integrity": "sha1-VNs1MC/aLCzMIZVK074issukJyE=", + "integrity": "sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA==", "dev": true, "requires": { "events-to-array": "^1.0.1", @@ -8054,13 +8054,13 @@ "tmatch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-4.0.0.tgz", - "integrity": "sha1-uheAB/ML9qcPN8ZD/KUEX7L4xEg=", + "integrity": "sha512-Ynn2Gsp+oCvYScQXeV+cCs7citRDilq0qDXA6tuvFwDgiYyyaq7D5vKUlAPezzZR5NDobc/QMeN6e5guOYmvxg==", "dev": true }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -8069,13 +8069,13 @@ "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha1-STvUj2LXxD/N7TE6A9ytsuEhOoA=", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", "dev": true }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha1-U/Nto/R3g7CSWvoG/587FlKA94E=", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -8148,7 +8148,7 @@ "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw=", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "typedarray": { @@ -8197,7 +8197,7 @@ "update-notifier": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha1-0HRFk+E/Fh5AassdlAi3LK0Ir/Y=", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", "dev": true, "requires": { "boxen": "^1.2.1", @@ -8313,7 +8313,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha1-G0r0lV6zB3xQHCOHL8ZROBFYcTE=" + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "validate-npm-package-license": { "version": "3.0.1", @@ -8346,7 +8346,7 @@ "wdio-dot-reporter": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.10.tgz", - "integrity": "sha1-+s+3ycWYQUmVH1nLw80HUhAc8OA=", + "integrity": "sha512-A0TCk2JdZEn3M1DSG9YYbNRcGdx/YRw19lTiRpgwzH4qqWkO/oRDZRmi3Snn4L2j54KKTfPalBhlOtc8fojVgg==", "dev": true }, "webdriverio": { @@ -8478,7 +8478,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -8546,7 +8546,7 @@ "write-file-atomic": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha1-H/YVdcLipOjlENb6TiQ8zhg5mas=", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -8652,7 +8652,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", From c1822e2f49842914f33857b5cd593fc8bee76913 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Wed, 5 Dec 2018 19:27:31 -0500 Subject: [PATCH 18/24] teardown server last, orca should reply 404 instead of ECONNREFUSED --- test/integration/orca_serve_graph-only_test.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/test/integration/orca_serve_graph-only_test.js b/test/integration/orca_serve_graph-only_test.js index e4342029..e6267144 100644 --- a/test/integration/orca_serve_graph-only_test.js +++ b/test/integration/orca_serve_graph-only_test.js @@ -57,12 +57,6 @@ tap.test('should work for *plotly-graph* component', t => { }) }) -tap.test('should teardown', t => { - app.stop() - .catch(t.fail) - .then(t.end) -}) - tap.test('should not work for *plotly-thumbnail* component', t => { request({ method: 'POST', @@ -75,8 +69,15 @@ tap.test('should not work for *plotly-thumbnail* component', t => { } }) }, (err, res) => { - t.equal(err.code, 'ECONNREFUSED') - t.equal(res, undefined, 'should be undefined') + if (err) t.fail(err) + + t.equal(res.statusCode, 404, 'should return a HTTP 404 response') t.end() }) }) + +tap.test('should teardown', t => { + app.stop() + .catch(t.fail) + .then(t.end) +}) From ffc9bfd2bd1806a9e1d19de6441539355faf5105 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Thu, 6 Dec 2018 11:41:17 -0500 Subject: [PATCH 19/24] cache node_modules only if package-lock.json didn't change --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index c6615798..4aa3fea1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,7 @@ platform: #services: cache: - - node_modules + - node_modules -> package-lock.json - '%LOCALAPPDATA%\electron\Cache' - '%LOCALAPPDATA%\electron-builder\cache' From e24f167205e6e2169894a95cc63cb57a3a555c75 Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Thu, 6 Dec 2018 12:48:05 -0500 Subject: [PATCH 20/24] install Inkscape in deployment container --- deployment/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/Dockerfile b/deployment/Dockerfile index ca3ef3b8..ba548875 100644 --- a/deployment/Dockerfile +++ b/deployment/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:xenial +FROM ubuntu:bionic #################### # Install node and dependencies @@ -90,7 +90,7 @@ RUN apt-get update -y && apt-get install -y subversion && \ RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' && \ apt-get update -y && \ - apt-get install -y google-chrome-stable xvfb poppler-utils git && \ + apt-get install -y google-chrome-stable xvfb poppler-utils inkscape git && \ rm -rf /var/lib/apt/lists/* && apt-get clean COPY package.json /var/www/image-exporter/ From e76c52be7e219dcb41737c26f96fd0efc2e3dccd Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Thu, 6 Dec 2018 13:08:36 -0500 Subject: [PATCH 21/24] improve code readability and style --- src/util/inkscape.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/util/inkscape.js b/src/util/inkscape.js index a0fa52f3..e1c3eebe 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -98,7 +98,8 @@ class Inkscape { var m = style.match(fillOpacityZero) if (m) { - var rgbFill = m[1] + `fill: rgb(${bgColor[0]},${bgColor[1]},${bgColor[2]});` + var sep = m[1] + var rgbFill = `${sep}fill: rgb(${bgColor[0]},${bgColor[1]},${bgColor[2]});` style = style.replace(m[0], rgbFill) node.setAttribute('style', style) } @@ -139,7 +140,7 @@ class Inkscape { if (rgba[3] === 0) { node.remove() } else { - var rgbFill = sep + 'fill: rgb(' + rgba.slice(0, 3) + ')' + var rgbFill = `${sep}fill: rgb(${rgba.slice(0, 3).join(',')})` style = style.replace(m[0], rgbFill) node.setAttribute('style', style) } From e4ab53daff9840acc8c0ee8b54bf8ab249baf5cb Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Thu, 6 Dec 2018 16:23:33 -0500 Subject: [PATCH 22/24] safer code which ensures there is a figure.layout object --- src/util/inkscape.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/inkscape.js b/src/util/inkscape.js index e1c3eebe..250b7a28 100644 --- a/src/util/inkscape.js +++ b/src/util/inkscape.js @@ -59,7 +59,7 @@ class Inkscape { // Get background color from figure's definition var bgColor - if (opts.figure.layout.paper_bgcolor) { + if ((opts.figure.layout || {}).paper_bgcolor) { var color = tinycolor(opts.figure.layout.paper_bgcolor) color = color.toRgb() bgColor = [color.r, color.g, color.b] From b6daae1db73b7019a425e8165ed2a97eb515f96d Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Thu, 6 Dec 2018 16:30:58 -0500 Subject: [PATCH 23/24] revert to ubuntu:xenial, install latest Inkscape from a PPA --- deployment/Dockerfile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/deployment/Dockerfile b/deployment/Dockerfile index ba548875..c24b8004 100644 --- a/deployment/Dockerfile +++ b/deployment/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:bionic +FROM ubuntu:xenial #################### # Install node and dependencies @@ -90,7 +90,7 @@ RUN apt-get update -y && apt-get install -y subversion && \ RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' && \ apt-get update -y && \ - apt-get install -y google-chrome-stable xvfb poppler-utils inkscape git && \ + apt-get install -y google-chrome-stable xvfb poppler-utils git && \ rm -rf /var/lib/apt/lists/* && apt-get clean COPY package.json /var/www/image-exporter/ @@ -109,6 +109,12 @@ RUN cd /opt && \ ln -s monit-* monit && \ chmod 600 /etc/monitrc +#################### +# Install latest stable Inkscape +RUN apt-get update && apt-get install -y software-properties-common python-software-properties \ + && add-apt-repository -y ppa:inkscape.dev/stable && apt-get install -y inkscape \ + && rm -rf /var/lib/apt/lists/* && apt-get clean + #################### # Add entrypoint script COPY deployment/run_server / From f117d367a105810ca6ce0e02269fda32aed9e8af Mon Sep 17 00:00:00 2001 From: Antoine Roy-Gobeil Date: Thu, 6 Dec 2018 16:48:16 -0500 Subject: [PATCH 24/24] run `apt-get update` prior to installing Inkscape to get latest version --- deployment/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deployment/Dockerfile b/deployment/Dockerfile index c24b8004..c3e04467 100644 --- a/deployment/Dockerfile +++ b/deployment/Dockerfile @@ -112,7 +112,8 @@ RUN cd /opt && \ #################### # Install latest stable Inkscape RUN apt-get update && apt-get install -y software-properties-common python-software-properties \ - && add-apt-repository -y ppa:inkscape.dev/stable && apt-get install -y inkscape \ + && add-apt-repository -y ppa:inkscape.dev/stable \ + && apt-get update && apt-get install -y inkscape \ && rm -rf /var/lib/apt/lists/* && apt-get clean ####################