diff --git a/.eslintrc.js b/.eslintrc.js index 4860e5898..7ade414c8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -29,6 +29,7 @@ module.exports = { '@typescript-eslint', 'react', 'react-hooks', + 'sort-destructure-keys' // 'jest' ], rules: { @@ -42,7 +43,9 @@ module.exports = { }], 'arrow-body-style': 'off', 'arrow-parens': 'off', - 'camelcase': 'warn', + 'camelcase': ['warn', { + allow: ["^UNSAFE_", "doc_count", "^active_"], + }], 'comma-dangle': ['warn', 'always-multiline'], 'func-names': ['warn', 'as-needed'], 'function-paren-newline': ['warn', 'consistent'], @@ -88,6 +91,9 @@ module.exports = { commentPattern: 'break[\\s\\w]*omitted', }], 'no-nested-ternary': 'off', + 'no-unused-expressions': ['warn', { + allowShortCircuit: true, + }], 'no-var': 'error', // Must use const or let. 'object-property-newline': ['warn', { // allowAllPropertiesOnSameLine: false, @@ -173,6 +179,9 @@ module.exports = { 'react/sort-comp': 'warn', 'react/sort-prop-types': 'error', 'react/prop-types': 'off', // Disable prop-types as TS is used for type checking. + 'sort-destructure-keys/sort-destructure-keys': ['warn', { + caseSensitive: false, + }], '@typescript-eslint/explicit-function-return-type': 'off', // Allows functional components, should be fixed soon: https://github.com/typescript-eslint/typescript-eslint/issues/149 '@typescript-eslint/explicit-member-accessibility': 'off', // Allows not having to set public/private on class properties. }, diff --git a/.gitignore b/.gitignore index 61cf30ef2..aa5d4d0a0 100755 --- a/.gitignore +++ b/.gitignore @@ -3,20 +3,25 @@ logs *.log npm-debug.log* lerna-debug.log* +yarn-debug.log* yarn-error.log* *.swp # Runtime data pids +.env.local +.env.development.local +.env.test.local +.env.production.local *.pid *.seed -# Coverage directory used by tools like istanbul +# Testing coverage -# Dependency directories -/node_modules -/jspm_packages +# Dependencies +node_modules +jspm_packages # Optional npm cache directory .npm @@ -32,10 +37,13 @@ coverage *.iml .vscode/chrome -# build folders +# production folders dist build # OS .DS_Store -__generated__ \ No newline at end of file +__generated__ + +#OncoJS development +/src/packages/@oncojs diff --git a/config-overrides.js b/config-overrides.js index 032628e7d..7ba9956cc 100644 --- a/config-overrides.js +++ b/config-overrides.js @@ -1,21 +1,29 @@ -const { injectBabelPlugin } = require("react-app-rewired"); +const { injectBabelPlugin } = require('react-app-rewired'); module.exports = function override(config, env) { config = injectBabelPlugin( [ - "import-inspector", + 'import-inspector', { serverSideRequirePath: false, - webpackRequireWeakId: true - } + webpackRequireWeakId: true, + }, ], config ); config = injectBabelPlugin( - ["relay", { compat: true, schema: "data/schema.graphql" }], + [ + 'relay', + { + compat: true, + schema: 'data/schema.graphql', + }, + ], config ); + env === 'development' && (config.devtool = 'eval-source-map'); + return config; }; diff --git a/package-lock.json b/package-lock.json index 4c0b19ef6..2beae2cfa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,22 @@ "@babel/highlight": "^7.0.0" } }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "requires": { + "@babel/types": "^7.0.0" + } + }, "@babel/highlight": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", @@ -76,6 +92,41 @@ } } }, + "@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + } + } + }, + "@emotion/is-prop-valid": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz", + "integrity": "sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA==", + "requires": { + "@emotion/memoize": "0.7.1" + } + }, + "@emotion/memoize": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.1.tgz", + "integrity": "sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==" + }, + "@emotion/unitless": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.3.tgz", + "integrity": "sha512-4zAPlpDEh2VwXswwr/t8xGNDGg8RQiPxtxZ3qQEXyQsBV39ptTdESCjuBvGze1nLMVrxmTIKmnO/nAV8Tqjjzg==" + }, "@jephuff/canvg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@jephuff/canvg/-/canvg-1.0.0.tgz", @@ -85,6 +136,42 @@ "stackblur": "^1.0.0" } }, + "@oncojs/boxplot": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@oncojs/boxplot/-/boxplot-0.2.0.tgz", + "integrity": "sha512-upYkFy0lqw95H1rbH8eLj2BXyk6ybH4A+IAmhWa+fJWx/BaRGDlbld1kAv1Lqm2RrZDfNo7pijY/i32muJFxKg==", + "requires": { + "d3-axis": "1.0.12", + "d3-scale": "3.0.0", + "d3-selection": "1.4.0", + "react-resize-detector": "4.1.3", + "styled-components": "4.2.0" + }, + "dependencies": { + "d3-axis": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz", + "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==" + }, + "d3-scale": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.0.0.tgz", + "integrity": "sha512-ktic5HBFlAZj2CN8CCl/p/JyY8bMQluN7+fA6ICE6yyoMOnSQAZ1Bb8/5LcNpNKMBMJge+5Vv4pWJhARYlQYFw==", + "requires": { + "d3-array": "^1.2.0 || 2", + "d3-format": "1", + "d3-interpolate": "1", + "d3-time": "1", + "d3-time-format": "2" + } + }, + "d3-selection": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.0.tgz", + "integrity": "sha512-EYVwBxQGEjLCKF2pJ4+yrErskDnz5v403qvAid96cNdCMr8rmCYfY5RGzWz24mdIbxmDf6/4EAH+K9xperD5jg==" + } + } + }, "@oncojs/react-lolliplot": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/@oncojs/react-lolliplot/-/react-lolliplot-0.11.1.tgz", @@ -351,7 +438,7 @@ }, "@types/filesize": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@types/filesize/-/filesize-3.6.0.tgz", + "resolved": "http://registry.npmjs.org/@types/filesize/-/filesize-3.6.0.tgz", "integrity": "sha512-rOWxCKMjt2DBuwddUnl5GOpf/jAkkqteB+XldncpVxVX+HPTmK2c5ACMOVEbp9gaH81IlhTdC3TwvRa5nopasw==" }, "@types/geojson": { @@ -366,7 +453,7 @@ }, "@types/json5": { "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "resolved": "http://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, @@ -430,6 +517,14 @@ "@types/react-icon-base": "*" } }, + "@types/react-outside-click-handler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/react-outside-click-handler/-/react-outside-click-handler-1.2.0.tgz", + "integrity": "sha512-yejuPUAzmlMmFuPGPYY1nxKj9NI7nn8qaCsyK1hte+Qy488+1d49+tVXDOP/N4mHFN+UjNt8HXQpIyVpRDI/YQ==", + "requires": { + "@types/react": "*" + } + }, "@types/react-redux": { "version": "6.0.9", "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-6.0.9.tgz", @@ -727,7 +822,7 @@ }, "ansi-regex": { "version": "0.2.1", - "resolved": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=" }, "ansi-styles": { @@ -1054,7 +1149,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { "ansi-styles": "^2.2.1", @@ -1079,7 +1174,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -1338,7 +1433,7 @@ }, "babel-plugin-istanbul": { "version": "4.1.6", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", + "resolved": "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", "integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==", "dev": true, "requires": { @@ -1365,6 +1460,17 @@ "graphql": "^0.10.5" } }, + "babel-plugin-styled-components": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.0.tgz", + "integrity": "sha512-sQVKG8irFXx14ZfaK1bBePirfkacl3j8nZwSZK+ZjsbnadRHKQTbhXbe/RB1vT6Vgkz45E+V95LBq4KqdhZUNw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-module-imports": "^7.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.10" + } + }, "babel-plugin-syntax-async-functions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", @@ -1404,8 +1510,7 @@ "babel-plugin-syntax-jsx": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", - "dev": true + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" }, "babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", @@ -2390,7 +2495,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { @@ -2624,6 +2729,11 @@ } } }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + }, "caniuse-api": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", @@ -2688,7 +2798,7 @@ }, "chalk": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", "requires": { "ansi-styles": "^1.1.0", @@ -2793,7 +2903,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -2815,7 +2925,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -2911,7 +3021,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -3017,7 +3127,7 @@ }, "commander": { "version": "2.6.0", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.6.0.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=" }, "commondir": { @@ -3217,7 +3327,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -3263,7 +3373,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { @@ -3276,7 +3386,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { @@ -3334,6 +3444,11 @@ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", "dev": true }, + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" + }, "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", @@ -3342,7 +3457,7 @@ }, "css-in-js-utils": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", + "resolved": "http://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==", "requires": { "hyphenate-style-name": "^1.0.2", @@ -3385,7 +3500,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -3427,7 +3542,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -3472,6 +3587,16 @@ } } }, + "css-to-react-native": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.1.tgz", + "integrity": "sha512-yO+oEx1Lf+hDKasqQRVrAvzMCz825Huh1VMlEEDlRWyAhFb/FWb6I0KpEF1PkyKQ7NEdcx9d5M2ZEWgJAsgPvQ==", + "requires": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^3.3.0" + } + }, "css-what": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.2.tgz", @@ -3562,7 +3687,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -3604,7 +3729,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -3927,9 +4052,9 @@ } }, "damerau-levenshtein": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz", - "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", + "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==", "dev": true }, "dashdash": { @@ -4152,7 +4277,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { @@ -4200,6 +4325,14 @@ "esutils": "^2.0.2" } }, + "document.contains": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/document.contains/-/document.contains-1.0.1.tgz", + "integrity": "sha512-A1KqlZq1w605bwiiLqVZehWE9S9UYlUXPoduFWi64pNVNQ9vy6wwH/7BS+iEfSlF1YyZgcg5PZw5HqDi7FCrUw==", + "requires": { + "define-properties": "^1.1.3" + } + }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -4721,9 +4854,9 @@ "dev": true }, "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, "has-flag": { @@ -4948,9 +5081,9 @@ } }, "resolve": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", - "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -4981,18 +5114,18 @@ } }, "eslint-plugin-react": { - "version": "7.12.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz", - "integrity": "sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.13.0.tgz", + "integrity": "sha512-uA5LrHylu8lW/eAH3bEQe9YdzpPaFd9yAJTwTi/i/BKTD7j6aQMKVAdGM/ML72zD6womuSK7EiGtMKuK06lWjQ==", "dev": true, "requires": { "array-includes": "^3.0.3", "doctrine": "^2.1.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.0.1", + "jsx-ast-utils": "^2.1.0", "object.fromentries": "^2.0.0", - "prop-types": "^15.6.2", - "resolve": "^1.9.0" + "prop-types": "^15.7.2", + "resolve": "^1.10.1" }, "dependencies": { "doctrine": { @@ -5016,9 +5149,9 @@ } }, "resolve": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", - "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -5032,6 +5165,15 @@ "integrity": "sha512-lHBVRIaz5ibnIgNG07JNiAuBUeKhEf8l4etNx5vfAEwqQ5tcuK3jV9yjmopPgQDagQb7HwIuQVsE3IVcGrRnag==", "dev": true }, + "eslint-plugin-sort-destructure-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sort-destructure-keys/-/eslint-plugin-sort-destructure-keys-1.3.0.tgz", + "integrity": "sha512-tZZhhCnuKOxJPvlNWrdPzvdxHXy1ayK98XfYIK3vgKBkfXQg8PYICmnjEDYGouB5NH5kotI34xohdXpReZQ76w==", + "dev": true, + "requires": { + "natural-compare-lite": "^1.4.0" + } + }, "eslint-restricted-globals": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", @@ -5211,7 +5353,7 @@ }, "expect": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/expect/-/expect-22.4.3.tgz", "integrity": "sha512-XcNXEPehqn8b/jm8FYotdX0YrXn36qp4HWlrVT4ktwQas1l1LPxiVWncYnnL2eyMtKAmVIaG0XAp0QlrqJaxaA==", "dev": true, "requires": { @@ -5257,7 +5399,7 @@ }, "jest-diff": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-diff/-/jest-diff-22.4.3.tgz", "integrity": "sha512-/QqGvCDP5oZOF6PebDuLwrB2BMD8ffJv6TAGAdEVuDx1+uEgrHpSFrfrOiMRx2eJ1hgNjlQrOQEHetVwij90KA==", "dev": true, "requires": { @@ -5269,7 +5411,7 @@ }, "jest-matcher-utils": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz", "integrity": "sha512-lsEHVaTnKzdAPR5t4B6OcxXo9Vy4K+kRRbG5gtddY8lBEC+Mlpvm1CJcsMESRjzUhzkz568exMV1hTB76nAKbA==", "dev": true, "requires": { @@ -5280,7 +5422,7 @@ }, "jest-message-util": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz", "integrity": "sha512-iAMeKxhB3Se5xkSjU0NndLLCHtP4n+GtCqV0bISKA5dmOXQfEbdEmYiu2qpnWBDCQdEafNDDU6Q+l6oBMd/+BA==", "dev": true, "requires": { @@ -5293,13 +5435,13 @@ }, "jest-regex-util": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.4.3.tgz", "integrity": "sha512-LFg1gWr3QinIjb8j833bq7jtQopiwdAs67OGfkPrvy7uNUbVMfTXXcOKXJaeY5GgjobELkKvKENqq1xrUectWg==", "dev": true }, "pretty-format": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz", "integrity": "sha512-S4oT9/sT6MN7/3COoOy+ZJeA92VmOnveLHgrwBE3Z1W5N9S2A1QGNYiE1z75DAENbJrXXUb+OWXhpJcg05QKQQ==", "dev": true, "requires": { @@ -5396,7 +5538,7 @@ }, "external-editor": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", "dev": true, "requires": { @@ -5892,7 +6034,7 @@ }, "finalhandler": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "dev": true, "requires": { @@ -6050,7 +6192,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -6072,7 +6214,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -6173,8 +6315,8 @@ "dev": true, "optional": true, "requires": { - "nan": "2.11.1", - "node-pre-gyp": "0.10.0" + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" }, "dependencies": { "abbrev": { @@ -6184,16 +6326,12 @@ "optional": true }, "ansi-regex": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true + "version": "2.1.1", + "bundled": true }, "ansi-styles": { "version": "2.2.1", - "bundled": true, - "dev": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -6219,7 +6357,7 @@ "bundled": true, "optional": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -6228,26 +6366,16 @@ "bundled": true, "dev": true, "optional": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, "dependencies": { "supports-color": { "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true + "bundled": true } } }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", @@ -6262,8 +6390,7 @@ }, "core-util-is": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "debug": { "version": "2.6.9", @@ -6271,13 +6398,13 @@ "dev": true, "optional": true, "requires": { - "ms": "0.7.1" + "ms": "2.0.0" }, "dependencies": { "ms": { - "version": "0.7.1", - "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true, "optional": true } @@ -6305,7 +6432,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "fs.realpath": { @@ -6319,14 +6446,14 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" }, "dependencies": { "object-assign": { @@ -6364,8 +6491,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6382,7 +6507,7 @@ "dev": true, "optional": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": "^2.1.0" } }, "ignore-walk": { @@ -6391,7 +6516,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.4" } }, "inflight": { @@ -6399,14 +6524,13 @@ "bundled": true, "optional": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { "version": "2.0.3", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -6417,22 +6541,20 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "isarray": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "minimatch": { "version": "3.0.4", "bundled": true, "optional": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -6447,8 +6569,8 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" } }, "minizlib": { @@ -6457,7 +6579,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "mkdirp": { @@ -6479,9 +6601,9 @@ "dev": true, "optional": true, "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, "node-pre-gyp": { @@ -6490,16 +6612,16 @@ "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } }, "nopt": { @@ -6508,8 +6630,8 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npm-bundled": { @@ -6524,8 +6646,8 @@ "dev": true, "optional": true, "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, "npmlog": { @@ -6534,10 +6656,10 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" }, "dependencies": { "are-we-there-yet": { @@ -6555,8 +6677,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.0", @@ -6567,7 +6688,7 @@ "bundled": true, "optional": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "osenv": { @@ -6576,8 +6697,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -6591,8 +6712,7 @@ }, "process-nextick-args": { "version": "2.0.0", - "bundled": true, - "optional": true + "bundled": true }, "rc": { "version": "1.2.7", @@ -6600,10 +6720,10 @@ "dev": true, "optional": true, "requires": { - "deep-extend": "0.5.1", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -6625,13 +6745,13 @@ "version": "2.3.6", "bundled": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "rimraf": { @@ -6640,7 +6760,7 @@ "dev": true, "optional": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" }, "dependencies": { "glob": { @@ -6698,24 +6818,23 @@ "version": "1.0.2", "bundled": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { "version": "1.1.1", "bundled": true, - "optional": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { "version": "3.0.1", "bundled": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" }, "dependencies": { "ansi-regex": { @@ -6739,19 +6858,18 @@ "dev": true, "optional": true, "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" } }, "util-deprecate": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "wide-align": { "version": "1.1.2", @@ -6802,7 +6920,7 @@ }, "get-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, @@ -6941,7 +7059,7 @@ }, "got": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz", "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { @@ -7311,7 +7429,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { @@ -8190,7 +8308,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -8250,7 +8368,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -8303,7 +8421,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -8325,7 +8443,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -8366,7 +8484,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -8388,7 +8506,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -8527,7 +8645,7 @@ }, "jest-get-type": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", "dev": true }, @@ -8576,7 +8694,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -8598,7 +8716,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -8637,7 +8755,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -8659,7 +8777,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -8711,7 +8829,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -8733,7 +8851,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -8817,7 +8935,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -8839,7 +8957,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -8888,7 +9006,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -8910,7 +9028,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -8954,7 +9072,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -8976,7 +9094,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -9017,7 +9135,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -9039,7 +9157,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -9630,6 +9748,11 @@ "mimic-fn": "^1.0.0" } }, + "memoize-one": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.0.4.tgz", + "integrity": "sha512-P0z5IeAH6qHHGkJIXWw0xC2HNEgkx/9uWWBQw64FJj3/ol14VYdfVGWWr0fXfjhhv3TKVIqUq65os6O4GUNksA==" + }, "memoizee": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.5.tgz", @@ -9675,7 +9798,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -9777,7 +9900,7 @@ }, "minimist": { "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mississippi": { @@ -9924,6 +10047,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha1-F7CVgZiJef3a/gIB6TG6kzyWy7Q=", + "dev": true + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -10745,7 +10874,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -10787,7 +10916,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -10830,7 +10959,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -10872,7 +11001,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -10905,7 +11034,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -10947,7 +11076,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -10979,7 +11108,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11021,7 +11150,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11053,7 +11182,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11095,7 +11224,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11127,7 +11256,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11169,7 +11298,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11201,7 +11330,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11243,7 +11372,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11276,7 +11405,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11318,7 +11447,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11350,7 +11479,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11392,7 +11521,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11479,7 +11608,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11521,7 +11650,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11553,7 +11682,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11595,7 +11724,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11641,7 +11770,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11683,7 +11812,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11723,7 +11852,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11765,7 +11894,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11798,7 +11927,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11840,7 +11969,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11875,7 +12004,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -11926,7 +12055,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -11961,7 +12090,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -12003,7 +12132,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -12074,7 +12203,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -12116,7 +12245,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -12151,7 +12280,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -12193,7 +12322,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -12226,7 +12355,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -12268,7 +12397,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -12301,7 +12430,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -12343,7 +12472,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -12375,7 +12504,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -12417,7 +12546,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -12451,7 +12580,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -12493,7 +12622,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -12539,7 +12668,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -12581,7 +12710,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -12615,7 +12744,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -12657,7 +12786,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -12669,8 +12798,7 @@ "postcss-value-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" }, "postcss-zindex": { "version": "2.2.0", @@ -12697,7 +12825,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -12739,7 +12867,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -12991,6 +13119,11 @@ "performance-now": "^2.1.0" } }, + "raf-schd": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.0.tgz", + "integrity": "sha512-m7zq0JkIrECzw9mO5Zcq6jN4KayE34yoIS9hJoiZNXyOAT06PPA8PrR+WtJIeFW09YjUfNkMMN9lrmAt6BURCA==" + }, "randomatic": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", @@ -13117,7 +13250,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -13235,7 +13368,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -13263,7 +13396,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -13355,8 +13488,7 @@ "react-is": { "version": "16.8.6", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", - "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==", - "dev": true + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" }, "react-lifecycles-compat": { "version": "3.0.4", @@ -13413,6 +13545,69 @@ "moment": ">=1.6.0" } }, + "react-outside-click-handler": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/react-outside-click-handler/-/react-outside-click-handler-1.2.3.tgz", + "integrity": "sha512-4orkx59ais0mM/j1Ekc5ewyRu5xNLX4a6pMs7RT8U7JkbPOlRsucE+190kXzYUUHsGfZvyAmsdQkL7lpqzMGBg==", + "requires": { + "airbnb-prop-types": "^2.12.0", + "consolidated-events": "^1.1.1 || ^2.0.0", + "document.contains": "^1.0.0", + "object.values": "^1.1.0", + "prop-types": "^15.7.2" + }, + "dependencies": { + "airbnb-prop-types": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.13.2.tgz", + "integrity": "sha512-2FN6DlHr6JCSxPPi25EnqGaXC4OC3/B3k1lCd6MMYrZ51/Gf/1qDfaR+JElzWa+Tl7cY2aYOlsYJGFeQyVHIeQ==", + "requires": { + "array.prototype.find": "^2.0.4", + "function.prototype.name": "^1.1.0", + "has": "^1.0.3", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0", + "prop-types": "^15.7.2", + "prop-types-exact": "^1.2.0", + "react-is": "^16.8.6" + } + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, "react-portal": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/react-portal/-/react-portal-3.2.0.tgz", @@ -13464,6 +13659,30 @@ "resolved": "https://registry.npmjs.org/react-relay-network-layer/-/react-relay-network-layer-2.0.1.tgz", "integrity": "sha1-bbkbGZ90cz6YDQd27G+nlh4BVNA=" }, + "react-resize-detector": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-4.1.3.tgz", + "integrity": "sha512-tzVDVFxhUVdTjxyR1OqNggkbFAA7srawgwhcm4XQjyGq/R8M13MiceI+4C7xfzHqaKk0Oq7ErIXexGGSgQEKcQ==", + "requires": { + "lodash": "^4.17.11", + "lodash-es": "^4.17.11", + "prop-types": "^15.7.2", + "raf-schd": "^4.0.0", + "resize-observer-polyfill": "^1.5.1" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, "react-router": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", @@ -13570,7 +13789,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -13607,7 +13826,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -13842,7 +14061,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -14472,7 +14691,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -14494,7 +14713,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -14573,7 +14792,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -14680,6 +14899,11 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", @@ -14816,9 +15040,9 @@ } }, "rxjs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.1.tgz", - "integrity": "sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -14877,7 +15101,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -15064,7 +15288,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { @@ -15122,6 +15346,11 @@ "integrity": "sha1-HdrOSYF5j5O9gzlzgD2A1S6TrWo=", "dev": true }, + "simple-statistics": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/simple-statistics/-/simple-statistics-7.0.2.tgz", + "integrity": "sha512-wqTjlmbiaL6Fqaw28tSjQrthjxVV17MMfi/H/qvE0jAvtLspB2S7gEtcR27uvhSRAa64LhjhoO169rX8sFW3pg==" + }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -15566,7 +15795,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -15614,7 +15843,7 @@ }, "strip-ansi": { "version": "0.3.0", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", "requires": { "ansi-regex": "^0.2.1" @@ -15673,6 +15902,49 @@ "schema-utils": "^0.3.0" } }, + "styled-components": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.2.0.tgz", + "integrity": "sha512-L/LzkL3ZbBhqIVHdR7DbYujy4tqvTNRfc+4JWDCYyhTatI+8CRRQUmdaR0+ARl03DWsfKLhjewll5uNLrqrl4A==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/is-prop-valid": "^0.7.3", + "@emotion/unitless": "^0.7.0", + "babel-plugin-styled-components": ">= 1", + "css-to-react-native": "^2.2.2", + "memoize-one": "^5.0.0", + "prop-types": "^15.5.4", + "react-is": "^16.6.0", + "stylis": "^3.5.0", + "stylis-rule-sheet": "^0.0.10", + "supports-color": "^5.5.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "stylis": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", + "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" + }, + "stylis-rule-sheet": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", + "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==" + }, "subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", @@ -15684,7 +15956,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -15763,9 +16035,9 @@ "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" }, "table": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz", - "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/table/-/table-5.3.3.tgz", + "integrity": "sha512-3wUNCgdWX6PNpOe3amTTPWPuF6VGvgzjKCaO1snFj0z7Y3mUPWf5+zDtxUVGispJkDECPmR29wbzh6bVMOHbcw==", "dev": true, "requires": { "ajv": "^6.9.1", @@ -16177,7 +16449,7 @@ }, "jest-diff": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-diff/-/jest-diff-22.4.3.tgz", "integrity": "sha512-/QqGvCDP5oZOF6PebDuLwrB2BMD8ffJv6TAGAdEVuDx1+uEgrHpSFrfrOiMRx2eJ1hgNjlQrOQEHetVwij90KA==", "dev": true, "requires": { @@ -16189,7 +16461,7 @@ }, "jest-environment-jsdom": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz", "integrity": "sha512-FviwfR+VyT3Datf13+ULjIMO5CSeajlayhhYQwpzgunswoaLIPutdbrnfUHEMyJCwvqQFaVtTmn9+Y8WCt6n1w==", "dev": true, "requires": { @@ -16200,7 +16472,7 @@ }, "jest-environment-node": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-environment-node/-/jest-environment-node-22.4.3.tgz", "integrity": "sha512-reZl8XF6t/lMEuPWwo9OLfttyC26A5AMgDyEQ6DBgZuyfyeNUzYT8BFo6uxCCP/Av/b7eb9fTi3sIHFPBzmlRA==", "dev": true, "requires": { @@ -16229,7 +16501,7 @@ }, "jest-matcher-utils": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz", "integrity": "sha512-lsEHVaTnKzdAPR5t4B6OcxXo9Vy4K+kRRbG5gtddY8lBEC+Mlpvm1CJcsMESRjzUhzkz568exMV1hTB76nAKbA==", "dev": true, "requires": { @@ -16240,7 +16512,7 @@ }, "jest-message-util": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz", "integrity": "sha512-iAMeKxhB3Se5xkSjU0NndLLCHtP4n+GtCqV0bISKA5dmOXQfEbdEmYiu2qpnWBDCQdEafNDDU6Q+l6oBMd/+BA==", "dev": true, "requires": { @@ -16253,19 +16525,19 @@ }, "jest-mock": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-mock/-/jest-mock-22.4.3.tgz", "integrity": "sha512-+4R6mH5M1G4NK16CKg9N1DtCaFmuxhcIqF4lQK/Q1CIotqMs/XBemfpDPeVZBFow6iyUNu6EBT9ugdNOTT5o5Q==", "dev": true }, "jest-regex-util": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.4.3.tgz", "integrity": "sha512-LFg1gWr3QinIjb8j833bq7jtQopiwdAs67OGfkPrvy7uNUbVMfTXXcOKXJaeY5GgjobELkKvKENqq1xrUectWg==", "dev": true }, "jest-resolve": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-resolve/-/jest-resolve-22.4.3.tgz", "integrity": "sha512-u3BkD/MQBmwrOJDzDIaxpyqTxYH+XqAXzVJP51gt29H8jpj3QgKof5GGO2uPGKGeA1yTMlpbMs1gIQ6U4vcRhw==", "dev": true, "requires": { @@ -16275,7 +16547,7 @@ }, "jest-snapshot": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-snapshot/-/jest-snapshot-22.4.3.tgz", "integrity": "sha512-JXA0gVs5YL0HtLDCGa9YxcmmV2LZbwJ+0MfyXBBc5qpgkEYITQFJP7XNhcHFbUvRiniRpRbGVfJrOoYhhGE0RQ==", "dev": true, "requires": { @@ -16289,7 +16561,7 @@ }, "jest-util": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/jest-util/-/jest-util-22.4.3.tgz", "integrity": "sha512-rfDfG8wyC5pDPNdcnAlZgwKnzHvZDu8Td2NJI/jAGKEGxJPYiE4F0ss/gSAkG4778Y23Hvbz+0GMrDJTeo7RjQ==", "dev": true, "requires": { @@ -16337,7 +16609,7 @@ }, "pretty-format": { "version": "22.4.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz", + "resolved": "http://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz", "integrity": "sha512-S4oT9/sT6MN7/3COoOy+ZJeA92VmOnveLHgrwBE3Z1W5N9S2A1QGNYiE1z75DAENbJrXXUb+OWXhpJcg05QKQQ==", "dev": true, "requires": { @@ -16791,7 +17063,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -17994,7 +18266,7 @@ }, "load-json-file": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { @@ -18080,7 +18352,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -18575,7 +18847,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -18686,7 +18958,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -18939,7 +19211,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { diff --git a/package.json b/package.json index b881fe40f..550822e5e 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "1.21.0", + "version": "1.22.0", "repository": "NCI-GDC/portal-ui", "name": "portal-ui", "author": { @@ -25,6 +25,7 @@ } }, "dependencies": { + "@oncojs/boxplot": "0.2.0", "@oncojs/react-lolliplot": "0.11.1", "@oncojs/sapien": "0.5.2", "@oncojs/survivalplot": "0.8.2", @@ -37,6 +38,7 @@ "@types/react": "16.4.18", "@types/react-dom": "16.0.9", "@types/react-icons": "2.2.6", + "@types/react-outside-click-handler": "1.2.0", "@types/react-redux": "6.0.9", "@types/react-relay": "1.3.9", "@types/react-router-dom": "4.3.1", @@ -80,6 +82,7 @@ "react-loadable": "4.0.2", "react-markdown": "3.0.1", "react-modal": "3.0.0", + "react-outside-click-handler": "1.2.3", "react-progress": "0.0.12", "react-redux": "5.0.4", "react-relay": "1.3.0", @@ -93,18 +96,20 @@ "redux-api-middleware": "2.0.0-beta.2", "redux-persist": "5.9.1", "redux-thunk": "2.2.0", + "simple-statistics": "7.0.2", "url-join": "1.1.0" }, "devDependencies": { "babel-plugin-import-inspector": "2.0.0", "babel-plugin-relay": "1.3.0", "babel-plugin-transform-export-extensions": "6.22.0", - "eslint": "5.16.0", - "eslint-config-airbnb": "17.1.0", - "eslint-plugin-import": "2.17.2", - "eslint-plugin-jsx-a11y": "6.2.1", - "eslint-plugin-react": "7.12.4", - "eslint-plugin-react-hooks": "1.6.0", + "eslint": "^5.16.0", + "eslint-config-airbnb": "^17.1.0", + "eslint-plugin-import": "^2.17.2", + "eslint-plugin-jsx-a11y": "^6.2.1", + "eslint-plugin-react": "^7.13.0", + "eslint-plugin-react-hooks": "^1.6.0", + "eslint-plugin-sort-destructure-keys": "^1.3.0", "flow-bin": "0.61.0", "react-app-rewired": "1.6.2", "react-scripts-ts": "3.1.0", diff --git a/public/gdc-templates.js b/public/gdc-templates.js index 3ae7b3af1..7ae58a535 100644 --- a/public/gdc-templates.js +++ b/public/gdc-templates.js @@ -369,7 +369,7 @@ try { } module.run(['$templateCache', function($templateCache) { $templateCache.put('home/templates/home.html', - '

Harmonized Cancer Datasets

Genomic Data Commons Data Portal

Get Started by Exploring:
Perform Advanced Search Queries, such as:
Projects
Primary Site
Cases
Files

Infrastructure

Data is continuously being processed and harmonized by the GDC.
View GDC system statistics:

Compute Infrastructure12,800 Cores87.96 TB RAM
Storage Infrastructure4.98 PB Used5.42 PB Total
View Data Download Statistics Report

GDC Applications

The GDC Data Portal is a robust data-driven platform that allows cancer researchers and bioinformaticians to search and download cancer data for analysis. The GDC applications include:
 
'); + '

Harmonized Cancer Datasets

Genomic Data Commons Data Portal

Get Started by Exploring:
Perform Advanced Search Queries, such as:
Projects
Primary Site
Cases
Files

Infrastructure

Data is continuously being processed and harmonized by the GDC.
View GDC system statistics:

Compute Infrastructure12,800 Cores87.96 TB RAM
Storage Infrastructure4.98 PB Used5.42 PB Total
View Data Download Statistics Report

GDC Applications

The GDC Data Portal is a robust data-driven platform that allows cancer researchers and bioinformaticians to search and download cancer data for analysis. The GDC applications include:
 
'); }]); })(); @@ -838,7 +838,7 @@ try { } module.run(['$templateCache', function($templateCache) { $templateCache.put('components/header/templates/header.html', - ''); + ''); }]); })(); diff --git a/pull_request_template.md b/pull_request_template.md new file mode 100644 index 000000000..715381391 --- /dev/null +++ b/pull_request_template.md @@ -0,0 +1,11 @@ +## Ticket Number + +e.g. PRTL-0000 + +## Environment to be used in testing + +- [ ] `prod` +- [ ] `dev-oicr` +- [ ] `qa` (which version?) + +## Description of Changes diff --git a/src/packages/@ncigdc/components/Aggregations/FacetHeader.js b/src/packages/@ncigdc/components/Aggregations/FacetHeader.js index 597be6885..51d289514 100644 --- a/src/packages/@ncigdc/components/Aggregations/FacetHeader.js +++ b/src/packages/@ncigdc/components/Aggregations/FacetHeader.js @@ -1,7 +1,11 @@ /* @flow */ import React from 'react'; -import { compose, defaultProps } from 'recompose'; +import { + compose, + defaultProps, + setDisplayName, +} from 'recompose'; import { css } from 'glamor'; import { parseFilterParam } from '@ncigdc/utils/uri'; @@ -53,6 +57,7 @@ const MagnifyingGlass = styled(SearchIcon, { }); const FacetHeader = compose( + setDisplayName('EnhancedFacetHeader'), defaultProps({ handleRequestRemove: () => {}, isRemovable: false, @@ -61,16 +66,16 @@ const FacetHeader = compose( }), )( ({ - field, - title, + collapsed, description, - isRemovable, + field, handleRequestRemove, - collapsed, + hasValueSearch, + isRemovable, setCollapsed, - showingValueSearch, setShowingValueSearch, - hasValueSearch, + showingValueSearch, + title, }) => ( {(ctx: { pathname: string, query: IRawQuery }) => { @@ -79,15 +84,15 @@ const FacetHeader = compose( return (
setCollapsed(!collapsed)} - > + style={{ cursor: 'pointer' }} + > + /> {title} @@ -95,25 +100,24 @@ const FacetHeader = compose( + > )} {hasValueSearch && ( setShowingValueSearch(!showingValueSearch)} - /> + /> )} - + {isRemovable && ( - event.key === 'Enter' && handleRequestRemove()} + onKeyPress={event => event.key === 'Enter' && handleRequestRemove()} role="button" tabIndex="0" - aria-label="Close" - /> + /> )}
diff --git a/src/packages/@ncigdc/components/Aggregations/SuggestionFacet.js b/src/packages/@ncigdc/components/Aggregations/SuggestionFacet.js index d41c52796..0a0087037 100644 --- a/src/packages/@ncigdc/components/Aggregations/SuggestionFacet.js +++ b/src/packages/@ncigdc/components/Aggregations/SuggestionFacet.js @@ -3,7 +3,14 @@ // Vendor import React from 'react'; import _ from 'lodash'; -import { compose, pure, withState, withHandlers, renameProp } from 'recompose'; +import { + compose, + pure, + renameProp, + setDisplayName, + withHandlers, + withState, +} from 'recompose'; import SearchIcon from 'react-icons/lib/fa/search'; import LocationSubscriber from '@ncigdc/components/LocationSubscriber'; @@ -24,7 +31,7 @@ import Input from '@ncigdc/uikit/Form/Input'; import SetId from '@ncigdc/components/SetId'; import Hidden from '@ncigdc/components/Hidden'; -import { Container, CheckedRow, CheckedLink } from './'; +import { Container, CheckedRow, CheckedLink } from '.'; const MagnifyingGlass = styled(SearchIcon, { backgroundColor: ({ theme }) => theme.greyScale5, @@ -49,29 +56,26 @@ const StyledDropdownLink = styled(Link, { color: ({ theme }) => theme.greyScale2, ':link': { textDecoration: 'none', - color: ({ theme, linkIsActive }) => - linkIsActive ? 'white' : theme.primary, + color: ({ linkIsActive, theme }) => (linkIsActive ? 'white' : theme.primary), }, ':visited': { textDecoration: 'none', - color: ({ theme, linkIsActive }) => - linkIsActive ? 'white' : theme.primary, + color: ({ linkIsActive, theme }) => (linkIsActive ? 'white' : theme.primary), }, - backgroundColor: ({ linkIsActive }) => - linkIsActive ? 'rgb(31, 72, 108)' : 'inherit', + backgroundColor: ({ linkIsActive }) => (linkIsActive ? 'rgb(31, 72, 108)' : 'inherit'), width: '100%', textDecoration: 'none', }); const SuggestionFacet = compose( + setDisplayName('EnhancedSuggestionFacet'), withDropdown, withState('inputValue', 'setInputValue', ''), withState('isLoading', 'setIsLoading', false), renameProp('hits', 'results'), withHandlers({ // TODO: use router push - handleSelectItem: () => item => - document.querySelector(`[data-link-id="${item.id}"]`).click(), + handleSelectItem: () => item => document.querySelector(`[data-link-id="${item.id}"]`).click(), }), namespace( 'selectableList', @@ -88,24 +92,24 @@ const SuggestionFacet = compose( pure, )( ({ - isLoading, - setIsLoading, - selectableList, - dropdownItem, - title, + active, + collapsed, doctype, + dropdownItem, fieldNoDoctype, + inputValue, + isLoading, + mouseDownHandler, + mouseUpHandler, placeholder, results, - setAutocomplete, + selectableList, setActive, - active, - mouseDownHandler, - mouseUpHandler, - collapsed, - style, - inputValue, + setAutocomplete, setInputValue, + setIsLoading, + style, + title, }) => { const query = v => ({ offset: 0, @@ -144,7 +148,7 @@ const SuggestionFacet = compose( dotField: `${doctype}.${fieldNoDoctype}`, }) || { content: { value: [] } }; return ( - + {!collapsed && ( {[].concat(currentValues.content.value || []).map(v => ( @@ -166,7 +170,7 @@ const SuggestionFacet = compose( ], }, }} - > + > {getCheckedValue(v)} @@ -178,44 +182,44 @@ const SuggestionFacet = compose( {title} { - const value = e.target.value; + const { value } = e.target; setInputValue(value); setActive(!!value); - if (!!value) { + if (value) { setIsLoading(true); setAutocomplete( value, - readyState => - _.some([ - readyState.ready, - readyState.aborted, - readyState.error, - ]) && setIsLoading(false), + readyState => _.some([ + readyState.ready, + readyState.aborted, + readyState.error, + ]) && setIsLoading(false), ); } }} onKeyDown={selectableList.handleKeyEvent} placeholder={placeholder} + style={{ borderRadius: '0 4px 4px 0' }} value={inputValue} - aria-activedescendant={ - active - ? _.get( - selectableList, - `focusedItem.${fieldNoDoctype}`, - ) - : null // false gets stringify, so value needs to be `null` or `undefined` - } {...active && { 'aria-owns': `${fieldNoDoctype}-options`, }} - /> + /> {active && ( e.stopPropagation()} style={{ ...dropdown, marginTop: 0, @@ -223,25 +227,24 @@ const SuggestionFacet = compose( width: '300px', wordBreak: 'break-word', }} - onClick={e => e.stopPropagation()} - > + > {(results || []).map(x => ( { setInputValue(''); setActive(false); }} onMouseOver={() => selectableList.setFocusedItem(x)} - > + style={{ alignItems: 'center' }} + > + merge="add" + query={query(x[fieldNoDoctype])} + > {dropdownItem(x, inputValue)} diff --git a/src/packages/@ncigdc/components/Charts/BarChart.js b/src/packages/@ncigdc/components/Charts/BarChart.js index e2290e562..ec292cdb1 100644 --- a/src/packages/@ncigdc/components/Charts/BarChart.js +++ b/src/packages/@ncigdc/components/Charts/BarChart.js @@ -16,7 +16,7 @@ import { withTooltip } from '@ncigdc/uikit/Tooltip'; import withSize from '@ncigdc/utils/withSize'; import './style.css'; -export const DEFAULT_X_AXIS_LABEL_LENGTH = 8; +export const DEFAULT_X_AXIS_LABEL_LENGTH = 10; const BarChart = ({ data, diff --git a/src/packages/@ncigdc/components/DownloadVisualizationButton.js b/src/packages/@ncigdc/components/DownloadVisualizationButton.js index aab8d72c1..90ed9ba33 100644 --- a/src/packages/@ncigdc/components/DownloadVisualizationButton.js +++ b/src/packages/@ncigdc/components/DownloadVisualizationButton.js @@ -65,8 +65,10 @@ const DownloadVisualizationButton = ({ theme, tooltipHTML, disabled, + buttonStyle, ...props -}: TProps) => ( +}: TProps) => { +return ( } - style={visualizingButton} + style={{...visualizingButton, ...buttonStyle}} type="button" > {noText ? ( @@ -178,6 +180,6 @@ const DownloadVisualizationButton = ({ )} -); +)}; export default enhance(DownloadVisualizationButton); diff --git a/src/packages/@ncigdc/components/EntityPageHorizontalTable.js b/src/packages/@ncigdc/components/EntityPageHorizontalTable.js index 56f72fa67..32c8fdcd9 100644 --- a/src/packages/@ncigdc/components/EntityPageHorizontalTable.js +++ b/src/packages/@ncigdc/components/EntityPageHorizontalTable.js @@ -30,7 +30,7 @@ const EntityPageHorizontalTable = ({ rightComponent, headings, data, - emptyMessage, + emptyMessage = 'No valid data to be shown', emptyMessageStyle, theme, tableId, @@ -38,117 +38,128 @@ const EntityPageHorizontalTable = ({ dividerStyle, tableContainerStyle = {}, ...props -}) => ( - - {(title || rightComponent) && ( -

{ + return ( + - {title || } {rightComponent} -

- )} - {!!data.length && ( - ( - - ))} - subheadings={headings.map( - (h, i) => - h.subheadings && - h.subheadings.map((s, j) => ( + {title || } + {' '} + {rightComponent} + + )} + {data.length > 0 + ? ( +
0 ? dividerStyle : {}), - }} + {(title || rightComponent) && ( +

- {h.title} -

+ {data.map((d, k) => ( + + {headings.map((h, i) => [].concat(get(d, h.key, '--')).map((v, j) => ( + + )))} + + ))} + + )} + headings={headings.map((h, i) => ( - )) - )} - body={ - - {data.map((d, k) => ( - - {headings.map((h, i) => - [].concat(get(d, h.key, '--')).map((v, j) => ( - - )) - )} - ))} - - } - /> - )} - {!data.length && ( - - {emptyMessage && ( -

{emptyMessage}

+ id={tableId} + style={styles.table} + subheadings={headings.map( + (h, i) => h.subheadings && + h.subheadings.map((s, j) => ( +
+ )) + )} + /> + ) + : ( + + {emptyMessage && ( +

+ {emptyMessage} +

+ )} +
)} - - )} - -); + + ); +}; export default withTheme(EntityPageHorizontalTable); diff --git a/src/packages/@ncigdc/components/FacetSelection.js b/src/packages/@ncigdc/components/FacetSelection.js index 4a1af17ae..8745a5611 100644 --- a/src/packages/@ncigdc/components/FacetSelection.js +++ b/src/packages/@ncigdc/components/FacetSelection.js @@ -5,12 +5,13 @@ import _ from 'lodash'; import { css } from 'glamor'; import { compose, - withState, + defaultProps, lifecycle, - withProps, renameProps, - defaultProps, + setDisplayName, withHandlers, + withProps, + withState, } from 'recompose'; import { fetchApi } from '@ncigdc/utils/ajax'; import entityShortnameMapping from '@ncigdc/utils/entityShortnameMapping'; @@ -18,10 +19,10 @@ import Highlight from '@ncigdc/uikit/Highlight'; import withSelectableList from '@ncigdc/utils/withSelectableList'; import withPropsOnChange from '@ncigdc/utils/withPropsOnChange'; -const facetMatchesQuery = (facet, query) => - _.some([facet.field, facet.description].map(_.toLower), searchTarget => - _.includes(searchTarget, query), - ); +const facetMatchesQuery = (facet, query) => _.some( + [facet.field, facet.description].map(_.toLower), + searchTarget => _.includes(searchTarget, query), +); const styles = { header: { @@ -107,14 +108,14 @@ const styles = { }; // Highlighting is frustratingly slow with > 100 items -const ConditionalHighlight = ({ condition, search, children }) => - condition ? ( - {children} +const ConditionalHighlight = ({ children, condition, search }) => (condition ? ( + {children} ) : ( {children} - ); + )); export default compose( + setDisplayName('EnhancedFacetSelection'), withState('facetMapping', 'setFacetMapping', {}), withState('query', 'setQuery', ''), withState('focusedFacet', 'setFocusedFacet', null), @@ -126,19 +127,19 @@ export default compose( ), withPropsOnChange( ['isLoadingFacetMapping', 'isLoadingAdditionalFacetData'], - ({ isLoadingFacetMapping, isLoadingAdditionalFacetData }) => ({ + ({ isLoadingAdditionalFacetData, isLoadingFacetMapping }) => ({ isLoading: _.some([isLoadingFacetMapping, isLoadingAdditionalFacetData]), }), ), withState('shouldHideUselessFacets', 'setShouldHideUselessFacets', false), withProps( ({ + docType, + facetMapping, relay, + relayVarName, setIsLoadingAdditionalFacetData, setShouldHideUselessFacets, - facetMapping, - relayVarName, - docType, }) => ({ setUselessFacetVisibility: shouldHideUselessFacets => { setShouldHideUselessFacets(shouldHideUselessFacets); @@ -157,7 +158,11 @@ export default compose( }, readyState => { if ( - _.some([readyState.ready, readyState.aborted, readyState.error]) + _.some([ + readyState.ready, + readyState.aborted, + readyState.error, + ]) ) { setIsLoadingAdditionalFacetData(false); } @@ -169,8 +174,7 @@ export default compose( ), withPropsOnChange( ['isLoadingFacetMapping'], - ({ isLoadingFacetMapping, setUselessFacetVisibility }) => - !isLoadingFacetMapping && + ({ isLoadingFacetMapping, setUselessFacetVisibility }) => !isLoadingFacetMapping && JSON.parse(localStorage.getItem('shouldHideUselessFacets') || 'null') && setUselessFacetVisibility(true), ), @@ -183,8 +187,7 @@ export default compose( setFacetMapping(mapping); setIsLoadingFacetMapping(false); }, - handleQueryInputChange: ({ setQuery }) => event => - setQuery(event.target.value), + handleQueryInputChange: ({ setQuery }) => event => setQuery(event.target.value), }), defaultProps({ excludeFacetsBy: _.noop, @@ -194,8 +197,7 @@ export default compose( withPropsOnChange(['additionalFacetData'], ({ additionalFacetData }) => ({ usefulFacets: _.omitBy( additionalFacetData, - aggregation => - !aggregation || + aggregation => !aggregation || _.some([ aggregation.buckets && aggregation.buckets.filter(bucket => bucket.key !== '_missing') @@ -208,20 +210,18 @@ export default compose( })), withProps( ({ - facetMapping, excludeFacetsBy, + facetMapping, query, shouldHideUselessFacets, usefulFacets, }) => ({ - filteredFacets: _.filter(_.values(facetMapping), facet => - _.every([ - facetMatchesQuery(facet, query), - !excludeFacetsBy(facet), - !shouldHideUselessFacets || + filteredFacets: _.filter(_.values(facetMapping), facet => _.every([ + facetMatchesQuery(facet, query), + !excludeFacetsBy(facet), + !shouldHideUselessFacets || Object.keys(usefulFacets).includes(facet.field), - ]), - ), + ]),), }), ), renameProps({ @@ -229,10 +229,10 @@ export default compose( }), withHandlers({ handleClose: ({ - setQuery, - setFocusedFacet, onRequestClose, relay, + setFocusedFacet, + setQuery, }) => () => { setQuery(''); setFocusedFacet(null); @@ -265,29 +265,29 @@ export default compose( margin: 0, lineHeight: 1.42857143, }} - > + > {props.title} + > Cancel
+ placeholder="search" + type="text" + />

{props.isLoading @@ -295,15 +295,14 @@ export default compose( : `${props.filteredFacets.length} ${props.docType} fields`}

-
0 && j === 0 ? dividerStyle : {}), + }} + > + {h.color && ( +
+ )} + + {v} +
0 && j === 0 ? dividerStyle : {}), + ...(h.thStyle || h.style || {}), + ...(i > 0 ? dividerStyle : {}), }} - > - {s} + > + {h.title}
0 && j === 0 ? dividerStyle : {}), - }} - className={h.className || ''} - > - {h.color && ( -
- )} - {v} -
0 && j === 0 ? dividerStyle : {}), + }} + > + {s} +
UUID, - , - , - , - , - ]} - body={ + body={( {x.treatments.hits.edges.map(({ node }) => ( @@ -238,17 +280,33 @@ export default compose( ))} - } - /> - )} + )} + headings={[ + , + , + , + , + , + ]} + /> + )} {(!x.treatments || !x.treatments.hits.edges.length) && ( -
+
No Treatments Found. -
- )} +
+ )} ))} - /> + tabs={ + diagnoses.length > 1 + ? diagnoses.map(x => ( +

+ {truncate(x.node.diagnosis_id, { length: 11 })} +

+ )) + : [] + } + /> )} {!diagnoses.length && (

No Diagnoses Found.

@@ -259,22 +317,16 @@ export default compose(
{!!familyHistory.length && ( 1 - ? familyHistory.map(x => ( -

- {truncate(x.family_history_id, { length: 11 })} -

- )) - : [] - } + contentStyle={{ border: 'none' }} tabContent={familyHistory.map(x => ( + /> ))} - /> + tabs={ + familyHistory.length > 1 + ? familyHistory.map(x => ( +

+ {truncate(x.family_history_id, { length: 11 })} +

+ )) + : [] + } + /> )} {!familyHistory.length && (

@@ -308,30 +372,49 @@ export default compose(
{!!totalExposures && ( 1 - ? exposures.map(x => ( -

- {truncate(x.node.exposure_id, { length: 11 })} -

- )) - : [] - } + contentStyle={{ border: 'none' }} tabContent={exposures.map(x => ( + /> ))} - /> + tabs={ + exposures.length > 1 + ? exposures.map(x => ( +

+ {truncate(x.node.exposure_id, { length: 11 })} +

+ )) + : [] + } + /> )} {!totalExposures && (

No Exposures Found.

@@ -346,10 +429,8 @@ export default compose( borderTop: `1px solid ${theme.greyScale5}`, marginTop: '10px', }} - > + > { const fileData = { @@ -364,7 +445,8 @@ export default compose( )} {f.node.access === 'controlled' && ( - )}{' '} + )} + {' '} {f.node.file_name} ), @@ -376,36 +458,47 @@ export default compose( display: 'flex', flexDirection: 'row', }} - > + > + />
), }; })} headings={[ - { key: 'file_name', title: 'Filename' }, - { key: 'data_format', title: 'Data format' }, + { + key: 'file_name', + title: 'Filename', + }, + { + key: 'data_format', + title: 'Data format', + }, { key: 'file_size', title: 'Size', style: { textAlign: 'right' }, }, - { key: 'action', title: 'Action' }, + { + key: 'action', + title: 'Action', + }, ]} - /> + title="Clinical Supplement File" + titleStyle={{ fontSize: '1em' }} + />

)} diff --git a/src/packages/@ncigdc/modern_components/ClinicalCard/ClinicalCard.relay.js b/src/packages/@ncigdc/modern_components/ClinicalCard/ClinicalCard.relay.js index eae1b8192..4936e855b 100644 --- a/src/packages/@ncigdc/modern_components/ClinicalCard/ClinicalCard.relay.js +++ b/src/packages/@ncigdc/modern_components/ClinicalCard/ClinicalCard.relay.js @@ -3,42 +3,55 @@ import React from 'react'; import { graphql } from 'react-relay'; import { makeFilter } from '@ncigdc/utils/filters'; -import { compose, withPropsOnChange, branch, renderComponent } from 'recompose'; +import { + branch, + compose, + renderComponent, + setDisplayName, + withPropsOnChange, +} from 'recompose'; import Query from '@ncigdc/modern_components/Query'; -export default (Component: ReactClass<*>) => - compose( - branch( - ({ caseId }) => !caseId, - renderComponent(() => ( -
-
caseId
must be provided -
- )), - ), - withPropsOnChange(['caseId'], ({ caseId }) => { - return { - variables: { - filters: makeFilter([ - { - field: 'cases.case_id', - value: [caseId], - }, - ]), - fileFilters: makeFilter([ - { field: 'cases.case_id', value: [caseId] }, - { field: 'files.data_type', value: ['Clinical Supplement'] }, - ]), - }, - }; - }), - )((props: Object) => { - return ( - ) => compose( + setDisplayName('EnhancedClinicalCard_Relay'), + branch( + ({ caseId }) => !caseId, + renderComponent(() => ( +
+
caseId
+ {' '} +must be provided +
+ )), + ), + withPropsOnChange(['caseId'], ({ caseId }) => { + return { + variables: { + fileFilters: makeFilter([ + { + field: 'cases.case_id', + value: [caseId], + }, + { + field: 'files.data_type', + value: ['Clinical Supplement'], + }, + ]), + filters: makeFilter([ + { + field: 'cases.case_id', + value: [caseId], + }, + ]), + }, + }; + }), +)((props: Object) => { + return ( + ) => morphology primary_diagnosis prior_malignancy + synchronous_malignancy progression_or_recurrence site_of_resection_or_biopsy tissue_or_organ_of_origin @@ -161,6 +175,7 @@ export default (Component: ReactClass<*>) => } } `} - /> - ); - }); + variables={props.variables} + /> + ); +}); diff --git a/src/packages/@ncigdc/modern_components/DownloadBiospecimenDropdown/DownloadBiospecimenDropdown.js b/src/packages/@ncigdc/modern_components/DownloadBiospecimenDropdown/DownloadBiospecimenDropdown.js index d257e40ac..fcae68f27 100644 --- a/src/packages/@ncigdc/modern_components/DownloadBiospecimenDropdown/DownloadBiospecimenDropdown.js +++ b/src/packages/@ncigdc/modern_components/DownloadBiospecimenDropdown/DownloadBiospecimenDropdown.js @@ -20,7 +20,6 @@ const styles = { minWidth: '100%', width: '100%', left: '1px', - borderRadius: '5px', }, dropdownButton: { marginLeft: '0.2rem', @@ -72,7 +71,10 @@ export default compose( const biospecimenCount = viewer ? viewer[scope].cases.hits.total : null; const buttonProps = { className: 'data-download-biospecimen', - style: { ...styles.dropdownButton, ...buttonStyles }, + style: { + ...styles.dropdownButton, + ...buttonStyles, + }, leftIcon: state.setCreating || state.jsonDownloading || state.tsvDownloading ? ( @@ -82,20 +84,26 @@ export default compose( }; return ( setState({ ...state, setCreating: true })} + onClick={() => setState({ + ...state, + setCreating: true, + })} onComplete={(setId, size) => { - setState({ ...state, setId, size, setCreating: false }); + setState({ + ...state, + setId, + size, + setCreating: false, + }); }} - displaySpinnerOverlay={false} - > + > {state.setCreating || state.jsonDownloading || state.tsvDownloading @@ -108,78 +116,56 @@ export default compose( ? 'Processing' : inactiveText} - ) + ) } - dropdownStyle={{ ...styles.dropdownContainer, ...dropdownStyles }} - > + className="data-download-biospecimen" + disabled={state.setCreating} + dropdownStyle={{ + ...styles.dropdownContainer, + ...dropdownStyles, + }} + > {state.setCreating ? (
) : (
- setState(s => ({ - ...s, - tsvDownloading: currentState, - }))} - active={state.tsvDownloading} - size={biospecimenCount ? biospecimenCount : state.size} + className="data-download-biospecimen-tsv" + endpoint="/biospecimen_tar" + filename={tsvFilename} filters={ shouldCreateSet ? { - op: 'and', - content: [ - { - op: 'in', - content: { - field: 'cases.case_id', - value: [`set_id:${state.setId}`], - }, + op: 'and', + content: [ + { + op: 'in', + content: { + field: 'cases.case_id', + value: [`set_id:${state.setId}`], }, - ], - } + }, + ], + } : filters } - filename={tsvFilename} - /> - setState(s => ({ + ...s, + tsvDownloading: currentState, + }))} + size={biospecimenCount || state.size} style={styles.button(theme)} - endpoint="/cases" + /> + - setState(s => ({ - ...s, - jsonDownloading: currentState, - }))} - active={state.jsonDownloading} - filters={ - shouldCreateSet - ? { - op: 'and', - content: [ - { - op: 'in', - content: { - field: 'cases.case_id', - value: [`set_id:${state.setId}`], - }, - }, - ], - } - : filters - } - size={biospecimenCount ? biospecimenCount : state.size} - fields={['case_id']} + className="data-download-biospecimen" dataExportExpands={[ 'samples', 'samples.portions', @@ -192,8 +178,33 @@ export default compose( 'samples.portions.annotations', 'samples.portions.center', ]} + endpoint="/cases" + fields={['case_id']} filename={jsonFilename} - /> + filters={ + shouldCreateSet + ? { + op: 'and', + content: [ + { + op: 'in', + content: { + field: 'cases.case_id', + value: [`set_id:${state.setId}`], + }, + }, + ], + } + : filters + } + inactiveText="JSON" + setParentState={currentState => setState(s => ({ + ...s, + jsonDownloading: currentState, + }))} + size={biospecimenCount || state.size} + style={styles.button(theme)} + />
)} diff --git a/src/packages/@ncigdc/modern_components/DownloadClinicalDropdown/DownloadClinicalDropdown.js b/src/packages/@ncigdc/modern_components/DownloadClinicalDropdown/DownloadClinicalDropdown.js index 25d90834d..b71452b8b 100644 --- a/src/packages/@ncigdc/modern_components/DownloadClinicalDropdown/DownloadClinicalDropdown.js +++ b/src/packages/@ncigdc/modern_components/DownloadClinicalDropdown/DownloadClinicalDropdown.js @@ -17,7 +17,6 @@ export const styles = { minWidth: '100%', width: '100%', left: '1px', - borderRadius: '5px', }, dropdownButton: { marginLeft: '0.2rem', @@ -66,65 +65,56 @@ export default compose( const clinicalCount = viewer ? viewer[scope].cases.hits.total : null; return ( ) : ( - ) + ) } - > + style={{ + ...styles.common, + ...styles.dropdownButton, + ...buttonStyles, + }} + > {state.jsonDownloading || state.tsvDownloading ? 'Processing' : inactiveText} - } - dropdownStyle={{ ...styles.dropdownContainer, ...dropdownStyles }} - > + )} + className="data-download-clinical" + dropdownStyle={{ + ...styles.dropdownContainer, + ...dropdownStyles, + }} + > - setState(s => ({ - ...s, - tsvDownloading: currentState, - }))} - active={state.tsvDownloading} - filters={filters} + className="data-download-clinical-tsv" + endpoint="/clinical_tar" filename={tsvFilename} + filters={filters} + format="TSV" + inactiveText="TSV" scope={scope} - /> - setState(s => ({ + ...s, + tsvDownloading: currentState, + }))} size={clinicalCount} style={styles.button(theme)} - endpoint="/cases" + /> + - setState(s => ({ - ...s, - jsonDownloading: currentState, - }))} - active={state.jsonDownloading} - filters={filters} - fields={['case_id']} + className="data-download-clinical-json" dataExportExpands={[ 'demographic', 'diagnoses', @@ -132,8 +122,18 @@ export default compose( 'family_histories', 'exposures', ]} + endpoint="/cases" + fields={['case_id']} filename={jsonFilename} - /> + filters={filters} + inactiveText="JSON" + setParentState={currentState => setState(s => ({ + ...s, + jsonDownloading: currentState, + }))} + size={clinicalCount} + style={styles.button(theme)} + /> ); }, diff --git a/src/packages/@ncigdc/modern_components/QQPlot/QQPlot.js b/src/packages/@ncigdc/modern_components/QQPlot/QQPlot.js new file mode 100644 index 000000000..833a7bddf --- /dev/null +++ b/src/packages/@ncigdc/modern_components/QQPlot/QQPlot.js @@ -0,0 +1,243 @@ +import React from 'react'; +import * as d3 from 'd3'; +import ReactFauxDOM from 'react-faux-dom'; +import { + compose, + withState, + pure, + withProps, +} from 'recompose'; +import { last, groupBy, sortBy } from 'lodash'; +import reactSize from 'react-sizeme'; + +import { qnorm } from './qqUtils'; + +const QQPlot = ({ + axisStyles = {}, + data = [], + exportCoordinates = false, + height = 320, + plotTitle = '', + qqLineStyles = {}, + qqPointStyles = {}, + size: { width }, + styles = {}, + xAxisTitle = 'Theoretical Quantiles', + yAxisTitle = 'Sample Quantiles', +}) => { + // default styles + const qqLine = { + color: '#e377c2', + strokeWidth: 2, + ...qqLineStyles, + }; + const qqPoint = { + color: 'blue', + strokeWidth: 1, + radius: 1.5, + ...qqPointStyles, + }; + const axisStyle = { + textColor: '#888', + fontSize: '1rem', + fontWeight: '400', + ...axisStyles, + }; + + const margin = styles.margin || { + top: 20, + right: 20, + bottom: 20, + left: 20, + }; + + const chartWidth = (width || 300) - margin.left - margin.right; + const chartHeight = height - margin.top - margin.bottom; + const padding = styles.padding || 40; + + // qq plot calculations + const n = data.length; + + // subtract 1 to account for 0 index array + const getQuantile = (count, quantile) => Math.ceil(count * (quantile / 4)) - 1; + + let zScores = data; + + // sample quantile(y) and theoretical quantile (x) + if (!exportCoordinates) { + zScores = sortBy(data).map((age, i) => ({ + x: qnorm((i + 1 - 0.5) / n), + y: age, + })); + } + + const quantile1Coords = zScores[getQuantile(n, 1)]; + const quantile3Coords = zScores[getQuantile(n, 3)]; + + // create svg + const el = ReactFauxDOM.createElement('div'); + el.style.width = '100%'; + el.setAttribute('class', 'qq-plot'); + + const xScale = d3 + .scaleLinear() + .domain([ + d3.min(zScores, (d) => { + return Math.floor(d.x); + }), + d3.max(zScores, (d) => { + return Math.ceil(d.x); + }), + ]) + .range([padding, chartWidth - padding * 2]); + + const yScale = d3 + .scaleLinear() + .domain([ + d3.min(zScores, (d) => { + return Math.floor(d.y); + }), + d3.max(zScores, (d) => { + return Math.ceil(d.y); + }), + ]) + .range([chartHeight, padding]); + + const xAxis = d3 + .axisBottom() + .scale(xScale) + .ticks(Object.keys(groupBy(zScores.map(z => z.x), Math.floor)).length); + + const yAxis = d3 + .axisLeft() + .scale(yScale) + .ticks(5); + + // get slope from first and third quantile to match qqline from R + const slope = (quantile3Coords.y - quantile1Coords.y) / (quantile3Coords.x - quantile1Coords.x); + const yMin = zScores[0].y; + const yMax = last(zScores).y; + + // calculate x values for start and end of line + const xAtYMin = quantile1Coords.x - ((quantile1Coords.y - yMin) / slope); + const xAtYMax = quantile3Coords.x + ((yMax - quantile3Coords.y) / slope); + + const svg = d3 + .select(el) + .append('svg') + .attr('width', chartWidth) + .attr('height', chartHeight + padding); + + // draw sample points + svg + .selectAll('circle') + .data(zScores) + .enter() + .append('circle') + .attr('cx', (d) => xScale(d.x)) + .attr('cy', (d) => yScale(d.y)) + .attr('r', qqPoint.radius) + .attr('stroke', qqPoint.color) + .attr('stroke-width', qqPoint.strokeWidth) + .attr('fill', 'transparent') + .attr('transform', `translate(${padding},${-(padding / 2)})`); + + const line = d3 + .line() + .x(d => xScale(d.x)) + .y(d => yScale(d.y)); + + // draw qq line + svg + .append('path') + .attr('class', 'coords') + .datum([ + { + x: xAtYMin, + y: yMin, + }, + ...quantile1Coords, + ...quantile3Coords, + { + x: xAtYMax, + y: yMax, + }, + ]) + .attr('d', line) + .attr('stroke', qqLine.color) + .attr('stroke-width', qqLine.strokeWidth) + .attr('transform', `translate(${padding},${-(padding / 2)})`); + +// clip path to prevent qq line extending beyond y-axis + svg + .append('rect') + .attr('x', -(padding)) + .attr('y', padding / 2) + .attr('clip-path', 'url(#regression-clip-left)') + .style('fill', 'white') + .attr('height', chartHeight - padding) + .attr('width', padding * 2) + .attr('transform', `translate(${padding},${padding / 2})`); + + // position slightly higher to account for qqline end + svg + .append('rect') + .attr('x', -(padding)) + .attr('y', padding / 2) + .attr('clip-path', 'url(#regression-clip-right)') + .style('fill', 'white') + .attr('height', chartHeight) + .attr('width', padding * 2) + .attr('transform', `translate(${chartWidth},${-padding})`); + + svg + .append('text') + .attr('y', 0) + .attr('x', (width / 2) - (padding / 2)) + .attr('dy', '1em') + .style('text-anchor', 'middle') + .style('fontSize', '1.2rem') + .style('fontWeight', '400') + .style('marginBottom', 10) + .text(plotTitle); + + // x axis + svg + .append('g') + .attr('class', 'x axis') + .attr('transform', `translate(${padding},${height - (padding / 2)})`) + .call(xAxis); + + svg + .append('text') + .attr('text-anchor', 'middle') + .attr('transform', `translate(${(chartWidth + padding) / 2},${height + (padding / 2)})`) + .text(xAxisTitle) + .style('fontSize', axisStyle.fontSize) + .style('fontWeight', axisStyle.fontWeight) + .attr('fill', axisStyle.textColor); + + // y axis + svg + .append('g') + .attr('class', 'y axis') + .attr('transform', `translate(${padding * 2}, ${-(padding / 2)})`) + .call(yAxis); + + svg + .append('text') + .attr('text-anchor', 'middle') + .attr('transform', `translate(${padding - 10},${height / 2})rotate(-90)`) + .text(yAxisTitle) + .style('fontSize', axisStyle.fontSize) + .style('fontWeight', axisStyle.fontWeight) + .attr('fill', axisStyle.textColor); + + return el.toReact(); +}; + +export default reactSize(compose( + withState('chart', 'setState', ), + withProps(({ data }) => ({ data })), + pure +))(QQPlot); diff --git a/src/packages/@ncigdc/modern_components/QQPlot/QQPlotQuery.js b/src/packages/@ncigdc/modern_components/QQPlot/QQPlotQuery.js new file mode 100644 index 000000000..a4b8e0745 --- /dev/null +++ b/src/packages/@ncigdc/modern_components/QQPlot/QQPlotQuery.js @@ -0,0 +1,140 @@ +import React from 'react'; +import { + compose, withPropsOnChange, withProps, withState, +} from 'recompose'; +import { + sortBy, isArray, isPlainObject, isNumber, isEqual +} from 'lodash'; + +import { addInFilters } from '@ncigdc/utils/filters'; +import { fetchApi } from '@ncigdc/utils/ajax'; +import Spinner from '@ncigdc/uikit/Loaders/Material'; +import { withTheme } from '@ncigdc/theme'; +import { qnorm } from './qqUtils'; +import QQPlot from './QQPlot'; + +export default compose( + withTheme, + withState('data', 'setData', null), + withState('isLoading', 'setIsLoading', true), + withProps({ + updateData: async ({ + dataHandler, + fieldName, + first, + filters, + setData, + setDataHandler, + setIsLoading, + }) => { + setIsLoading(true); + setDataHandler(false); + const missingFilter = { + op: 'and', + content: [ + { + op: 'NOT', + content: { + field: `cases.${fieldName}`, + value: ['MISSING'], + }, + }, + ], + }; + const newFilters = addInFilters(filters, missingFilter) + const res = await fetchApi('case_ssms', { + headers: { 'Content-Type': 'application/json' }, + body: { + filters: JSON.stringify(newFilters), + size: first, + fields: fieldName, + }, + }); + const data = res && res.data ? res.data.hits : []; + const parsedFieldName = field => { + const parsed = field.split('.'); + return { + clinicalType: parsed[0], + clinicalField: parsed[1], + clinicalNestedField: parsed[2], + }; + }; + const { clinicalField, clinicalNestedField, clinicalType } = parsedFieldName(fieldName); + + const continuousValues = []; + + data.forEach(hit => { + if (isArray(hit[clinicalType])) { + return hit[clinicalType].map(subType => { + if (clinicalNestedField) { + return subType[clinicalField].map(sub => { + return continuousValues.push(sub[clinicalNestedField]); + }); + } + return continuousValues.push(subType[clinicalField]); + }); + } + if (isPlainObject(hit[clinicalType])) { + return continuousValues.push(hit[clinicalType][clinicalField]); + } + return continuousValues.push(hit[clinicalType]); + }); + const sortedData = sortBy(continuousValues.filter(b => isNumber(b))); + const parsedData = sortBy(sortedData).map((age, i) => ({ + x: qnorm((i + 1 - 0.5) / sortedData.length), + y: age, + })); + setData(parsedData, () => setIsLoading(false)); + dataHandler(parsedData.map(d => ({ + 'Sample Quantile': d.y, + 'Theoretical Quantile': d.x, + })), () => setDataHandler(true)); + }, + }), + withPropsOnChange((props, nextProps) => !isEqual(props.dataBuckets, nextProps.dataBuckets), ({ updateData, ...props }) => updateData(props)), +)(({ + chartHeight, + clinicalType, + data, + fieldName, + isLoading, + queryField, + theme, + ...props +}) => { + if (isLoading) { + return ( +
+ +
+ ); + } + + return ( + + ); +}); diff --git a/src/packages/@ncigdc/modern_components/QQPlot/qqUtils.js b/src/packages/@ncigdc/modern_components/QQPlot/qqUtils.js new file mode 100644 index 000000000..f1a404422 --- /dev/null +++ b/src/packages/@ncigdc/modern_components/QQPlot/qqUtils.js @@ -0,0 +1,47 @@ +// from https://rangevoting.org/Qnorm.html +export const qnorm = function (p) { + // ALGORITHM AS 111, APPL.STATIST., VOL.26, 118-121, 1977. + // Computes z = invNorm(p) + + p = parseFloat(p); + const split = 0.42; + + const a0 = 2.50662823884; + const a1 = -18.61500062529; + const a2 = 41.39119773534; + const a3 = -25.44106049637; + const b1 = -8.4735109309; + const b2 = 23.08336743743; + const b3 = -21.06224101826; + const b4 = 3.13082909833; + const c0 = -2.78718931138; + const c1 = -2.29796479134; + const c2 = 4.85014127135; + const c3 = 2.32121276858; + const d1 = 3.54388924762; + const d2 = 1.63706781897; + + const q = p - 0.5; + + let r; + let ppnd; + + if (Math.abs(q) <= split) { + r = q * q; + ppnd = + (q * (((a3 * r + a2) * r + a1) * r + a0)) / + ((((b4 * r + b3) * r + b2) * r + b1) * r + 1); + } else { + r = p; + if (q > 0) r = 1 - p; + if (r > 0) { + r = Math.sqrt(-Math.log(r)); + ppnd = (((c3 * r + c2) * r + c1) * r + c0) / ((d2 * r + d1) * r + 1); + if (q < 0) ppnd = -ppnd; + } else { + ppnd = 0; + } + } + + return ppnd; +}; diff --git a/src/packages/@ncigdc/modern_components/withSetAction/SetActionButton.js b/src/packages/@ncigdc/modern_components/withSetAction/SetActionButton.js index 6b4c14c68..39c687fdc 100644 --- a/src/packages/@ncigdc/modern_components/withSetAction/SetActionButton.js +++ b/src/packages/@ncigdc/modern_components/withSetAction/SetActionButton.js @@ -3,7 +3,7 @@ import Button from '@ncigdc/uikit/Button'; import Overlay from '@ncigdc/uikit/Overlay'; import Spinner from '@ncigdc/uikit/Loaders/Material'; -export default class extends React.Component { +export default class SetActionButton extends React.Component { clicked = false; componentWillReceiveProps(next) { @@ -39,7 +39,8 @@ export default class extends React.Component { onClick(); createSet(props); }} - style={style}> + style={style} + > {children}
diff --git a/src/packages/@ncigdc/modern_components/withSetAction/index.js b/src/packages/@ncigdc/modern_components/withSetAction/index.js index 7469966f5..335e4f6ae 100644 --- a/src/packages/@ncigdc/modern_components/withSetAction/index.js +++ b/src/packages/@ncigdc/modern_components/withSetAction/index.js @@ -1,62 +1,111 @@ // @flow -import { withProps, compose } from 'recompose'; +import { + compose, + setDisplayName, + withProps, +} from 'recompose'; import withSetAction from './withSetAction'; import SetActionButton from './SetActionButton'; export const CreateExploreGeneSetButton = compose( withSetAction, - withProps(() => ({ type: 'gene', scope: 'explore', action: 'create' })), + withProps(() => ({ + type: 'gene', + scope: 'explore', + action: 'create', + })), )(SetActionButton); export const CreateExploreCaseSetButton = compose( withSetAction, - withProps(() => ({ type: 'case', scope: 'explore', action: 'create' })), + withProps(() => ({ + type: 'case', + scope: 'explore', + action: 'create', + })), )(SetActionButton); export const CreateExploreSsmSetButton = compose( withSetAction, - withProps(() => ({ type: 'ssm', scope: 'explore', action: 'create' })), + withProps(() => ({ + type: 'ssm', + scope: 'explore', + action: 'create', + })), )(SetActionButton); export const CreateRepositoryCaseSetButton = compose( withSetAction, - withProps(() => ({ type: 'case', scope: 'repository', action: 'create' })), + withProps(() => ({ + type: 'case', + scope: 'repository', + action: 'create', + })), )(SetActionButton); export const AppendExploreGeneSetButton = compose( withSetAction, - withProps(() => ({ type: 'gene', scope: 'explore', action: 'append' })), + withProps(() => ({ + type: 'gene', + scope: 'explore', + action: 'append', + })), )(SetActionButton); export const AppendExploreCaseSetButton = compose( withSetAction, - withProps(() => ({ type: 'case', scope: 'explore', action: 'append' })), + withProps(() => ({ + type: 'case', + scope: 'explore', + action: 'append', + })), )(SetActionButton); export const AppendExploreSsmSetButton = compose( withSetAction, - withProps(() => ({ type: 'ssm', scope: 'explore', action: 'append' })), + withProps(() => ({ + type: 'ssm', + scope: 'explore', + action: 'append', + })), )(SetActionButton); export const AppendRepositoryCaseSetButton = compose( withSetAction, - withProps(() => ({ type: 'case', scope: 'repository', action: 'append' })), + withProps(() => ({ + type: 'case', + scope: 'repository', + action: 'append', + })), )(SetActionButton); export const RemoveFromExploreGeneSetButton = compose( withSetAction, - withProps(() => ({ type: 'gene', scope: 'explore', action: 'remove_from' })), + withProps(() => ({ + type: 'gene', + scope: 'explore', + action: 'remove_from', + })), )(SetActionButton); export const RemoveFromExploreCaseSetButton = compose( + setDisplayName('EnhancedRemoveFromExploreCaseSetButton'), withSetAction, - withProps(() => ({ type: 'case', scope: 'explore', action: 'remove_from' })), + withProps(() => ({ + type: 'case', + scope: 'explore', + action: 'remove_from', + })), )(SetActionButton); export const RemoveFromExploreSsmSetButton = compose( withSetAction, - withProps(() => ({ type: 'ssm', scope: 'explore', action: 'remove_from' })), + withProps(() => ({ + type: 'ssm', + scope: 'explore', + action: 'remove_from', + })), )(SetActionButton); export const RemoveFromRepositoryCaseSetButton = compose( diff --git a/src/packages/@ncigdc/tableModels/utils.tsx b/src/packages/@ncigdc/tableModels/utils.tsx index 9400e5617..a12fad966 100644 --- a/src/packages/@ncigdc/tableModels/utils.tsx +++ b/src/packages/@ncigdc/tableModels/utils.tsx @@ -3,12 +3,17 @@ import _ from 'lodash'; import Tooltip from '@ncigdc/uikit/Tooltip/Tooltip'; import Hidden from '@ncigdc/components/Hidden'; import { tableToolTipHint } from '@ncigdc/theme/mixins'; -import { DATA_CATEGORIES } from '@ncigdc/utils/constants'; +import { DATA_CATEGORIES, DATA_CATEGORIES_FOR_PROJECTS_TABLE } from '@ncigdc/utils/constants'; import { Th, Td, ThNum, TdNum } from '@ncigdc/uikit/Table'; import { makeFilter } from '@ncigdc/utils/filters'; import { findDataCategory } from '@ncigdc/utils/data'; import { IListLinkProps } from '@ncigdc/components/Links/types'; -import { TCategoryAbbr, IDataCategory } from '@ncigdc/utils/data/types'; +import ProjectLink from '@ncigdc/components/Links/ProjectLink'; +import { + IDataCategory, + TCategoryAbbr, +} from '@ncigdc/utils/data/types'; + interface ICreateDataCategoryColumnsProps{ title: string; countKey: string; @@ -79,6 +84,8 @@ export const createDataCategoryColumns = ({ getCellLinkFilters, getTotalLinkFilters, }: ICreateDataCategoryColumnsProps)=> { + const isProjectsTable = countKey === 'case_count'; + const CATEGORY_COLUMNS = isProjectsTable ? DATA_CATEGORIES_FOR_PROJECTS_TABLE : DATA_CATEGORIES; return [ { name: 'Data Categories', @@ -87,16 +94,21 @@ export const createDataCategoryColumns = ({ th: () => (
), downloadable: true, - subHeadingIds: _.map(DATA_CATEGORIES, category => category.abbr), + subHeadingIds: _.map(CATEGORY_COLUMNS, category => category.abbr), }, - ..._.map(DATA_CATEGORIES, (category: { full: string; abbr: TCategoryAbbr }) => ({ + ..._.map(CATEGORY_COLUMNS, (category: { + dataCategory: TCategoryAbbr, + full: string, + tooltip: string, + abbr: TCategoryAbbr, + }) => ({ name: category.abbr, id: category.abbr, subHeading: true, @@ -104,21 +116,28 @@ export const createDataCategoryColumns = ({ th: () => ( - + {category.abbr} ), td: ({ node }: { node: INode }) => { - const count = findDataCategory( - category.abbr, - node.summary.data_categories - )[countKey]; + const isMetadataColumn = ['Clinical Metadata', 'Biospecimen Metadata'].includes(category.tooltip); + const count = isMetadataColumn + ? node.summary.file_count + : findDataCategory( + category.dataCategory || category.abbr, + node.summary.data_categories + )[countKey]; return ( {count === 0 ? ( '0' + ) : isMetadataColumn ? ( + + {node.summary.case_count.toLocaleString()} + ) : ( - findDataCategory(category.abbr, x.node.summary.data_categories)[ - countKey - ] - ).toLocaleString()} + findDataCategory( + category.dataCategory || category.abbr, + x.node.summary.data_categories)[countKey] + ).toLocaleString()} ), diff --git a/src/packages/@ncigdc/theme/fonts/gdc-icons.icomoon.selection.json b/src/packages/@ncigdc/theme/fonts/gdc-icons.icomoon.selection.json index 1dafdcdea..7377fc3a1 100755 --- a/src/packages/@ncigdc/theme/fonts/gdc-icons.icomoon.selection.json +++ b/src/packages/@ncigdc/theme/fonts/gdc-icons.icomoon.selection.json @@ -322,7 +322,7 @@ "width": 1045, "grid": 0, "tags": [ - "GDC-App-data-transer-tool" + "GDC-App-data-transfer-tool" ], "colorPermutations": { "11631621621163163163118918518512552552551": [ @@ -378,7 +378,7 @@ 59670, 59671 ], - "name": "gdc-data-transer-tool" + "name": "gdc-data-transfer-tool" }, "setIdx": 1, "setId": 2, diff --git a/src/packages/@ncigdc/theme/global.css b/src/packages/@ncigdc/theme/global.css index 190501f95..81b30ebe9 100644 --- a/src/packages/@ncigdc/theme/global.css +++ b/src/packages/@ncigdc/theme/global.css @@ -6668,41 +6668,41 @@ ul.sort-list .dndDragging { margin-left: -1.02050781em; color: #a3a3a3; } -.icon-gdc-data-transer-tool .path1:before { +.icon-gdc-data-transfer-tool .path1:before { content: "\e910"; color: #ffffff; } -.icon-gdc-data-transer-tool .path2:before { +.icon-gdc-data-transfer-tool .path2:before { content: "\e911"; margin-left: -1.02050781em; color: #ffffff; } -.icon-gdc-data-transer-tool .path3:before { +.icon-gdc-data-transfer-tool .path3:before { content: "\e912"; margin-left: -1.02050781em; color: #ffffff; } -.icon-gdc-data-transer-tool .path4:before { +.icon-gdc-data-transfer-tool .path4:before { content: "\e913"; margin-left: -1.02050781em; color: #a3a3a3; } -.icon-gdc-data-transer-tool .path5:before { +.icon-gdc-data-transfer-tool .path5:before { content: "\e914"; margin-left: -1.02050781em; color: #a3a3a3; } -.icon-gdc-data-transer-tool .path6:before { +.icon-gdc-data-transfer-tool .path6:before { content: "\e915"; margin-left: -1.02050781em; color: #000000; } -.icon-gdc-data-transer-tool .path7:before { +.icon-gdc-data-transfer-tool .path7:before { content: "\e916"; margin-left: -1.02050781em; color: #ffffff; } -.icon-gdc-data-transer-tool .path8:before { +.icon-gdc-data-transfer-tool .path8:before { content: "\e917"; margin-left: -1.02050781em; color: #ffffff; @@ -7008,6 +7008,10 @@ ul.sort-list .dndDragging { padding: 2px; height: 25px; } +.icon-gdc-publications { + padding: 2px; + height: 30px; +} .list-indent { margin-right: 10px; background: #5b5151; @@ -8574,3 +8578,19 @@ fieldset[disabled] .btn-primary.active { cursor: pointer; background-color: #dbdbdb; } + +#projects-table th { + word-wrap: break-word !important; + white-space: normal !important; + vertical-align: bottom; + max-width: 100px !important; +} + +#projects-table td { + white-space: normal !important; + max-width: 100px !important; +} + +abbr span { + display: inline !important; +} diff --git a/src/packages/@ncigdc/theme/images/GDC-App-publications.svg b/src/packages/@ncigdc/theme/images/GDC-App-publications.svg new file mode 100644 index 000000000..f5f60f612 --- /dev/null +++ b/src/packages/@ncigdc/theme/images/GDC-App-publications.svg @@ -0,0 +1 @@ +icon-publications \ No newline at end of file diff --git a/src/packages/@ncigdc/theme/mixins.js b/src/packages/@ncigdc/theme/mixins.js index 42565a782..41c48c21f 100644 --- a/src/packages/@ncigdc/theme/mixins.js +++ b/src/packages/@ncigdc/theme/mixins.js @@ -2,8 +2,8 @@ import { css } from 'glamor'; -import { getTheme } from './index'; import Color from 'color'; +import { getTheme } from './index'; export const center = { display: 'flex', @@ -31,6 +31,7 @@ export const dropdown = { backgroundColor: 'white', textAlign: 'left', right: 0, + borderRadius: '5px', }; export const dropdownButton = { @@ -57,9 +58,9 @@ export const visualizingButton = { export const margin = (left, right) => { if (left && right) { return { margin: '0 0.5rem' }; - } else if (left) { + } if (left) { return { marginLeft: '0.5rem' }; - } else if (right) { + } if (right) { return { marginRight: '0.5rem' }; } return {}; @@ -125,10 +126,9 @@ export const linkButton = { color: 'white', }, ':hover': { - backgroundColor: ({ theme }: Object) => - Color(theme.primary) - .lighten(0.7) - .rgbString(), + backgroundColor: ({ theme }: Object) => Color(theme.primary) + .lighten(0.7) + .rgbString(), color: 'white', }, }; diff --git a/src/packages/@ncigdc/uikit/ControlEditableRow.js b/src/packages/@ncigdc/uikit/ControlEditableRow.js new file mode 100644 index 000000000..a026d60e1 --- /dev/null +++ b/src/packages/@ncigdc/uikit/ControlEditableRow.js @@ -0,0 +1,141 @@ +import React from 'react'; +import { + compose, + withState, + withHandlers, +} from 'recompose'; + +import Input from '@ncigdc/uikit/Form/Input'; +import Pencil from '@ncigdc/theme/icons/Pencil'; +import { Row, Column } from '@ncigdc/uikit/Flex'; +import OutsideClickHandler from 'react-outside-click-handler'; + +export default compose( + withState('isEditing', 'setIsEditing', ({ isEditing }: any) => isEditing || false), + withState('value', 'setValue', ({ text }: any) => text), + withHandlers({ + handleCancel: ({ + cleanWarning, + setIsEditing, + setValue, + text, + }: any) => () => { + setIsEditing(false); + setValue(text); + cleanWarning(); + }, + toggleEditingAndSave: ({ + disabled = false, + handleSave, + isEditing, + setIsEditing, + value, + }: any) => () => { + if (disabled) { + return; + } + if (value.length !== 0) { + if (isEditing) { + if (handleSave(value) !== 'unsave') { + setIsEditing(false); + } + } else { + setIsEditing(true); + } + } + }, + }), +)( + ({ + isEditing, + toggleEditingAndSave, + value, + setValue, + handleCancel, + children, + iconStyle = {}, + containerStyle = {}, + disabled = false, + noEditingStyle, + disableOnKeyDown = false, + warning, + onEdit, + }): any => { + return ( + + {isEditing ? ( + { + if (disableOnKeyDown) { + return; + } + toggleEditingAndSave(); + }} + > + + + { + onEdit(e.target.value); + setValue(e.target.value); + }} + onFocus={e => e.target.select()} + onKeyDown={e => { + if (!disableOnKeyDown && (e.key === 'Enter')) { + toggleEditingAndSave(); + } else if (e.key === 'Escape') { + handleCancel(); + } + }} + style={{ + borderRadius: '4px', + transition: 'all 0.2s ease', + width: '300px', + }} + type="text" + value={value} + /> + + {warning + ? ( + + {warning} + + ) : null} + + + ) + : ( + + {children} + + + ) + } + + ); + } +); diff --git a/src/packages/@ncigdc/uikit/Dropdown.js b/src/packages/@ncigdc/uikit/Dropdown.js index 135f8563c..55266ebb0 100644 --- a/src/packages/@ncigdc/uikit/Dropdown.js +++ b/src/packages/@ncigdc/uikit/Dropdown.js @@ -20,9 +20,12 @@ const Dropdown = ({ className, }) => ( + className={`${className} dropdown`} + style={{ + position: 'relative', + ...style, + }} + > !isDisabled && setActive(!active)}> {button || ( @@ -34,9 +37,12 @@ const Dropdown = ({ {active && ( !autoclose && e.stopPropagation()} - > + style={{ + ...styles.dropdown, + ...dropdownStyle, + }} + > {children} )} diff --git a/src/packages/@ncigdc/uikit/EditableLabel.js b/src/packages/@ncigdc/uikit/EditableLabel.js index 556f31939..61e197b70 100644 --- a/src/packages/@ncigdc/uikit/EditableLabel.js +++ b/src/packages/@ncigdc/uikit/EditableLabel.js @@ -71,81 +71,81 @@ export default compose( disabled = false, disabledMessage = null, }) => ( -
- {isEditing ? ( - - + {isEditing ? ( + setValue(e.target.value)} - onKeyDown={e => { - if (e.key === 'Enter') { - toggleEditingAndSave(); - } else if (e.key === 'Escape') { - handleCancel(); - } + justifyContent: 'space-between', + alignItems: 'center', + ...containerStyle, }} - type="text" - autoFocus - onFocus={e => e.target.select()} - /> - MAX_SET_NAME_LENGTH - ? `Maximum name length ${MAX_SET_NAME_LENGTH}` - : null - } + spacing={'5px'} > - - - - - ) : ( - - - {children} - - - )} -
- ) -); + ) : ( + + + {children} + + + + )} + + ) +); \ No newline at end of file diff --git a/src/packages/@ncigdc/uikit/Modal.js b/src/packages/@ncigdc/uikit/Modal.js index 9900e2fff..bcdd684ed 100644 --- a/src/packages/@ncigdc/uikit/Modal.js +++ b/src/packages/@ncigdc/uikit/Modal.js @@ -26,21 +26,23 @@ const modalStyles = { borderRadius: '4px', margin: '30px auto', padding: '0px', - width: '65%', + width: '55%', boxShadow: 'rgba(0, 0, 0, 0.5) 0px 5px 15px', }, }; -const Modal = ({ isOpen, onRequestClose, style, children }) => ( +const Modal = ({ + children, isOpen, onRequestClose, style, +}) => ( {})} - contentLabel="Modal" - className="test-modal" - > - {Children.map(children, child => cloneElement(child, { ...child.props }))} - + className="test-modal" + contentLabel="Modal" + isOpen={isOpen} + onRequestClose={onRequestClose || (() => { })} + style={{ ..._.merge({}, modalStyles, style) }} + > + {Children.map(children, child => cloneElement(child, { ...child.props }))} + ); export default Modal; diff --git a/src/packages/@ncigdc/uikit/Tabs.js b/src/packages/@ncigdc/uikit/Tabs.js index 55ebee87c..ef1f767ad 100644 --- a/src/packages/@ncigdc/uikit/Tabs.js +++ b/src/packages/@ncigdc/uikit/Tabs.js @@ -1,17 +1,10 @@ -// @flow - -// Vendor import React, { Children } from 'react'; import PropTypes from 'prop-types'; import Color from 'color'; import { css } from 'glamor'; import { withTheme } from '@ncigdc/theme'; - -// Custom import { Row, Column } from './Flex'; -/*----------------------------------------------------------------------------*/ - const borderStyle = theme => `1px solid ${theme.greyScale4}`; const tabBorder = (theme, side) => ({ @@ -21,53 +14,49 @@ const tabBorder = (theme, side) => ({ borderBottom: side && borderStyle(theme), }); -const baseTabStyle = (theme, side) => - css({ - padding: '1.2rem 1.8rem', - fontSize: '1.5rem', - color: '#000', - textDecoration: 'none', - borderTop: '1px solid transparent', - borderLeft: '1px solid transparent', - borderBottom: '1px solid transparent', - borderRight: '1px solid transparent', - backgroundColor: theme.greyScale6, - marginBottom: !side && '-1px', - marginRight: side && '-1px', - transition: 'background-color 0.2s ease', - borderRadius: side ? '4px 0 0 4px' : '4px 4px 0 0', - cursor: 'pointer', - overflow: 'hidden', - }); +const baseTabStyle = (theme, side) => css({ + padding: '1.2rem 1.8rem', + fontSize: '1.5rem', + color: '#000', + textDecoration: 'none', + borderTop: '1px solid transparent', + borderLeft: '1px solid transparent', + borderBottom: '1px solid transparent', + borderRight: '1px solid transparent', + backgroundColor: theme.greyScale6, + marginBottom: !side && '-1px', + marginRight: side && '-1px', + transition: 'background-color 0.2s ease', + borderRadius: side ? '4px 0 0 4px' : '4px 4px 0 0', + cursor: 'pointer', + overflow: 'hidden', +}); const styles = { - active: (theme, side) => - css({ - backgroundColor: '#fff', + active: (theme, side) => css({ + backgroundColor: '#fff', + ...tabBorder(theme, side), + position: 'relative', + left: '0px', + zIndex: 2, + ':hover': { + backgroundColor: 'white', + }, + }), + inactive: (theme, side) => css({ + ':hover': { + textDecoration: 'none', + color: '#000', + backgroundColor: Color(theme.greyScale6) + .darken(0.05) + .rgbString(), ...tabBorder(theme, side), - position: 'relative', - left: '0px', - zIndex: 2, - ':hover': { - backgroundColor: 'white', - }, - }), - inactive: (theme, side) => - css({ - ':hover': { - textDecoration: 'none', - color: '#000', - backgroundColor: Color(theme.greyScale6) - .darken(0.05) - .rgbString(), - ...tabBorder(theme, side), - }, - }), - margin: side => - css({ - marginLeft: !side && '0.4rem', - marginTop: side && '0.4rem', - }), + }, + }), + margin: side => css({ + marginLeft: !side && '0.4rem', + marginTop: side && '0.4rem', + }), content: theme => ({ border: borderStyle(theme), backgroundColor: '#fff', @@ -89,26 +78,26 @@ const Tab = ({ {...(sibling ? styles.margin(side) : {})} style={tabStyle} {...props} - > + > {children} ); const Tabs = ({ - style, - tabs, activeIndex, children, + contentStyle, onTabClick, side, - contentStyle, - theme, + style, tabStyle, tabToolbar, + tabs, + theme, ...props -}) => - side ? ( - +}) => (side + ? ( +
+ > {Children.map(tabs, (child, i) => ( (onTabClick ? onTabClick(i) : () => {})} - active={i === activeIndex} sibling={i} - theme={theme} - tabStyle={tabStyle} side - > + tabStyle={tabStyle} + theme={theme} + > {child} ))} @@ -145,41 +134,43 @@ const Tabs = ({ width: 1, ...(contentStyle || {}), }} - > + > {children} ) : ( - + {Children.map(tabs, (child, i) => ( (onTabClick ? onTabClick(i) : () => {})} - active={i === activeIndex} - sibling={i} - theme={theme} - tabStyle={tabStyle} - side={false} - > + active={i === activeIndex} + className="test-tab" + onClick={() => (onTabClick ? onTabClick(i) : () => {})} + sibling={i} + side={false} + tabStyle={tabStyle} + theme={theme} + > {child} ))} {tabToolbar && {tabToolbar}} - + {children} - ); + )); Tabs.propTypes = { - children: PropTypes.node, activeIndex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + children: PropTypes.node, style: PropTypes.object, tabs: PropTypes.node, }; -/*----------------------------------------------------------------------------*/ - export default withTheme(Tabs); diff --git a/src/packages/@ncigdc/uikit/Tooltip/index.js b/src/packages/@ncigdc/uikit/Tooltip/index.js index 165f208e0..164331518 100644 --- a/src/packages/@ncigdc/uikit/Tooltip/index.js +++ b/src/packages/@ncigdc/uikit/Tooltip/index.js @@ -1,8 +1,4 @@ -// @flow - -import GlobalTooltip from './GlobalTooltip'; -import Tooltip from './Tooltip'; -import tooltipReducer, { setTooltip } from './dux'; -import withTooltip from './withTooltip'; - -export { GlobalTooltip, Tooltip, tooltipReducer, setTooltip, withTooltip }; +export { default as GlobalTooltip } from './GlobalTooltip'; +export { default as Tooltip } from './Tooltip'; +export { default as tooltipReducer, setTooltip } from './dux'; +export { default as withTooltip, TooltipInjector } from './withTooltip'; diff --git a/src/packages/@ncigdc/uikit/Tooltip/withTooltip.js b/src/packages/@ncigdc/uikit/Tooltip/withTooltip.js index be042f488..d8850d2ce 100644 --- a/src/packages/@ncigdc/uikit/Tooltip/withTooltip.js +++ b/src/packages/@ncigdc/uikit/Tooltip/withTooltip.js @@ -2,16 +2,18 @@ import React from 'react'; import { compose, - withState, lifecycle, - withHandlers, mapProps, + setDisplayName, + withHandlers, + withState, } from 'recompose'; import { connect } from 'react-redux'; -import { setTooltip } from '@ncigdc/uikit/Tooltip'; import { omit } from 'lodash'; +import { setTooltip } from './dux'; const enhance = compose( + setDisplayName('TooltipEnhancer'), connect(), withState('tooltipState', 'setTooltipState', false), withHandlers({ @@ -27,11 +29,20 @@ const enhance = compose( } }, }), - mapProps(props => - omit(props, ['tooltipState', 'setTooltipState', 'dispatch']), - ), + mapProps(props => omit(props, [ + 'tooltipState', + 'setTooltipState', + 'dispatch', + ]),), ); const withTooltip = Wrapped => enhance(props => ); +export const TooltipInjector = enhance(({ + children, + ...props +}) => React.cloneElement( + children, props +)); + export default withTooltip; diff --git a/src/packages/@ncigdc/uikit/UnstyledButton.js b/src/packages/@ncigdc/uikit/UnstyledButton.js index 9b18dc767..25e6f7787 100644 --- a/src/packages/@ncigdc/uikit/UnstyledButton.js +++ b/src/packages/@ncigdc/uikit/UnstyledButton.js @@ -13,8 +13,17 @@ const base = { padding: 0, }; -export default ({ children, style, ...props }) => ( - ); + +export default UnstyledButton; diff --git a/src/packages/@ncigdc/utils/ageDisplay.js b/src/packages/@ncigdc/utils/ageDisplay.js index ed01df8c3..f696e815d 100644 --- a/src/packages/@ncigdc/utils/ageDisplay.js +++ b/src/packages/@ncigdc/utils/ageDisplay.js @@ -3,19 +3,17 @@ import _ from 'lodash'; export const DAYS_IN_YEAR = 365.25; -export const getLowerAgeYears = (days: number) => - Math.ceil(days / DAYS_IN_YEAR); -export const getUpperAgeYears = (days: number) => - Math.ceil((days + 1 - DAYS_IN_YEAR) / DAYS_IN_YEAR); +export const getLowerAgeYears = (days: number) => Math.ceil(days / DAYS_IN_YEAR); +export const getUpperAgeYears = (days: number) => Math.ceil((days + 1 - DAYS_IN_YEAR) / DAYS_IN_YEAR); export default ( ageInDays: number, yearsOnly: boolean = false, defaultValue: string = '--', ): string => { - const DAYS_IN_YEAR = 365.25; - const leapThenPair = (years: number, days: number): number[] => - days === 365 ? [years + 1, 0] : [years, days]; + const leapThenPair = (years: number, days: number): number[] => ( + days === 365 ? [years + 1, 0] : [years, days] + ); const timeString = ( num: number, singular: string, diff --git a/src/packages/@ncigdc/utils/constants.js b/src/packages/@ncigdc/utils/constants.js index bc335e6e0..ebcab40fb 100644 --- a/src/packages/@ncigdc/utils/constants.js +++ b/src/packages/@ncigdc/utils/constants.js @@ -48,18 +48,72 @@ export const LOCAL_STORAGE_API_OVERRIDE = API_OVERRIDE_KEYS.some( k => localStorage[k] ); +const DATA_CATEGORIES_COMMON = { + SEQ: { + full: 'Sequencing Reads', + abbr: 'Seq', + }, + EXP: { + full: 'Transcriptome Profiling', + abbr: 'Exp', + }, + SNV: { + full: 'Simple Nucleotide Variation', + abbr: 'SNV', + }, + CNV: { + full: 'Copy Number Variation', + abbr: 'CNV', + }, + METH: { + full: 'DNA Methylation', + abbr: 'Meth', + }, +}; + export const DATA_CATEGORIES = { - SEQ: { full: 'Sequencing Reads', abbr: 'Seq' }, - EXP: { full: 'Transcriptome Profiling', abbr: 'Exp' }, - SNV: { full: 'Simple Nucleotide Variation', abbr: 'SNV' }, - CNV: { full: 'Copy Number Variation', abbr: 'CNV' }, - METH: { full: 'DNA Methylation', abbr: 'Meth' }, - CLINICAL: { full: 'Clinical', abbr: 'Clinical' }, - BIOSPECIMEN: { full: 'Biospecimen', abbr: 'Bio' }, + ...DATA_CATEGORIES_COMMON, + CLINICAL: { + full: 'Clinical', + abbr: 'Clinical', + }, + BIOSPECIMEN: { + full: 'Biospecimen', + abbr: 'Bio', + }, +}; + +export const DATA_CATEGORIES_FOR_PROJECTS_TABLE = { + ...DATA_CATEGORIES_COMMON, + CLINICAL_METADATA: { + full: '', + abbr: 'Clinical', + tooltip: 'Clinical Metadata', + }, + CLINICAL_SUPPLEMENT: { + full: 'Clinical', + dataCategory: 'Clinical', + abbr: 'Clinical Supplement', + tooltip: 'Clinical Supplement', + }, + BIOSPECIMEN_METADATA: { + full: '', + abbr: 'Bio', + tooltip: 'Biospecimen Metadata', + }, + BIOSPECIMEN_SUPPLEMENT: { + full: 'Biospecimen', + dataCategory: 'Bio', + abbr: 'Bio Supplement', + tooltip: 'Biospecimen Supplement', + }, }; export const DATA_TYPES = { - GEQ: { full: 'Gene Expression Quantification', abbr: 'GEQ' }, + GEQ: { + full: 'Gene Expression Quantification', + abbr: 'GEQ', + }, }; export const EXPERIMENTAL_STRATEGIES = [ @@ -115,7 +169,11 @@ export const MUTATION_SUBTYPE_MAP = { 'small insertion': 'Insertion', }; -export const DNA_CHANGE_MARKERS = ['del', 'ins', '>']; +export const DNA_CHANGE_MARKERS = [ + 'del', + 'ins', + '>', +]; export const HUMAN_BODY_SITES_MAP = { 'accessory sinuses': 'Head and Neck', @@ -287,20 +345,41 @@ export const IMPACT_SHORT_FORMS = { export const FAKE_USER = localStorage.REACT_APP_ALLOW_FAKE_USER || process.env.REACT_APP_ALLOW_FAKE_USER - ? { + ? { username: 'DEV_USER', projects: { phs_ids: { - phs000178: ['_member_', 'read', 'delete'], + phs000178: [ + '_member_', + 'read', + 'delete', + ], }, gdc_ids: { - 'TCGA-LIHC': ['read', 'delete', 'create', 'update', 'read_report'], - 'CGCI-BLGSP': ['create', 'update', 'release', 'read_report'], - 'TCGA-DEV3': ['read', 'create', 'update', 'release', 'delete'], + 'TCGA-LIHC': [ + 'read', + 'delete', + 'create', + 'update', + 'read_report', + ], + 'CGCI-BLGSP': [ + 'create', + 'update', + 'release', + 'read_report', + ], + 'TCGA-DEV3': [ + 'read', + 'create', + 'update', + 'release', + 'delete', + ], }, }, } - : null; + : null; export const IS_DEV = process.env.NODE_ENV === 'development'; @@ -324,4 +403,11 @@ export const CLINICAL_BLACKLIST = [ export const IS_CDAVE_DEV = localStorage.REACT_APP_IS_CDAVE_DEV || process.env.NODE_ENV === 'development' || - false; \ No newline at end of file + false; + +export const analysisColors = { + Demographic: '#1f77b4', + Diagnosis: '#ff7f0e', + Treatment: '#2ca02c', + Exposure: '#9467bd', +}; diff --git a/src/packages/@ncigdc/utils/data/types.ts b/src/packages/@ncigdc/utils/data/types.ts index 6106c9a89..070283dc0 100644 --- a/src/packages/@ncigdc/utils/data/types.ts +++ b/src/packages/@ncigdc/utils/data/types.ts @@ -15,13 +15,13 @@ export type TCategory = | 'Biospecimen'; export type TCategoryAbbr = - | 'Seq' - | 'Exp' - | 'SNV' - | 'CNV' - | 'Clinical' | 'Bio' - | 'Meth'; + | 'Clinical' + | 'CNV' + | 'Exp' + | 'Meth' + | 'Seq' + | 'SNV'; export type TCategoryMap = { [k in TCategoryAbbr]: TCategory }; diff --git a/src/packages/@ncigdc/utils/filters/index.ts b/src/packages/@ncigdc/utils/filters/index.ts index 44e7954a1..b859384ed 100644 --- a/src/packages/@ncigdc/utils/filters/index.ts +++ b/src/packages/@ncigdc/utils/filters/index.ts @@ -19,8 +19,8 @@ import { function compareTerms(a: IValueFilter, b: IValueFilter): boolean { return ( - a.content.field === b.content.field && - a.op.toLowerCase() === b.op.toLowerCase() + a.content && (a.content.field === b.content.field) && + a.op && (a.op.toLowerCase() === b.op.toLowerCase()) ); } @@ -82,7 +82,6 @@ const replace: TMergeFilters = (x, y) => ({ }); const addIn: TMergeFilters = (x, y) => ({ - op: 'and', content: y.content .reduce((acc, curr) => { const found = acc.find(a => compareTerms(a, curr)); @@ -95,6 +94,7 @@ const addIn: TMergeFilters = (x, y) => ({ ].filter(removeNoValueFilter); }, x.content) .sort(sortFilters), + op: y.op || 'and', }); const filterNoContent = (f: IGroupFilter) => (f.content.length ? f : null); diff --git a/src/packages/@ncigdc/utils/withFacetSelection.js b/src/packages/@ncigdc/utils/withFacetSelection.js index c7f5bc987..5fb4cb11a 100644 --- a/src/packages/@ncigdc/utils/withFacetSelection.js +++ b/src/packages/@ncigdc/utils/withFacetSelection.js @@ -2,7 +2,13 @@ /* eslint fp/no-this: 0, max-len: 1 */ import _ from 'lodash'; import { connect } from 'react-redux'; -import { withState, withProps, withHandlers, compose } from 'recompose'; +import { + compose, + setDisplayName, + withHandlers, + withProps, + withState, +} from 'recompose'; import { add, remove, reset } from '@ncigdc/dux/customFacets'; import withRouter from '@ncigdc/utils/withRouter'; import { removeFilter } from '@ncigdc/utils/filters/index'; @@ -21,57 +27,63 @@ export default ({ presetFacetFields, validFacetDocTypes, validFacetPrefixes, -}: TProps) => - compose( - connect((state, props) => ({ - userSelectedFacets: state.customFacets[entityType], - })), - withState('shouldShowFacetSelection', 'setShouldShowFacetSelection', false), - withProps(({ userSelectedFacets }) => ({ - facetExclusionTest: facet => { - const facetFieldNamesToExclude = presetFacetFields.concat( - userSelectedFacets.map(x => x.field), - ); - const match = _.some([ - !_.includes(validFacetDocTypes, facet.doc_type), - _.includes(facetFieldNamesToExclude, facet.field), - validFacetPrefixes && +}: TProps) => compose( + setDisplayName('WithFacetSelection'), + connect((state, props) => ({ + userSelectedFacets: state.customFacets[entityType], + })), + withState('shouldShowFacetSelection', 'setShouldShowFacetSelection', false), + withProps(({ userSelectedFacets }) => ({ + facetExclusionTest: facet => { + const facetFieldNamesToExclude = presetFacetFields.concat( + userSelectedFacets.map(x => x.field), + ); + const match = _.some([ + !_.includes(validFacetDocTypes, facet.doc_type), + _.includes(facetFieldNamesToExclude, facet.field), + validFacetPrefixes && !_.includes(validFacetPrefixes.map(p => facet.full.indexOf(p)), 0), - ]); - return match; - }, - })), - withRouter, - withHandlers({ - handleSelectFacet: ({ - userSelectedFacets, - setShouldShowFacetSelection, - dispatch, - }) => facet => { - setShouldShowFacetSelection(false); - dispatch(add({ entityType, facet })); - }, - handleResetFacets: ({ dispatch }) => () => { - dispatch(reset({ entityType })); - }, - handleRequestRemoveFacet: ({ - userSelectedFacets, - dispatch, - push, - query, - }) => facet => { - dispatch(remove({ entityType, field: facet.field })); - const newFilters = removeFilter( - facet.full, - parseFilterParam(query.filters), - ); + ]); + return match; + }, + })), + withRouter, + withHandlers({ + handleSelectFacet: ({ + dispatch, + setShouldShowFacetSelection, + userSelectedFacets, + }) => facet => { + setShouldShowFacetSelection(false); + dispatch(add({ + entityType, + facet, + })); + }, + handleResetFacets: ({ dispatch }) => () => { + dispatch(reset({ entityType })); + }, + handleRequestRemoveFacet: ({ + dispatch, + push, + query, + userSelectedFacets, + }) => facet => { + dispatch(remove({ + entityType, + field: facet.field, + })); + const newFilters = removeFilter( + facet.full, + parseFilterParam(query.filters), + ); - return push({ - query: removeEmptyKeys({ - ...query, - filters: newFilters && stringifyJSONParam(newFilters), - }), - }); - }, - }), - ); + return push({ + query: removeEmptyKeys({ + ...query, + filters: newFilters && stringifyJSONParam(newFilters), + }), + }); + }, + }), +); diff --git a/src/packages/@ncigdc/utils/wrapSvg.js b/src/packages/@ncigdc/utils/wrapSvg.js index 60b28f5f5..5d4f70d74 100644 --- a/src/packages/@ncigdc/utils/wrapSvg.js +++ b/src/packages/@ncigdc/utils/wrapSvg.js @@ -67,7 +67,7 @@ function buildForeignObject({ }): { html: string, height: number } { const foreignObjects = elements.filter(Boolean); // $FlowIgnore - const elementsHeight = sum(foreignObjects.map(e => e.offsetHeight || 15)); + const elementsHeight = sum(foreignObjects.map(e => (e.className === 'p-value' ? 25 : e.offsetHeight || 17))); return { height: elementsHeight, @@ -175,10 +175,10 @@ const wrapSvg = ({ 22, ])}" viewBox="0 0 ${width} ${sum([ - height, - afterObject.height, - 22, -])}" + height, + afterObject.height, + 22, + ])}" style="font-size: 10px" class="${EXPORT_CLASS} ${svgClass || ''} ${className}" > @@ -191,14 +191,14 @@ const wrapSvg = ({ ${beforeObject.html} ${rightObject.html} + titleHeight, + margins.top, + beforeObject.height, + ])})"> ${svg.innerHTML.replace( - /url\(['"]?https?:\/\/[^#]+(#.+)['"]?\)/g, - 'url($1)', - )} + /url\(['"]?https?:\/\/[^#]+(#.+)['"]?\)/g, + 'url($1)', + )} ${afterObject.html} ${legends diff --git a/tslint.json b/tslint.json index 5d5e0f0e3..405081b63 100644 --- a/tslint.json +++ b/tslint.json @@ -11,7 +11,8 @@ "coverage/lcov-report/*.js", "__mocks__/*.js", "data/*.js", - "public/*.js" + "public/*.js", + "src/packages/@oncojs/**/*" ] }, "rules": { @@ -77,4 +78,4 @@ "allow-snake-case" ] } -} \ No newline at end of file +}
Therapeutic AgentsTreatment Intent TypeTreatment or TherapyDays to Treatment Start
UUIDTherapeutic AgentsTreatment Intent TypeTreatment or TherapyDays to Treatment Start {title}