From e9b5c4f5e4304b6d839b24accaec82769e28fb8f Mon Sep 17 00:00:00 2001 From: Rikin Kachhia Date: Fri, 26 Jul 2019 13:08:59 +0530 Subject: [PATCH 01/27] show error stack trace on console error page for easier bug reporting (close #2598) (#2597) --- console/src/components/Error/ErrorBoundary.js | 4 ++-- console/src/components/Error/ErrorPage.scss | 5 +++++ console/src/components/Error/RuntimeError.js | 6 +++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/console/src/components/Error/ErrorBoundary.js b/console/src/components/Error/ErrorBoundary.js index 271d7169e31..6ef3ca1156a 100644 --- a/console/src/components/Error/ErrorBoundary.js +++ b/console/src/components/Error/ErrorBoundary.js @@ -54,7 +54,7 @@ class ErrorBoundary extends React.Component { render() { const { metadata } = this.props; - const { hasError, type } = this.state; + const { hasError, type, error } = this.state; if (hasError && metadata.ongoingRequest) { return ( @@ -68,7 +68,7 @@ class ErrorBoundary extends React.Component { return type === '404' ? ( ) : ( - + ); } diff --git a/console/src/components/Error/ErrorPage.scss b/console/src/components/Error/ErrorPage.scss index bc49f6931b3..ac33f894368 100644 --- a/console/src/components/Error/ErrorPage.scss +++ b/console/src/components/Error/ErrorPage.scss @@ -27,6 +27,11 @@ .message p > a { font-weight: bold; } + + .errorStack { + max-height: 300px; + width: 450px; + } } } diff --git a/console/src/components/Error/RuntimeError.js b/console/src/components/Error/RuntimeError.js index 8a614e3ee0c..88e10a48bfd 100644 --- a/console/src/components/Error/RuntimeError.js +++ b/console/src/components/Error/RuntimeError.js @@ -10,7 +10,7 @@ class RuntimeError extends Component { const errorImage = require('./error-logo.png'); const styles = require('./ErrorPage.scss'); - const { resetCallback } = this.props; + const { resetCallback, error } = this.props; return (
@@ -28,6 +28,10 @@ class RuntimeError extends Component { .

+
+
{error.stack}
+
+
You can report this issue on our{' '} From 47792f85b0393ef4d2b1324a9af47c4592f71d4f Mon Sep 17 00:00:00 2001 From: Rikin Kachhia Date: Fri, 26 Jul 2019 13:16:49 +0530 Subject: [PATCH 02/27] fix radio btn selection on data input in edit row page (close #2595) (#2600) --- .../src/components/Services/Data/TableBrowseRows/EditItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/src/components/Services/Data/TableBrowseRows/EditItem.js b/console/src/components/Services/Data/TableBrowseRows/EditItem.js index 1fc88f16c09..3975dccfc2c 100644 --- a/console/src/components/Services/Data/TableBrowseRows/EditItem.js +++ b/console/src/components/Services/Data/TableBrowseRows/EditItem.js @@ -82,7 +82,7 @@ class EditItem extends Component { refs[colName].valueNode = node; }; const clicker = e => { - e.target.parentNode.click(); + e.target.closest('.radio-inline').click(); e.target.focus(); }; From ce30fa8488e51a4b82df65c930e756f795e1dde5 Mon Sep 17 00:00:00 2001 From: Praveen Durairaj Date: Fri, 26 Jul 2019 14:42:00 +0530 Subject: [PATCH 03/27] community: add gatsby-contentful-auth0 sample app (#2603) --- .../gatsby-contentful-auth0/README.md | 47 + .../gatsby-contentful-auth0/app/.env.EXAMPLE | 5 + .../gatsby-contentful-auth0/app/.gitignore | 71 + .../gatsby-contentful-auth0/app/.prettierrc | 7 + .../gatsby-contentful-auth0/app/README.md | 28 + .../app/gatsby-browser.js | 31 + .../app/gatsby-config.js | 22 + .../app/gatsby-node.js | 37 + .../app/package-lock.json | 12385 ++++++++++++++++ .../gatsby-contentful-auth0/app/package.json | 35 + .../app/src/components/Playlist.js | 116 + .../app/src/components/style.css | 14 + .../app/src/pages/account.js | 59 + .../app/src/pages/callback.js | 10 + .../app/src/pages/index.js | 9 + .../app/src/utils/auth.js | 84 + .../app/static/favicon.ico | Bin 0 -> 2813 bytes .../auth0/insert_user_rule.js | 32 + .../hasura/config.yaml | 1 + .../1563970185567_init_schema.up.sql | 70 + .../1563970259491_init_metadata.up.yaml | 169 + ...create_remote_relationship_track.down.yaml | 6 + ...k_create_remote_relationship_track.up.yaml | 14 + 23 files changed, 13252 insertions(+) create mode 100644 community/sample-apps/gatsby-contentful-auth0/README.md create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/.env.EXAMPLE create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/.gitignore create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/.prettierrc create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/README.md create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/gatsby-browser.js create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/gatsby-config.js create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/gatsby-node.js create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/package-lock.json create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/package.json create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/src/components/Playlist.js create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/src/components/style.css create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/src/pages/account.js create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/src/pages/callback.js create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/src/pages/index.js create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/src/utils/auth.js create mode 100644 community/sample-apps/gatsby-contentful-auth0/app/static/favicon.ico create mode 100644 community/sample-apps/gatsby-contentful-auth0/auth0/insert_user_rule.js create mode 100644 community/sample-apps/gatsby-contentful-auth0/hasura/config.yaml create mode 100644 community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1563970185567_init_schema.up.sql create mode 100644 community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1563970259491_init_metadata.up.yaml create mode 100644 community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1564120661494_table_playlist_track_create_remote_relationship_track.down.yaml create mode 100644 community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1564120661494_table_playlist_track_create_remote_relationship_track.up.yaml diff --git a/community/sample-apps/gatsby-contentful-auth0/README.md b/community/sample-apps/gatsby-contentful-auth0/README.md new file mode 100644 index 00000000000..25b1d858077 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/README.md @@ -0,0 +1,47 @@ +# gatsby-contentful-auth0 +This is the sample music playlist application demonstrating the Gatsby + Contentful Remote Join with Hasura GraphQL. + +## Getting started + +If you've cloned this repository, navigate into the directory and install the npm modules using this command: + +```bash +npm install +``` + +> Note: if you clone this project through the Gatsby CLI, it will install the modules for you. + +## Auth0 +This application uses Auth0 to manage identity. Refer to the [Auth0 integration guide](https://docs.hasura.io/1.0/graphql/manual/guides/integrations/auth0-jwt.html) for the configuration. + +### Modify auth config + +Rename `.env.EXAMPLE` to `.env.development` (or `.env.production`) and replace `` for `AUTH0_DOMAIN` and `AUTH0_CLIENTID` with your Auth0 domain prefix and your client ID. These can be found on your [client dashboard](https://manage.auth0.com/#/clients). + +Replace the `` for `AUTH0_CALLBACK` with the URL for your callback route. The default for development is `http://localhost:8000/callback`. + +## Contentful +Contentful remote schema is added as part of the migration. Configure the environment variables in Hasura GraphQL Engine server for the types to get merged. + +- `CONTENTFUL_API_KEY` +- `CONTENTFUL_API_ENDPOINT` which is of the format https://graphql.contentful.com/content/v1/spaces/ + +## Migrations + +Execute the following command inside `hasura` to apply the migrations + +```bash +hasura migrate apply +``` + +This will create all the necessary tables, relationships and remote joins. + +## Run the app +You can start the development server with the following command: + +```bash +gatsby develop +``` + +The app runs at `localhost:8000` by default. + diff --git a/community/sample-apps/gatsby-contentful-auth0/app/.env.EXAMPLE b/community/sample-apps/gatsby-contentful-auth0/app/.env.EXAMPLE new file mode 100644 index 00000000000..57d3d1298df --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/.env.EXAMPLE @@ -0,0 +1,5 @@ +# ./.env +# Get these values at https://manage.auth0.com and create a new file called .env.development +AUTH0_DOMAIN= +AUTH0_CLIENTID= +AUTH0_CALLBACK= \ No newline at end of file diff --git a/community/sample-apps/gatsby-contentful-auth0/app/.gitignore b/community/sample-apps/gatsby-contentful-auth0/app/.gitignore new file mode 100644 index 00000000000..e557c20d8ad --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/.gitignore @@ -0,0 +1,71 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# dotenv environment variables file +.env +.env.* +!.env.EXAMPLE + +# gatsby files +.cache/ +public + +# Mac files +.DS_Store + +# Yarn +yarn-error.log +.pnp/ +.pnp.js +# Yarn Integrity file +.yarn-integrity diff --git a/community/sample-apps/gatsby-contentful-auth0/app/.prettierrc b/community/sample-apps/gatsby-contentful-auth0/app/.prettierrc new file mode 100644 index 00000000000..48e90e8d402 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/.prettierrc @@ -0,0 +1,7 @@ +{ + "endOfLine": "lf", + "semi": false, + "singleQuote": false, + "tabWidth": 2, + "trailingComma": "es5" +} diff --git a/community/sample-apps/gatsby-contentful-auth0/app/README.md b/community/sample-apps/gatsby-contentful-auth0/app/README.md new file mode 100644 index 00000000000..9222184b4d5 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/README.md @@ -0,0 +1,28 @@ +# gatsby-contentful-auth0 +This is the sample music playlist application demonstrating the Gatsby + Contentful Remote Join with Hasura GraphQL. + +## Getting started + +If you've cloned this repository, navigate into the directory and install the npm modules using this command: + +```bash +npm install +``` + +> Note: if you clone this project through the Gatsby CLI, it will install the modules for you. + +## Modify auth config + +Rename `.env.EXAMPLE` to `.env.development` (or `.env.production`) and replace `` for `AUTH0_DOMAIN` and `AUTH0_CLIENTID` with your Auth0 domain prefix and your client ID. These can be found on your [client dashboard](https://manage.auth0.com/#/clients). + +Replace the `` for `AUTH0_CALLBACK` with the URL for your callback route. The default for development is `http://localhost:8000/callback`. + +## Run the app +You can start the development server with the following command: + +```bash +gatsby develop +``` + +The app runs at `localhost:8000` by default. + diff --git a/community/sample-apps/gatsby-contentful-auth0/app/gatsby-browser.js b/community/sample-apps/gatsby-contentful-auth0/app/gatsby-browser.js new file mode 100644 index 00000000000..0722bb76f14 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/gatsby-browser.js @@ -0,0 +1,31 @@ +import React from "react" +import { silentAuth } from "./src/utils/auth" + +class SessionCheck extends React.Component { + constructor(props) { + super(props) + this.state = { + loading: true, + } + } + + handleCheckSession = () => { + this.setState({ loading: false }) + } + + componentDidMount() { + silentAuth(this.handleCheckSession) + } + + render() { + return ( + this.state.loading === false && ( + {this.props.children} + ) + ) + } +} + +export const wrapRootElement = ({ element }) => { + return {element} +} diff --git a/community/sample-apps/gatsby-contentful-auth0/app/gatsby-config.js b/community/sample-apps/gatsby-contentful-auth0/app/gatsby-config.js new file mode 100644 index 00000000000..e04f17d5610 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/gatsby-config.js @@ -0,0 +1,22 @@ +const fetch = require(`node-fetch`) +const { createHttpLink } = require(`apollo-link-http`) + +module.exports = { + plugins: [ + { + resolve: 'gatsby-source-graphql', + options: { + typeName: 'HASURA', + fieldName: 'hasura', + createLink: (pluginOptions) => { + return createHttpLink({ + uri: 'http://localhost:8080/v1/graphql', + headers: { + }, + fetch, + }) + }, + }, + }, + ] +}; diff --git a/community/sample-apps/gatsby-contentful-auth0/app/gatsby-node.js b/community/sample-apps/gatsby-contentful-auth0/app/gatsby-node.js new file mode 100644 index 00000000000..350d64d968a --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/gatsby-node.js @@ -0,0 +1,37 @@ +// ./gatsby-node.js +// Implement the Gatsby API “onCreatePage”. This is +// called after every page is created. +exports.onCreatePage = async ({ page, actions }) => { + const { createPage } = actions + + // page.matchPath is a special key that's used for matching pages + // only on the client. + if (page.path.match(/^\/account/)) { + page.matchPath = "/account/*" + + // Update the page. + createPage(page) + } +} + +exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => { + if (stage === "build-html") { + /* + * During the build step, `auth0-js` will break because it relies on + * browser-specific APIs. Fortunately, we don’t need it during the build. + * Using Webpack’s null loader, we’re able to effectively ignore `auth0-js` + * during the build. (See `src/utils/auth.js` to see how we prevent this + * from breaking the app.) + */ + actions.setWebpackConfig({ + module: { + rules: [ + { + test: /auth0-js/, + use: loaders.null(), + }, + ], + }, + }) + } +} diff --git a/community/sample-apps/gatsby-contentful-auth0/app/package-lock.json b/community/sample-apps/gatsby-contentful-auth0/app/package-lock.json new file mode 100644 index 00000000000..dc9631b79b5 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/package-lock.json @@ -0,0 +1,12385 @@ +{ + "name": "gatsby-contentful-hasura", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.3.tgz", + "integrity": "sha512-oDpASqKFlbspQfzAE7yaeTmdljSH2ADIvBlb0RwbStltTuWa0+7CCI1fYVINNv9saHPa1W7oaKeuNuKj+RQCvA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.0", + "@babel/helpers": "^7.4.3", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@babel/generator": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz", + "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==", + "requires": { + "@babel/types": "^7.4.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@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-builder-binary-assignment-operator-visitor": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", + "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "requires": { + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-react-jsx": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz", + "integrity": "sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw==", + "requires": { + "@babel/types": "^7.3.0", + "esutils": "^2.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.0.tgz", + "integrity": "sha512-SdqDfbVdNQCBp3WhK2mNdDvHd3BD6qbmIc43CAyjnsfCmgHMeqgDcM3BzY2lchi7HBJGJ2CVdynLWbezaE4mmQ==", + "requires": { + "@babel/helper-hoist-variables": "^7.4.0", + "@babel/traverse": "^7.4.0", + "@babel/types": "^7.4.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.3.tgz", + "integrity": "sha512-UMl3TSpX11PuODYdWGrUeW6zFkdYhDn7wRLrOuNVM6f9L+S9CzmDXYyrp3MTHcwWjnzur1f/Op8A7iYZWya2Yg==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.4.0", + "@babel/helper-split-export-declaration": "^7.4.0" + } + }, + "@babel/helper-define-map": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.0.tgz", + "integrity": "sha512-wAhQ9HdnLIywERVcSvX40CEJwKdAa1ID4neI9NXQPDOHwwA+57DqwLiPEVy2AIyWzAk0CQ8qx4awO0VUURwLtA==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.4.0", + "lodash": "^4.17.11" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", + "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "requires": { + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.0.tgz", + "integrity": "sha512-/NErCuoe/et17IlAQFKWM24qtyYYie7sFIrW/tIQXpck6vAu2hhtYYsKLBWQV+BQZMbcIYPU/QMYuTufrY4aQw==", + "requires": { + "@babel/types": "^7.4.0" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", + "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "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/helper-module-transforms": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.3.tgz", + "integrity": "sha512-H88T9IySZW25anu5uqyaC1DaQre7ofM+joZtAaO2F8NBdFfupH0SZ4gKjgSFVcvtx/aAirqA9L9Clio2heYbZA==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/template": "^7.2.2", + "@babel/types": "^7.2.2", + "lodash": "^4.17.11" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", + "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" + }, + "@babel/helper-regex": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.3.tgz", + "integrity": "sha512-hnoq5u96pLCfgjXuj8ZLX3QQ+6nAulS+zSgi6HulUwFbEruRAKwbGLU5OvXkE14L8XW6XsQEKsIDfgthKLRAyA==", + "requires": { + "lodash": "^4.17.11" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.0.tgz", + "integrity": "sha512-PVwCVnWWAgnal+kJ+ZSAphzyl58XrFeSKSAJRiqg5QToTsjL+Xu1f9+RJ+d+Q0aPhPfBGaYfkox66k86thxNSg==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.4.0", + "@babel/types": "^7.4.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "requires": { + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz", + "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==", + "requires": { + "@babel/types": "^7.4.0" + } + }, + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" + } + }, + "@babel/helpers": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.3.tgz", + "integrity": "sha512-BMh7X0oZqb36CfyhvtbSmcWc3GXocfxv3yNsAEuM0l+fAqSO22rQrUpijr3oE/10jCTrB6/0b9kzmG4VetCj8Q==", + "requires": { + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.3.tgz", + "integrity": "sha512-gxpEUhTS1sGA63EGQGuA+WESPR/6tz6ng7tSHFCmaTJK/cGK8y37cBTspX+U2xCAue2IQVvF6Z0oigmjwD8YGQ==" + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", + "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.0.tgz", + "integrity": "sha512-t2ECPNOXsIeK1JxJNKmgbzQtoG27KIlVE61vTqX0DKR9E9sZlVVxWUtEW9D5FlZ8b8j7SBNCHY47GgPKCKlpPg==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.4.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", + "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.2.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.3.tgz", + "integrity": "sha512-xC//6DNSSHVjq8O2ge0dyYlhshsH4T7XdCVoxbi5HzLYWfsC5ooFlJjrXk8RcAT+hjHAK9UjBXdylzSoDK3t4g==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.0.tgz", + "integrity": "sha512-h/KjEZ3nK9wv1P1FSNb9G079jXrNYR0Ko+7XkOx85+gM24iZbPn0rh4vCftk+5QKY7y1uByFataBTmX7irEF1w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.5.4" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", + "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.2.0.tgz", + "integrity": "sha512-UxYaGXYQ7rrKJS/PxIKRkv3exi05oH7rokBAsmCSsCxz1sVPZ7Fu6FzKoGgUvmY+0YgSkYHgUoCh5R5bCNBQlw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", + "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz", + "integrity": "sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", + "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", + "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", + "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.0.tgz", + "integrity": "sha512-EeaFdCeUULM+GPFEsf7pFcNSxM7hYjoj5fiYbyuiXobW4JhFnjAv9OWzNwHyHcKoPNpAfeRDuW6VyaXEDUBa7g==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", + "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.0.tgz", + "integrity": "sha512-AWyt3k+fBXQqt2qb9r97tn3iBwFpiv9xdAiG+Gr2HpAZpuayvbL55yWrsV3MyHvXk/4vmSiedhDRl1YI2Iy5nQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.11" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.3.tgz", + "integrity": "sha512-PUaIKyFUDtG6jF5DUJOfkBdwAS/kFFV3XFk7Nn0a6vR7ZT8jYw5cGtIlat77wcnd0C6ViGqo/wyNf4ZHytF/nQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.4.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.4.0", + "@babel/helper-split-export-declaration": "^7.4.0", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", + "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.3.tgz", + "integrity": "sha512-rVTLLZpydDFDyN4qnXdzwoVpk1oaXHIvPEOkOLyr88o7oHxVc/LyrnDx+amuBWGOwUb7D1s/uLsKBNTx08htZg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.3.tgz", + "integrity": "sha512-9Arc2I0AGynzXRR/oPdSALv3k0rM38IMFyto7kOCwb5F9sLUt2Ykdo3V9yUPR+Bgr4kb6bVEyLkPEiBhzcTeoA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.3", + "regexpu-core": "^4.5.4" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", + "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.0.tgz", + "integrity": "sha512-C4ZVNejHnfB22vI2TYN4RUp2oCmq6cSEAg4RygSvYZUECRqUu9O4PMEMNJ4wsemaRGg27BbgYctG4BZh+AgIHw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.3.tgz", + "integrity": "sha512-UselcZPwVWNSURnqcfpnxtMehrb8wjXYOimlYQPBnup/Zld426YzIhNEvuRsEWVHfESIECGrxoI6L5QqzuLH5Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.3.tgz", + "integrity": "sha512-uT5J/3qI/8vACBR9I1GlAuU/JqBtWdfCrynuOkrWG6nCDieZd5przB1vfP59FRHBZQ9DC2IUfqr/xKqzOD5x0A==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", + "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", + "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", + "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.3.tgz", + "integrity": "sha512-sMP4JqOTbMJMimqsSZwYWsMjppD+KRyDIUVW91pd7td0dZKAvPmhCaxhOzkzLParKwgQc7bdL9UNv+rpJB0HfA==", + "requires": { + "@babel/helper-module-transforms": "^7.4.3", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.0.tgz", + "integrity": "sha512-gjPdHmqiNhVoBqus5qK60mWPp1CmYWp/tkh11mvb0rrys01HycEGD7NvvSoKXlWEfSM9TcL36CpsK8ElsADptQ==", + "requires": { + "@babel/helper-hoist-variables": "^7.4.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", + "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.2.tgz", + "integrity": "sha512-NsAuliSwkL3WO2dzWTOL1oZJHm0TM8ZY8ZSxk2ANyKkt5SQlToGA4pzctmq1BEjoacurdwZ3xp2dCQWJkME0gQ==", + "requires": { + "regexp-tree": "^0.1.0" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.0.tgz", + "integrity": "sha512-6ZKNgMQmQmrEX/ncuCwnnw1yVGoaOW5KpxNhoWI7pCQdA0uZ0HqHGqenCUIENAnxRjy2WwNQ30gfGdIgqJXXqw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", + "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.3.tgz", + "integrity": "sha512-ULJYC2Vnw96/zdotCZkMGr2QVfKpIT/4/K+xWWY0MbOJyMZuk660BGkr3bEKWQrrciwz6xpmft39nA4BF7hJuA==", + "requires": { + "@babel/helper-call-delegate": "^7.4.0", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", + "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz", + "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz", + "integrity": "sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg==", + "requires": { + "@babel/helper-builder-react-jsx": "^7.3.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz", + "integrity": "sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz", + "integrity": "sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.3.tgz", + "integrity": "sha512-kEzotPuOpv6/iSlHroCDydPkKYw7tiJGKlmYp6iJn4a6C/+b2FdttlJsLKYxolYHgotTJ5G5UY5h0qey5ka3+A==", + "requires": { + "regenerator-transform": "^0.13.4" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz", + "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.4.3.tgz", + "integrity": "sha512-7Q61bU+uEI7bCUFReT1NKn7/X6sDQsZ7wL1sJ9IYMAO7cI+eg6x9re1cEw2fCRMbbTVyoeUKWSV1M6azEfKCfg==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "resolve": "^1.8.1", + "semver": "^5.5.1" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", + "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", + "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", + "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz", + "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", + "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.3.tgz", + "integrity": "sha512-lnSNgkVjL8EMtnE8eSS7t2ku8qvKH3eqNf/IwIfnSPUqzgqYmRwzdsQWv4mNQAN9Nuo6Gz1Y0a4CSmdpu1Pp6g==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.3", + "regexpu-core": "^4.5.4" + } + }, + "@babel/polyfill": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.3.tgz", + "integrity": "sha512-rkv8WIvJshA5Ev8iNMGgz5WZkRtgtiPexiT7w5qevGTuT7ZBfM3de9ox1y9JR5/OXb/sWGBbWlHNa7vQKqku3Q==", + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/preset-env": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.3.tgz", + "integrity": "sha512-FYbZdV12yHdJU5Z70cEg0f6lvtpZ8jFSDakTm7WXeJbLXh4R0ztGEu/SW7G1nJ2ZvKwDhz8YrbA84eYyprmGqw==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-json-strings": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.4.3", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.0", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-json-strings": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.2.0", + "@babel/plugin-transform-async-to-generator": "^7.4.0", + "@babel/plugin-transform-block-scoped-functions": "^7.2.0", + "@babel/plugin-transform-block-scoping": "^7.4.0", + "@babel/plugin-transform-classes": "^7.4.3", + "@babel/plugin-transform-computed-properties": "^7.2.0", + "@babel/plugin-transform-destructuring": "^7.4.3", + "@babel/plugin-transform-dotall-regex": "^7.4.3", + "@babel/plugin-transform-duplicate-keys": "^7.2.0", + "@babel/plugin-transform-exponentiation-operator": "^7.2.0", + "@babel/plugin-transform-for-of": "^7.4.3", + "@babel/plugin-transform-function-name": "^7.4.3", + "@babel/plugin-transform-literals": "^7.2.0", + "@babel/plugin-transform-member-expression-literals": "^7.2.0", + "@babel/plugin-transform-modules-amd": "^7.2.0", + "@babel/plugin-transform-modules-commonjs": "^7.4.3", + "@babel/plugin-transform-modules-systemjs": "^7.4.0", + "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.2", + "@babel/plugin-transform-new-target": "^7.4.0", + "@babel/plugin-transform-object-super": "^7.2.0", + "@babel/plugin-transform-parameters": "^7.4.3", + "@babel/plugin-transform-property-literals": "^7.2.0", + "@babel/plugin-transform-regenerator": "^7.4.3", + "@babel/plugin-transform-reserved-words": "^7.2.0", + "@babel/plugin-transform-shorthand-properties": "^7.2.0", + "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-sticky-regex": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.2.0", + "@babel/plugin-transform-typeof-symbol": "^7.2.0", + "@babel/plugin-transform-unicode-regex": "^7.4.3", + "@babel/types": "^7.4.0", + "browserslist": "^4.5.2", + "core-js-compat": "^3.0.0", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.5.0" + }, + "dependencies": { + "browserslist": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", + "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "requires": { + "caniuse-lite": "^1.0.30000955", + "electron-to-chromium": "^1.3.122", + "node-releases": "^1.1.13" + } + } + } + }, + "@babel/preset-react": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", + "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0" + } + }, + "@babel/runtime": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.3.tgz", + "integrity": "sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz", + "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.0", + "@babel/types": "^7.4.0" + } + }, + "@babel/traverse": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.3.tgz", + "integrity": "sha512-HmA01qrtaCwwJWpSKpA948cBvU5BrmviAief/b3AVw936DtcdsTexlbyzNuDnthwhOQ37xshn7hvQaEQk7ISYQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/types": "^7.4.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@babel/types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz", + "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "@gatsbyjs/relay-compiler": { + "version": "2.0.0-printer-fix.2", + "resolved": "https://registry.npmjs.org/@gatsbyjs/relay-compiler/-/relay-compiler-2.0.0-printer-fix.2.tgz", + "integrity": "sha512-7GeCCEQ7O15lMTT/SXy9HuRde4cv5vs465ZnLK2QCajSDLior+20yrMqHn1PGsJYK6nNZH7p3lw9qTCpqmuc7Q==", + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/polyfill": "^7.0.0", + "@babel/runtime": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "babel-preset-fbjs": "^3.1.2", + "chalk": "^2.4.1", + "fast-glob": "^2.2.2", + "fb-watchman": "^2.0.0", + "fbjs": "^1.0.0", + "immutable": "~3.7.6", + "nullthrows": "^1.1.0", + "relay-runtime": "2.0.0", + "signedsource": "^1.0.0", + "yargs": "^9.0.0" + } + }, + "@mikaelkristiansson/domready": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mikaelkristiansson/domready/-/domready-1.0.9.tgz", + "integrity": "sha512-FOAjeRHULSWXd6JMuCDwf3zPbe11kP971+Bufrj9M8rQ33ZMtThgKd6IJgzj6tr/+1Rq3czzLI1LAa9x0IC92w==" + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" + }, + "@pieh/friendly-errors-webpack-plugin": { + "version": "1.7.0-chalk-2", + "resolved": "https://registry.npmjs.org/@pieh/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.0-chalk-2.tgz", + "integrity": "sha512-65+vYGuDkHBCWWjqzzR/Ck318+d6yTI00EqII9qe3aPD1J3Olhvw0X38uM5moQb1PK/ksDXwSoPGt/5QhCiotw==", + "requires": { + "chalk": "^2.4.2", + "error-stack-parser": "^2.0.0", + "string-width": "^2.0.0", + "strip-ansi": "^3" + } + }, + "@reach/router": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.2.1.tgz", + "integrity": "sha512-kTaX08X4g27tzIFQGRukaHmNbtMYDS3LEWIS8+l6OayGIw6Oyo1HIF/JzeuR2FoF9z6oV+x/wJSVSq4v8tcUGQ==", + "requires": { + "create-react-context": "^0.2.1", + "invariant": "^2.2.3", + "prop-types": "^15.6.1", + "react-lifecycles-compat": "^3.0.4", + "warning": "^3.0.0" + } + }, + "@stefanprobst/lokijs": { + "version": "1.5.6-b", + "resolved": "https://registry.npmjs.org/@stefanprobst/lokijs/-/lokijs-1.5.6-b.tgz", + "integrity": "sha512-MNodHp46og+Sdde/LCxTLrxcD5Dimu21R/Fer2raXMG1XtHSV2+vZnkIV87OPAxuf2NiDj1W5hN7Q2MYUfQQ8w==" + }, + "@types/configstore": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/configstore/-/configstore-2.1.1.tgz", + "integrity": "sha1-zR6FU2M60xhcPy8jns/10mQ+krY=" + }, + "@types/debug": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.29.tgz", + "integrity": "sha1-oeUUrfvZLwOiJLpU1pMRHb8fN1Q=" + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + }, + "@types/get-port": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/get-port/-/get-port-0.0.4.tgz", + "integrity": "sha1-62u3Qj2fiItjJmDcfS/T5po1ZD4=" + }, + "@types/glob": { + "version": "5.0.36", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.36.tgz", + "integrity": "sha512-KEzSKuP2+3oOjYYjujue6Z3Yqis5HKA1BsIC+jZ1v3lrRNdsqyNNtX0rQf6LSuI4DJJ2z5UV//zBZCcvM0xikg==", + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/history": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.2.tgz", + "integrity": "sha512-ui3WwXmjTaY73fOQ3/m3nnajU/Orhi6cEu5rzX+BrAAJxa3eITXZ5ch9suPqtM03OWhAHhPSyBGCN4UKoxO20Q==" + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" + }, + "@types/mkdirp": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.3.29.tgz", + "integrity": "sha1-fyrX7FX5FEgvybHsS7GuYCjUYGY=" + }, + "@types/node": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-7.10.5.tgz", + "integrity": "sha512-RYkagUUbxQBss46ElbEa+j4q4X3GR12QwB7a/PM5hmVuVkYoW1jENT1+taspKUv8ibwW8cw+kRFbOaTc/Key3w==" + }, + "@types/prop-types": { + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.0.tgz", + "integrity": "sha512-eItQyV43bj4rR3JPV0Skpl1SncRCdziTEK9/v8VwXmV6d/qOUO8/EuWeHBbCZcsfSHfzI5UyMJLCSXtxxznyZg==" + }, + "@types/q": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", + "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==" + }, + "@types/reach__router": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.2.3.tgz", + "integrity": "sha512-Zp0AdVhoJXjwsgp8pDPVEMnAH5eHU64hi5EnPT1Jerddqwiy0O87KFrnZKd1DKdO87cU120n2d3SnKKPtf4wFA==", + "requires": { + "@types/history": "*", + "@types/react": "*" + } + }, + "@types/react": { + "version": "16.8.13", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.13.tgz", + "integrity": "sha512-otJ4ntMuHGrvm67CdDJMAls4WqotmAmW0g3HmWi9LCjSWXrxoXY/nHXrtmMfvPEEmGFNm6NdgMsJmnfH820Qaw==", + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } + }, + "@types/tmp": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.32.tgz", + "integrity": "sha1-DTyzECL4Qn6ljACK8yuA2hJspOM=" + }, + "@types/zen-observable": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.0.tgz", + "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==" + }, + "@webassemblyjs/ast": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", + "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", + "requires": { + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/wast-parser": "1.7.11" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", + "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", + "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", + "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==" + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", + "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", + "requires": { + "@webassemblyjs/wast-printer": "1.7.11" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", + "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==" + }, + "@webassemblyjs/helper-module-context": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", + "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==" + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", + "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", + "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", + "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", + "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", + "requires": { + "@xtuc/long": "4.2.1" + } + }, + "@webassemblyjs/utf8": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", + "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", + "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/helper-wasm-section": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11", + "@webassemblyjs/wasm-opt": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", + "@webassemblyjs/wast-printer": "1.7.11" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", + "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/ieee754": "1.7.11", + "@webassemblyjs/leb128": "1.7.11", + "@webassemblyjs/utf8": "1.7.11" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", + "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", + "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-api-error": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/ieee754": "1.7.11", + "@webassemblyjs/leb128": "1.7.11", + "@webassemblyjs/utf8": "1.7.11" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", + "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/floating-point-hex-parser": "1.7.11", + "@webassemblyjs/helper-api-error": "1.7.11", + "@webassemblyjs/helper-code-frame": "1.7.11", + "@webassemblyjs/helper-fsm": "1.7.11", + "@xtuc/long": "4.2.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", + "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/wast-parser": "1.7.11", + "@xtuc/long": "4.2.1" + } + }, + "@wry/context": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.4.4.tgz", + "integrity": "sha512-LrKVLove/zw6h2Md/KZyWxIkFM6AoyKp71OqpH9Hiip1csjPVoD3tPxlbQUNxEnHENks3UGgNpSBCAfq9KWuag==", + "requires": { + "@types/node": ">=6", + "tslib": "^1.9.3" + } + }, + "@wry/equality": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.9.tgz", + "integrity": "sha512-mB6ceGjpMGz1ZTza8HYnrPGos2mC6So4NhS1PtZ8s4Qt0K7fBiIGhpSxUbQmhwcSWE3no+bYxmI2OL6KuXYmoQ==", + "requires": { + "tslib": "^1.9.3" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", + "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==" + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" + }, + "acorn-dynamic-import": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", + "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", + "requires": { + "acorn": "^5.0.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + } + } + }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==" + }, + "address": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz", + "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==" + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" + }, + "ajv-keywords": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==" + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" + }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "requires": { + "string-width": "^2.0.0" + } + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==" + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "apollo-cache": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/apollo-cache/-/apollo-cache-1.3.2.tgz", + "integrity": "sha512-+KA685AV5ETEJfjZuviRTEImGA11uNBp/MJGnaCvkgr+BYRrGLruVKBv6WvyFod27WEB2sp7SsG8cNBKANhGLg==", + "requires": { + "apollo-utilities": "^1.3.2", + "tslib": "^1.9.3" + }, + "dependencies": { + "apollo-utilities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.2.tgz", + "integrity": "sha512-JWNHj8XChz7S4OZghV6yc9FNnzEXj285QYp/nLNh943iObycI5GTDO3NGR9Dth12LRrSFMeDOConPfPln+WGfg==", + "requires": { + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + } + }, + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, + "apollo-cache-inmemory": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/apollo-cache-inmemory/-/apollo-cache-inmemory-1.6.2.tgz", + "integrity": "sha512-AyCl3PGFv5Qv1w4N9vlg63GBPHXgMCekZy5mhlS042ji0GW84uTySX+r3F61ZX3+KM1vA4m9hQyctrEGiv5XjQ==", + "requires": { + "apollo-cache": "^1.3.2", + "apollo-utilities": "^1.3.2", + "optimism": "^0.9.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + }, + "dependencies": { + "apollo-utilities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.2.tgz", + "integrity": "sha512-JWNHj8XChz7S4OZghV6yc9FNnzEXj285QYp/nLNh943iObycI5GTDO3NGR9Dth12LRrSFMeDOConPfPln+WGfg==", + "requires": { + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + } + }, + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, + "apollo-client": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/apollo-client/-/apollo-client-2.6.3.tgz", + "integrity": "sha512-DS8pmF5CGiiJ658dG+mDn8pmCMMQIljKJSTeMNHnFuDLV0uAPZoeaAwVFiAmB408Ujqt92oIZ/8yJJAwSIhd4A==", + "requires": { + "@types/zen-observable": "^0.8.0", + "apollo-cache": "1.3.2", + "apollo-link": "^1.0.0", + "apollo-utilities": "1.3.2", + "symbol-observable": "^1.0.2", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3", + "zen-observable": "^0.8.0" + }, + "dependencies": { + "apollo-utilities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.2.tgz", + "integrity": "sha512-JWNHj8XChz7S4OZghV6yc9FNnzEXj285QYp/nLNh943iObycI5GTDO3NGR9Dth12LRrSFMeDOConPfPln+WGfg==", + "requires": { + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + } + }, + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, + "apollo-link": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.11.tgz", + "integrity": "sha512-PQvRCg13VduLy3X/0L79M6uOpTh5iHdxnxYuo8yL7sJlWybKRJwsv4IcRBJpMFbChOOaHY7Og9wgPo6DLKDKDA==", + "requires": { + "apollo-utilities": "^1.2.1", + "ts-invariant": "^0.3.2", + "tslib": "^1.9.3", + "zen-observable-ts": "^0.8.18" + } + }, + "apollo-link-http": { + "version": "1.5.15", + "resolved": "https://registry.npmjs.org/apollo-link-http/-/apollo-link-http-1.5.15.tgz", + "integrity": "sha512-epZFhCKDjD7+oNTVK3P39pqWGn4LEhShAoA1Q9e2tDrBjItNfviiE33RmcLcCURDYyW5JA6SMgdODNI4Is8tvQ==", + "requires": { + "apollo-link": "^1.2.12", + "apollo-link-http-common": "^0.2.14", + "tslib": "^1.9.3" + }, + "dependencies": { + "apollo-link": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.12.tgz", + "integrity": "sha512-fsgIAXPKThyMVEMWQsUN22AoQI+J/pVXcjRGAShtk97h7D8O+SPskFinCGEkxPeQpE83uKaqafB2IyWdjN+J3Q==", + "requires": { + "apollo-utilities": "^1.3.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3", + "zen-observable-ts": "^0.8.19" + } + }, + "apollo-utilities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.2.tgz", + "integrity": "sha512-JWNHj8XChz7S4OZghV6yc9FNnzEXj285QYp/nLNh943iObycI5GTDO3NGR9Dth12LRrSFMeDOConPfPln+WGfg==", + "requires": { + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + } + }, + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + }, + "zen-observable-ts": { + "version": "0.8.19", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.19.tgz", + "integrity": "sha512-u1a2rpE13G+jSzrg3aiCqXU5tN2kw41b+cBZGmnc+30YimdkKiDj9bTowcB41eL77/17RF/h+393AuVgShyheQ==", + "requires": { + "tslib": "^1.9.3", + "zen-observable": "^0.8.0" + } + } + } + }, + "apollo-link-http-common": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.14.tgz", + "integrity": "sha512-v6mRU1oN6XuX8beVIRB6OpF4q1ULhSnmy7ScnHnuo1qV6GaFmDcbdvXqxIkAV1Q8SQCo2lsv4HeqJOWhFfApOg==", + "requires": { + "apollo-link": "^1.2.12", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + }, + "dependencies": { + "apollo-link": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.12.tgz", + "integrity": "sha512-fsgIAXPKThyMVEMWQsUN22AoQI+J/pVXcjRGAShtk97h7D8O+SPskFinCGEkxPeQpE83uKaqafB2IyWdjN+J3Q==", + "requires": { + "apollo-utilities": "^1.3.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3", + "zen-observable-ts": "^0.8.19" + } + }, + "apollo-utilities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.2.tgz", + "integrity": "sha512-JWNHj8XChz7S4OZghV6yc9FNnzEXj285QYp/nLNh943iObycI5GTDO3NGR9Dth12LRrSFMeDOConPfPln+WGfg==", + "requires": { + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + } + }, + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + }, + "zen-observable-ts": { + "version": "0.8.19", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.19.tgz", + "integrity": "sha512-u1a2rpE13G+jSzrg3aiCqXU5tN2kw41b+cBZGmnc+30YimdkKiDj9bTowcB41eL77/17RF/h+393AuVgShyheQ==", + "requires": { + "tslib": "^1.9.3", + "zen-observable": "^0.8.0" + } + } + } + }, + "apollo-link-ws": { + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/apollo-link-ws/-/apollo-link-ws-1.0.18.tgz", + "integrity": "sha512-nrWh9m7k1FQw1AK1GB1VTJS0o01cpsP2RYmTAh2j+P4lL2/72WgsblhbuF+yA1/jsgVrzg6xa+TNw3UwgGp3+g==", + "requires": { + "apollo-link": "^1.2.12", + "tslib": "^1.9.3" + }, + "dependencies": { + "apollo-link": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.12.tgz", + "integrity": "sha512-fsgIAXPKThyMVEMWQsUN22AoQI+J/pVXcjRGAShtk97h7D8O+SPskFinCGEkxPeQpE83uKaqafB2IyWdjN+J3Q==", + "requires": { + "apollo-utilities": "^1.3.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3", + "zen-observable-ts": "^0.8.19" + } + }, + "apollo-utilities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.2.tgz", + "integrity": "sha512-JWNHj8XChz7S4OZghV6yc9FNnzEXj285QYp/nLNh943iObycI5GTDO3NGR9Dth12LRrSFMeDOConPfPln+WGfg==", + "requires": { + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + } + }, + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + }, + "zen-observable-ts": { + "version": "0.8.19", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.19.tgz", + "integrity": "sha512-u1a2rpE13G+jSzrg3aiCqXU5tN2kw41b+cBZGmnc+30YimdkKiDj9bTowcB41eL77/17RF/h+393AuVgShyheQ==", + "requires": { + "tslib": "^1.9.3", + "zen-observable": "^0.8.0" + } + } + } + }, + "apollo-utilities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.2.1.tgz", + "integrity": "sha512-Zv8Udp9XTSFiN8oyXOjf6PMHepD4yxxReLsl6dPUy5Ths7jti3nmlBzZUOxuTWRwZn0MoclqL7RQ5UEJN8MAxg==", + "requires": { + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.2.1", + "tslib": "^1.9.3" + }, + "dependencies": { + "ts-invariant": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.2.1.tgz", + "integrity": "sha512-Z/JSxzVmhTo50I+LKagEISFJW3pvPCqsMWLamCTX8Kr3N5aMrnGOqcflbe5hLUzwjvgPfnLzQtHZv0yWQ+FIHg==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "requires": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "requires": { + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "async-each": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.2.tgz", + "integrity": "sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg==" + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "auth0-js": { + "version": "9.10.1", + "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.10.1.tgz", + "integrity": "sha512-CDePT7UapFLPwp/lqOjL7kMk/lOi7h0AixurxaX+Rey4+4C0NRI+GiRR5u0dJQWSIXyKKOLieHpxzsr0c7VqSg==", + "requires": { + "base64-js": "^1.2.0", + "idtoken-verifier": "^1.2.0", + "js-cookie": "^2.2.0", + "qs": "^6.4.0", + "superagent": "^3.8.2", + "url-join": "^4.0.0", + "winchan": "^0.2.1" + } + }, + "autoprefixer": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.5.1.tgz", + "integrity": "sha512-KJSzkStUl3wP0D5sdMlP82Q52JLy5+atf2MHAre48+ckWkXgixmfHyWmA77wFDy6jTHU6mIgXv6hAQ2mf1PjJQ==", + "requires": { + "browserslist": "^4.5.4", + "caniuse-lite": "^1.0.30000957", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.14", + "postcss-value-parser": "^3.3.1" + }, + "dependencies": { + "browserslist": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", + "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "requires": { + "caniuse-lite": "^1.0.30000955", + "electron-to-chromium": "^1.3.122", + "node-releases": "^1.1.13" + } + } + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "requires": { + "ast-types-flow": "0.0.7" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "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" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "babel-core": { + "version": "7.0.0-bridge.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", + "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==" + }, + "babel-eslint": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-9.0.0.tgz", + "integrity": "sha512-itv1MwE3TMbY0QtNfeL7wzak1mV47Uy+n6HtSOO4Xd7rvmO+tsGQSgyOEEgo6Y2vHZKZphaoelNeSVj4vkLA1g==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "^1.0.0" + } + }, + "babel-loader": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.5.tgz", + "integrity": "sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw==", + "requires": { + "find-cache-dir": "^2.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "util.promisify": "^1.0.0" + } + }, + "babel-plugin-add-module-exports": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz", + "integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=" + }, + "babel-plugin-dynamic-import-node": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-1.2.0.tgz", + "integrity": "sha512-yeDwKaLgGdTpXL7RgGt5r6T4LmnTza/hUn5Ul8uZSGGMtEjYo13Nxai7SQaGCTEzUtg9Zq9qJn0EjEr7SeSlTQ==", + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0" + } + }, + "babel-plugin-macros": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.5.1.tgz", + "integrity": "sha512-xN3KhAxPzsJ6OQTktCanNpIFnnMsCV+t8OloKxIL72D6+SUZYFn9qfklPgef5HyyDtzYZqqb+fs1S12+gQY82Q==", + "requires": { + "@babel/runtime": "^7.4.2", + "cosmiconfig": "^5.2.0", + "resolve": "^1.10.0" + } + }, + "babel-plugin-remove-graphql-queries": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-remove-graphql-queries/-/babel-plugin-remove-graphql-queries-2.6.3.tgz", + "integrity": "sha512-vZEuO4kpPJsPex63BIMn5bBZGIDO42FQtzSD9UsDHjoWHfCB9/EQDnimtggI3Eyv4L3hwxsGNvVbS4IfFDJrlQ==" + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=" + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==" + }, + "babel-preset-fbjs": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.2.0.tgz", + "integrity": "sha512-5Jo+JeWiVz2wHUUyAlvb/sSYnXNig9r+HqGAOSfh5Fzxp7SnAaR/tEGRJ1ZX7C77kfk82658w6R5Z+uPATTD9g==", + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-syntax-class-properties": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoped-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-member-expression-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-property-literals": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" + } + }, + "babel-preset-gatsby": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/babel-preset-gatsby/-/babel-preset-gatsby-0.1.11.tgz", + "integrity": "sha512-n8Tg1r1J9juDc8GI0afrOFrEJ4No+lfylcYN2QLi90dvGl9VlfZIqoEf9bpw1maop+Ksz56NavxP6U0BHeZLqg==", + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/preset-env": "^7.4.1", + "@babel/preset-react": "^7.0.0", + "babel-plugin-macros": "^2.4.2" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } + }, + "better-opn": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-0.1.4.tgz", + "integrity": "sha512-7V92EnOdjWOB9lKsVsthCcu1FdFT5qNJVTiOgGy5wPuTsSptMMxm2G1FGHgWu22MyX3tyDRzTWk4lxY2Ppdu7A==", + "requires": { + "opn": "^5.4.0" + } + }, + "better-queue": { + "version": "3.8.10", + "resolved": "https://registry.npmjs.org/better-queue/-/better-queue-3.8.10.tgz", + "integrity": "sha512-e3gwNZgDCnNWl0An0Tz6sUjKDV9m6aB+K9Xg//vYeo8+KiH8pWhLFxkawcXhm6FpM//GfD9IQv/kmvWCAVVpKA==", + "requires": { + "better-queue-memory": "^1.0.1", + "node-eta": "^0.9.0", + "uuid": "^3.0.0" + } + }, + "better-queue-memory": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/better-queue-memory/-/better-queue-memory-1.0.3.tgz", + "integrity": "sha512-QLFkfV+k/7e4L4FR7kqkXKtRi22kl68c/3AaBs0ArDSz0iiuAl0DjVlb6gM220jW7izLE5TRy7oXOd4Cxa0wog==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, + "bluebird": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", + "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + }, + "dependencies": { + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-modules": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", + "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "cacache": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", + "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "requires": { + "bluebird": "^3.5.3", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "cache-manager": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-2.9.0.tgz", + "integrity": "sha1-Xh9jF8oaJeQN3zZacWJ1evFSNT4=", + "requires": { + "async": "1.5.2", + "lru-cache": "4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.0.tgz", + "integrity": "sha1-tcvwFVbBaWb+vlTO7A+03JDfbCg=", + "requires": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + } + } + }, + "cache-manager-fs-hash": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/cache-manager-fs-hash/-/cache-manager-fs-hash-0.0.6.tgz", + "integrity": "sha512-p1nmcCQH4/jyKqEqUqPSDDcCo0PjFdv56OvtSdUrSIB7s8rAfwETLZ0CHXWdAPyg0QaER/deTvl1dCXyjZ5xAA==", + "requires": { + "es6-promisify": "^6.0.0", + "lockfile": "^1.0.4" + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + }, + "dependencies": { + "browserslist": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", + "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "requires": { + "caniuse-lite": "^1.0.30000955", + "electron-to-chromium": "^1.3.122", + "node-releases": "^1.1.13" + } + } + } + }, + "caniuse-lite": { + "version": "1.0.30000957", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000957.tgz", + "integrity": "sha512-8wxNrjAzyiHcLXN/iunskqQnJquQQ6VX8JHfW5kLgAPRSiSuKZiNfmIkP5j7jgyXqAQBSoXyJxfnbCFS0ThSiQ==" + }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + }, + "chokidar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.2.tgz", + "integrity": "sha512-IwXUx0FXc5ibYmPC2XeEj5mpXoV66sR+t3jqu2NS2GYwCktt3KF1/Qqjws/NkegajBA4RbZ5+DDwlOiJsxDHEg==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.0" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + } + } + }, + "chownr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + }, + "chrome-trace-event": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz", + "integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==", + "requires": { + "tslib": "^1.9.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.0.tgz", + "integrity": "sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", + "optional": true + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "command-exists": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", + "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==" + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" + }, + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + }, + "compressible": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz", + "integrity": "sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==", + "requires": { + "mime-db": ">= 1.38.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "confusing-browser-globals": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.6.tgz", + "integrity": "sha512-GzyX86c2TvaagAOR+lHL2Yq4T4EnoBcnojZBcNbxVKSunxmGTnioXHR5Mo2ha/XnCoQw8eurvj6Ta+SwPEPkKg==" + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "requires": { + "date-now": "^0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "convert-hrtime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-2.0.0.tgz", + "integrity": "sha1-Gb+yyRYvnhHC8Ewsed4rfoCVxic=" + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "copyfiles": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-1.2.0.tgz", + "integrity": "sha1-qNo6xBqiIgrim9PFi2mEKU8sWTw=", + "requires": { + "glob": "^7.0.5", + "ltcdr": "^2.2.1", + "minimatch": "^3.0.3", + "mkdirp": "^0.5.1", + "noms": "0.0.0", + "through2": "^2.0.1" + } + }, + "core-js": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==" + }, + "core-js-compat": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.0.1.tgz", + "integrity": "sha512-2pC3e+Ht/1/gD7Sim/sqzvRplMiRnFQVlPpDVaHtY9l7zZP7knamr3VRD6NyGfHd84MrDC0tAM9ulNxYMW0T3g==", + "requires": { + "browserslist": "^4.5.4", + "core-js": "3.0.1", + "core-js-pure": "3.0.1", + "semver": "^6.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", + "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "requires": { + "caniuse-lite": "^1.0.30000955", + "electron-to-chromium": "^1.3.122", + "node-releases": "^1.1.13" + } + }, + "core-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.1.tgz", + "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==" + }, + "semver": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", + "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==" + } + } + }, + "core-js-pure": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.0.1.tgz", + "integrity": "sha512-mSxeQ6IghKW3MoyF4cz19GJ1cMm7761ON+WObSyLfTu/Jn3x7w4NwNFnrZxgl4MTSvYYepVLNuRtlB4loMwJ5g==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.0.tgz", + "integrity": "sha512-nxt+Nfc3JAqf4WIWd0jXLjTJZmsPLrA9DDc4nRw2KFJQJK7DNooqSXrNI7tzLG50CF8axczly5UV929tBmh/7g==", + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.0", + "parse-json": "^4.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "create-react-context": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz", + "integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==", + "requires": { + "fbjs": "^0.8.0", + "gud": "^1.0.0" + }, + "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, + "fbjs": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", + "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", + "requires": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + } + } + } + }, + "cross-fetch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.2.tgz", + "integrity": "sha1-pH/09/xxLauo9qaVoRyUhEDUVyM=", + "requires": { + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" + }, + "dependencies": { + "node-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" + }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + } + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-js": { + "version": "3.1.9-1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", + "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-loader": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.1.tgz", + "integrity": "sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw==", + "requires": { + "babel-code-frame": "^6.26.0", + "css-selector-tokenizer": "^0.7.0", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash": "^4.17.11", + "postcss": "^6.0.23", + "postcss-modules-extract-imports": "^1.2.0", + "postcss-modules-local-by-default": "^1.2.0", + "postcss-modules-scope": "^1.1.0", + "postcss-modules-values": "^1.3.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "css-selector-tokenizer": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz", + "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", + "requires": { + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + }, + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "requires": { + "jsesc": "~0.5.0" + } + } + } + }, + "css-tree": { + "version": "1.0.0-alpha.28", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", + "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + } + }, + "css-unit-converter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", + "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=" + }, + "css-url-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-url-regex/-/css-url-regex-1.1.0.tgz", + "integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=" + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=" + }, + "cssnano": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", + "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "requires": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.7", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "cssnano-preset-default": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", + "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.2", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=" + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=" + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "requires": { + "postcss": "^7.0.0" + } + }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" + }, + "csso": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", + "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "requires": { + "css-tree": "1.0.0-alpha.29" + }, + "dependencies": { + "css-tree": { + "version": "1.0.0-alpha.29", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", + "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + } + } + } + }, + "csstype": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.3.tgz", + "integrity": "sha512-rINUZXOkcBmoHWEyu7JdHu5JMzkGRoMX4ov9830WNgxf5UYxcBUO0QTKAqeJ5EZfSdlrcJYkC8WwfVW7JYi4yg==" + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "^1.0.1" + } + }, + "cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=" + }, + "damerau-levenshtein": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz", + "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "requires": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "deprecated-decorator": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", + "integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc=" + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=" + }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==" + }, + "detect-port": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", + "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "devcert-san": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/devcert-san/-/devcert-san-0.3.3.tgz", + "integrity": "sha1-qnckR0Gy2DF3HAEfIu4l45atS6k=", + "requires": { + "@types/configstore": "^2.1.1", + "@types/debug": "^0.0.29", + "@types/get-port": "^0.0.4", + "@types/glob": "^5.0.30", + "@types/mkdirp": "^0.3.29", + "@types/node": "^7.0.11", + "@types/tmp": "^0.0.32", + "command-exists": "^1.2.2", + "configstore": "^3.0.0", + "debug": "^2.6.3", + "eol": "^0.8.1", + "get-port": "^3.0.0", + "glob": "^7.1.1", + "mkdirp": "^0.5.1", + "tmp": "^0.0.31", + "tslib": "^1.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "requires": { + "utila": "~0.4" + } + }, + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "dom-walk": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", + "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "requires": { + "is-obj": "^1.0.0" + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "electron-to-chromium": { + "version": "1.3.124", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.124.tgz", + "integrity": "sha512-glecGr/kFdfeXUHOHAWvGcXrxNU+1wSO/t5B23tT1dtlvYB26GY8aHzZSWD7HqhqC800Lr+w/hQul6C5AF542w==" + }, + "elliptic": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz", + "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==", + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~6.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "engine.io-client": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", + "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "envinfo": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-5.12.1.tgz", + "integrity": "sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w==" + }, + "eol": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/eol/-/eol-0.8.1.tgz", + "integrity": "sha1-3vwyJJkMfspzuzRGGlbPncJHYdA=" + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-stack-parser": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.2.tgz", + "integrity": "sha512-E1fPutRDdIj/hohG0UpT5mayXNCxXP9d+snxFsPU9X0XgccOumKraa3juDMwTUyi7+Bu5+mCGagjg4IYeNbOdw==", + "requires": { + "stackframe": "^1.0.4" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promisify": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.0.1.tgz", + "integrity": "sha512-J3ZkwbEnnO+fGAKrjVpeUAnZshAdfZvbhQpqfIH9kSAspReRC4nJnu8ewm55b4y9ElyeuhCTzJD0XiH8Tsbhlw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "import-fresh": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", + "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "eslint-config-react-app": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-3.0.8.tgz", + "integrity": "sha512-Ovi6Bva67OjXrom9Y/SLJRkrGqKhMAL0XCH8BizPhjEVEhYczl2ZKiNZI2CuqO5/CJwAfMwRXAVGY0KToWr1aA==", + "requires": { + "confusing-browser-globals": "^1.0.6" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "eslint-loader": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.1.2.tgz", + "integrity": "sha512-rA9XiXEOilLYPOIInvVH5S/hYfyTPyxag6DZhoQOduM+3TkghAEQ3VcFO8VnX4J4qg/UIBzp72aOf/xvYmpmsg==", + "requires": { + "loader-fs-cache": "^1.0.0", + "loader-utils": "^1.0.2", + "object-assign": "^4.0.1", + "object-hash": "^1.1.4", + "rimraf": "^2.6.1" + } + }, + "eslint-module-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz", + "integrity": "sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==", + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-flowtype": { + "version": "2.50.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz", + "integrity": "sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ==", + "requires": { + "lodash": "^4.17.10" + } + }, + "eslint-plugin-graphql": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-graphql/-/eslint-plugin-graphql-2.1.1.tgz", + "integrity": "sha512-JT2paUyu3e9ZDnroSshwUMc6pKcnkfXTsZInX1+/rPotvqOLVLtdrx/cmfb7PTJwjiEAshwcpm3/XPdTpsKJPw==", + "requires": { + "graphql-config": "^2.0.1", + "lodash": "^4.11.1" + } + }, + "eslint-plugin-import": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz", + "integrity": "sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A==", + "requires": { + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.3.0", + "has": "^1.0.3", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "read-pkg-up": "^2.0.0", + "resolve": "^1.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz", + "integrity": "sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w==", + "requires": { + "aria-query": "^3.0.0", + "array-includes": "^3.0.3", + "ast-types-flow": "^0.0.7", + "axobject-query": "^2.0.2", + "damerau-levenshtein": "^1.0.4", + "emoji-regex": "^7.0.2", + "has": "^1.0.3", + "jsx-ast-utils": "^2.0.1" + } + }, + "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==", + "requires": { + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.0.1", + "object.fromentries": "^2.0.0", + "prop-types": "^15.6.2", + "resolve": "^1.9.0" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + } + } + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==" + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==" + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-source-polyfill": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/event-source-polyfill/-/event-source-polyfill-1.0.5.tgz", + "integrity": "sha512-PdStgZ3+G2o2gjqsBYbV4931ByVmwLwSrX7mFgawCL+9I1npo9dwAQTnWtNWXe5IY2P8+AbbPteeOueiEtRCUA==" + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==" + }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==" + }, + "eventsource": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", + "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", + "requires": { + "original": ">=0.0.5" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "express-graphql": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/express-graphql/-/express-graphql-0.6.12.tgz", + "integrity": "sha512-ouLWV0hRw4hnaLtXzzwhdC79ewxKbY2PRvm05mPc/zOH5W5WVCHDQ1SmNxEPBQdUeeSNh29aIqW9zEQkA3kMuA==", + "requires": { + "accepts": "^1.3.0", + "content-type": "^1.0.4", + "http-errors": "^1.3.0", + "raw-body": "^2.3.2" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-glob": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.6.tgz", + "integrity": "sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w==", + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" + }, + "faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "requires": { + "bser": "^2.0.0" + } + }, + "fbjs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz", + "integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==", + "requires": { + "core-js": "^2.4.1", + "fbjs-css-vars": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + } + }, + "fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" + }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "requires": { + "flat-cache": "^2.0.1" + } + }, + "file-loader": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", + "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", + "requires": { + "loader-utils": "^1.0.2", + "schema-utils": "^0.4.5" + } + }, + "filesize": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.5.11.tgz", + "integrity": "sha512-ZH7loueKBoDb7yG9esn1U+fgq7BzlzW6NRi5/rMdxIZ05dj7GFD/Xc5rq2CDt5Yq86CyfSYVyx4242QQNZbx1g==" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "requires": { + "is-buffer": "~2.0.3" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + } + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==" + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", + "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", + "requires": { + "debug": "^3.2.6" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "formidable": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", + "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-exists-cached": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", + "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=" + }, + "fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "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" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.2.4", + "bundled": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.3", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.5", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.2.0", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "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": { + "version": "2.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "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.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "gatsby": { + "version": "2.3.16", + "resolved": "https://registry.npmjs.org/gatsby/-/gatsby-2.3.16.tgz", + "integrity": "sha512-wd3a3P1novSaoWPFO9pfPH6rUeUtKVWTaNRk4HgzluhQ4KtG63al3N/7joDe7KFSNJGLAft0pNlHftl3bBI+Ow==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/polyfill": "^7.0.0", + "@babel/runtime": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@gatsbyjs/relay-compiler": "2.0.0-printer-fix.2", + "@mikaelkristiansson/domready": "^1.0.9", + "@pieh/friendly-errors-webpack-plugin": "1.7.0-chalk-2", + "@reach/router": "^1.1.1", + "@stefanprobst/lokijs": "^1.5.6-b", + "address": "1.0.3", + "autoprefixer": "^9.4.3", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "^9.0.0", + "babel-loader": "^8.0.0", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-plugin-dynamic-import-node": "^1.2.0", + "babel-plugin-remove-graphql-queries": "^2.6.3", + "babel-preset-gatsby": "^0.1.11", + "better-opn": "0.1.4", + "better-queue": "^3.8.6", + "bluebird": "^3.5.0", + "browserslist": "3.2.8", + "cache-manager": "^2.9.0", + "cache-manager-fs-hash": "^0.0.6", + "chalk": "^2.3.2", + "chokidar": "2.1.2", + "common-tags": "^1.4.0", + "compression": "^1.7.3", + "convert-hrtime": "^2.0.0", + "copyfiles": "^1.2.0", + "core-js": "^2.5.0", + "css-loader": "^1.0.0", + "debug": "^3.1.0", + "del": "^3.0.0", + "detect-port": "^1.2.1", + "devcert-san": "^0.3.3", + "dotenv": "^4.0.0", + "eslint": "^5.6.0", + "eslint-config-react-app": "^3.0.0", + "eslint-loader": "^2.1.0", + "eslint-plugin-flowtype": "^2.46.1", + "eslint-plugin-graphql": "^2.0.0", + "eslint-plugin-import": "^2.9.0", + "eslint-plugin-jsx-a11y": "^6.0.3", + "eslint-plugin-react": "^7.8.2", + "event-source-polyfill": "^1.0.5", + "express": "^4.16.3", + "express-graphql": "^0.6.12", + "fast-levenshtein": "~2.0.4", + "file-loader": "^1.1.11", + "flat": "^4.0.0", + "fs-exists-cached": "1.0.0", + "fs-extra": "^5.0.0", + "gatsby-cli": "^2.5.6", + "gatsby-link": "^2.0.16", + "gatsby-plugin-page-creator": "^2.0.12", + "gatsby-react-router-scroll": "^2.0.7", + "gatsby-telemetry": "^1.0.6", + "glob": "^7.1.1", + "graphql": "^14.1.1", + "graphql-compose": "^6.0.3", + "graphql-playground-middleware-express": "^1.7.10", + "graphql-relay": "^0.6.0", + "graphql-tools": "^3.0.4", + "hash-mod": "^0.0.5", + "invariant": "^2.2.4", + "is-relative": "^1.0.0", + "is-relative-url": "^2.0.0", + "is-wsl": "^1.1.0", + "jest-worker": "^23.2.0", + "joi": "12.x.x", + "json-loader": "^0.5.7", + "json-stringify-safe": "^5.0.1", + "kebab-hash": "^0.1.2", + "lodash": "^4.17.10", + "md5": "^2.2.1", + "md5-file": "^3.1.1", + "mime": "^2.2.0", + "mini-css-extract-plugin": "^0.4.0", + "mitt": "^1.1.2", + "mkdirp": "^0.5.1", + "moment": "^2.21.0", + "name-all-modules-plugin": "^1.0.1", + "normalize-path": "^2.1.1", + "null-loader": "^0.1.1", + "opentracing": "^0.14.3", + "optimize-css-assets-webpack-plugin": "^5.0.1", + "parseurl": "^1.3.2", + "physical-cpu-count": "^2.0.0", + "pnp-webpack-plugin": "^1.4.1", + "postcss-flexbugs-fixes": "^3.0.0", + "postcss-loader": "^2.1.3", + "prop-types": "^15.6.1", + "raw-loader": "^0.5.1", + "react-dev-utils": "^4.2.1", + "react-error-overlay": "^3.0.0", + "react-hot-loader": "^4.6.2", + "redux": "^4.0.0", + "request": "^2.85.0", + "semver": "^5.6.0", + "shallow-compare": "^1.2.2", + "sift": "^5.1.0", + "signal-exit": "^3.0.2", + "slash": "^1.0.0", + "socket.io": "^2.0.3", + "stack-trace": "^0.0.10", + "string-similarity": "^1.2.0", + "style-loader": "^0.21.0", + "terser-webpack-plugin": "^1.2.2", + "true-case-path": "^1.0.3", + "type-of": "^2.0.1", + "url-loader": "^1.0.1", + "util.promisify": "^1.0.0", + "uuid": "^3.1.0", + "v8-compile-cache": "^1.1.0", + "webpack": "~4.28.4", + "webpack-dev-middleware": "^3.0.1", + "webpack-dev-server": "^3.1.14", + "webpack-hot-middleware": "^2.21.0", + "webpack-merge": "^4.1.0", + "webpack-stats-plugin": "^0.1.5", + "xstate": "^4.3.2", + "yaml-loader": "^0.5.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "dotenv": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", + "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" + }, + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "gatsby-cli": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/gatsby-cli/-/gatsby-cli-2.5.6.tgz", + "integrity": "sha512-QPV1ST0SHB9X4FzI9M/uDrtf70/opjmo+EdbZxxwQOy6GWEZn3FDl4Ix+nlzY16WZlieJV4fmDcmz+nkBb/pDw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/runtime": "^7.0.0", + "bluebird": "^3.5.0", + "common-tags": "^1.4.0", + "convert-hrtime": "^2.0.0", + "core-js": "^2.5.0", + "envinfo": "^5.8.1", + "execa": "^0.8.0", + "fs-exists-cached": "^1.0.0", + "fs-extra": "^4.0.1", + "gatsby-telemetry": "^1.0.6", + "hosted-git-info": "^2.6.0", + "lodash": "^4.17.10", + "meant": "^1.0.1", + "node-fetch": "2.3.0", + "opentracing": "^0.14.3", + "pretty-error": "^2.1.1", + "resolve-cwd": "^2.0.0", + "source-map": "^0.5.7", + "stack-trace": "^0.0.10", + "update-notifier": "^2.3.0", + "uuid": "3.3.2", + "yargs": "^12.0.5", + "yurnalist": "^1.0.2" + }, + "dependencies": { + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "node-fetch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", + "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "gatsby-link": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/gatsby-link/-/gatsby-link-2.0.16.tgz", + "integrity": "sha512-2CWQeRtkidpi6uEMoq9KRkssqh66ybSWTeQ7W2as7uqldaFlZDOJxkpqf3C3n207iQxxcsY6vzvMgjtGzucv/Q==", + "requires": { + "@babel/runtime": "^7.0.0", + "@types/reach__router": "^1.0.0", + "prop-types": "^15.6.1" + } + }, + "gatsby-plugin-page-creator": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/gatsby-plugin-page-creator/-/gatsby-plugin-page-creator-2.0.12.tgz", + "integrity": "sha512-Pb4jpcI4Fqr6pqDdwm1+8DsyesZwBcvoQyDDvLBF+hbWD33iURjBqTrL8quTNtIO4svLkfieIdQ8D4IhlpFCmw==", + "requires": { + "@babel/runtime": "^7.0.0", + "bluebird": "^3.5.0", + "chokidar": "2.1.2", + "fs-exists-cached": "^1.0.0", + "glob": "^7.1.1", + "lodash": "^4.17.10", + "micromatch": "^3.1.10", + "parse-filepath": "^1.0.1", + "slash": "^1.0.0" + } + }, + "gatsby-react-router-scroll": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/gatsby-react-router-scroll/-/gatsby-react-router-scroll-2.0.7.tgz", + "integrity": "sha512-Yq8UBgurjt5XqezkBr67ZmMmsxFPdGG/7OERlju34PL05mAwOB1P2wdcZfjpVZM/k2xfVPcTRYk2zoUbtB/adg==", + "requires": { + "@babel/runtime": "^7.0.0", + "scroll-behavior": "^0.9.9", + "warning": "^3.0.0" + } + }, + "gatsby-source-graphql": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/gatsby-source-graphql/-/gatsby-source-graphql-2.1.3.tgz", + "integrity": "sha512-VYkopb5hxo/T1ZO3gWk4FxOQn7tMwO8u1ocQJ8U6HXV9/FV2fqkLpPViS5PN9W86MxbXXoJ3iSYIb0bzeRzx0g==", + "requires": { + "@babel/runtime": "^7.0.0", + "apollo-link": "1.2.1", + "apollo-link-http": "^1.5.4", + "graphql": "^14.1.1", + "graphql-tools": "^3.0.4", + "invariant": "^2.2.4", + "node-fetch": "^1.7.3", + "uuid": "^3.1.0" + }, + "dependencies": { + "@types/node": { + "version": "9.6.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.50.tgz", + "integrity": "sha512-9Yzqn2NzJxwFzon4W+aqUAMl3FiVnJ965f5F3H5T+EpUrHqb2Is1SPp/lsj2WFBqXrhIINJ5SzSwneLMg5PgSQ==" + }, + "apollo-link": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.1.tgz", + "integrity": "sha512-6Ghf+j3cQLCIvjXd2dJrLw+16HZbWbwmB1qlTc41BviB2hv+rK1nJr17Y9dWK0UD4p3i9Hfddx3tthpMKrueHg==", + "requires": { + "@types/node": "^9.4.6", + "apollo-utilities": "^1.0.0", + "zen-observable-ts": "^0.8.6" + } + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + } + } + }, + "gatsby-telemetry": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/gatsby-telemetry/-/gatsby-telemetry-1.0.6.tgz", + "integrity": "sha512-3j/pLm9VAgEanmQ56XggX6L/3V+w9sjUn+4Jn9Bm9nuBvqujsgOuBAlTYoySP0tjVliXDsmKQCnfF8cMErXOLQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/runtime": "^7.0.0", + "bluebird": "^3.5.0", + "ci-info": "2.0.0", + "configstore": "4.0.0", + "envinfo": "^5.8.1", + "fs-extra": "^7.0.1", + "is-docker": "1.1.0", + "node-fetch": "2.3.0", + "resolve-cwd": "^2.0.0", + "source-map": "^0.5.7", + "stack-trace": "^0.0.10", + "stack-utils": "1.0.2", + "uuid": "3.3.2" + }, + "dependencies": { + "configstore": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz", + "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==", + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + } + }, + "node-fetch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", + "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" + }, + "global": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", + "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", + "requires": { + "min-document": "^2.19.0", + "process": "~0.5.1" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "requires": { + "ini": "^1.3.4" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==" + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "graphql": { + "version": "14.4.2", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.4.2.tgz", + "integrity": "sha512-6uQadiRgnpnSS56hdZUSvFrVcQ6OF9y6wkxJfKquFtHlnl7+KSuWwSJsdwiK1vybm1HgcdbpGkCpvhvsVQ0UZQ==", + "requires": { + "iterall": "^1.2.2" + } + }, + "graphql-compose": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/graphql-compose/-/graphql-compose-6.2.0.tgz", + "integrity": "sha512-DuxSGduPxkFQbfr1XZcOqYC5ifmNea9zgJ924ugpNZfXWT9iQTaUiXQFZ4JM6AWkp3VHI7xwg3t7KN0tGLv1EA==", + "requires": { + "graphql-type-json": "^0.2.4", + "object-path": "^0.11.4" + } + }, + "graphql-config": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-2.2.1.tgz", + "integrity": "sha512-U8+1IAhw9m6WkZRRcyj8ZarK96R6lQBQ0an4lp76Ps9FyhOXENC5YQOxOFGm5CxPrX2rD0g3Je4zG5xdNJjwzQ==", + "requires": { + "graphql-import": "^0.7.1", + "graphql-request": "^1.5.0", + "js-yaml": "^3.10.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.4" + } + }, + "graphql-import": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.7.1.tgz", + "integrity": "sha512-YpwpaPjRUVlw2SN3OPljpWbVRWAhMAyfSba5U47qGMOSsPLi2gYeJtngGpymjm9nk57RFWEpjqwh4+dpYuFAPw==", + "requires": { + "lodash": "^4.17.4", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + } + } + }, + "graphql-playground-html": { + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/graphql-playground-html/-/graphql-playground-html-1.6.12.tgz", + "integrity": "sha512-yOYFwwSMBL0MwufeL8bkrNDgRE7eF/kTHiwrqn9FiR9KLcNIl1xw9l9a+6yIRZM56JReQOHpbQFXTZn1IuSKRg==" + }, + "graphql-playground-middleware-express": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.12.tgz", + "integrity": "sha512-17szgonnVSxWVrgblLRHHLjWnMUONfkULIwSunaMvYx8k5oG3yL86cyGCbHuDFUFkyr2swLhdfYl4mDfDXuvOA==", + "requires": { + "graphql-playground-html": "1.6.12" + } + }, + "graphql-relay": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/graphql-relay/-/graphql-relay-0.6.0.tgz", + "integrity": "sha512-OVDi6C9/qOT542Q3KxZdXja3NrDvqzbihn1B44PH8P/c5s0Q90RyQwT6guhGqXqbYEH6zbeLJWjQqiYvcg2vVw==", + "requires": { + "prettier": "^1.16.0" + } + }, + "graphql-request": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-1.8.2.tgz", + "integrity": "sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg==", + "requires": { + "cross-fetch": "2.2.2" + } + }, + "graphql-tag": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.1.tgz", + "integrity": "sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg==" + }, + "graphql-tools": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-3.1.1.tgz", + "integrity": "sha512-yHvPkweUB0+Q/GWH5wIG60bpt8CTwBklCSzQdEHmRUgAdEQKxw+9B7zB3dG7wB3Ym7M7lfrS4Ej+jtDZfA2UXg==", + "requires": { + "apollo-link": "^1.2.2", + "apollo-utilities": "^1.0.1", + "deprecated-decorator": "^0.1.6", + "iterall": "^1.1.3", + "uuid": "^3.1.0" + } + }, + "graphql-type-json": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.2.4.tgz", + "integrity": "sha512-/tq02ayMQjrG4oDFDRLLrPk0KvJXue0nVXoItBe7uAdbNXjQUu+HYCBdAmPLQoseVzUKKMzrhq2P/sfI76ON6w==" + }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" + }, + "gzip-size": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", + "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=", + "requires": { + "duplexer": "^0.1.1" + } + }, + "handle-thing": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", + "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash-mod": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/hash-mod/-/hash-mod-0.0.5.tgz", + "integrity": "sha1-2vHklzqRFmQ0Z9VO52kLQ++ALsw=" + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" + }, + "hoist-non-react-statics": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", + "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "requires": { + "react-is": "^16.7.0" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" + }, + "html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", + "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-parser-js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", + "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==" + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" + }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "idtoken-verifier": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-1.2.0.tgz", + "integrity": "sha512-8jmmFHwdPz8L73zGNAXHHOV9yXNC+Z0TUBN5rafpoaFaLFltlIFr1JkQa3FYAETP23eSsulVw0sBiwrE8jqbUg==", + "requires": { + "base64-js": "^1.2.0", + "crypto-js": "^3.1.9-1", + "jsbn": "^0.1.0", + "superagent": "^3.8.2", + "url-join": "^1.1.0" + }, + "dependencies": { + "url-join": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", + "integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=" + } + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "immutable": { + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", + "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks=" + }, + "import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "requires": { + "import-from": "^2.1.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "requires": { + "resolve-from": "^3.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "inquirer": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz", + "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==", + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "requires": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + } + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, + "ipaddr.js": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-builtin-module": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.0.0.tgz", + "integrity": "sha512-/93sDihsAD652hrMEbJGbMAVBf1qc96kyThHQ0CAOONHaE3aROLpTjDe4WQ5aoC5ITHFxEq1z8XqSU7km+8amw==", + "requires": { + "builtin-modules": "^3.0.0" + } + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "requires": { + "ci-info": "^1.5.0" + }, + "dependencies": { + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" + } + } + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, + "is-docker": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-1.1.0.tgz", + "integrity": "sha1-8EN01O7lMQ6ajhE78UlUEeRhdqE=" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "^1.0.1" + } + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-relative-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-relative-url/-/is-relative-url-2.0.0.tgz", + "integrity": "sha1-cpAtf+BLPUeS59sV+duEtyBMnO8=", + "requires": { + "is-absolute-url": "^2.0.0" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + }, + "is-root": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz", + "integrity": "sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-svg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", + "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "requires": { + "html-comment-regex": "^1.1.0" + } + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "requires": { + "punycode": "2.x.x" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + }, + "dependencies": { + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + } + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "iterall": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", + "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" + }, + "jest-worker": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-23.2.0.tgz", + "integrity": "sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk=", + "requires": { + "merge-stream": "^1.0.1" + } + }, + "joi": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-12.0.0.tgz", + "integrity": "sha512-z0FNlV4NGgjQN1fdtHYXf5kmgludM65fG/JlXzU6+rwkt9U5UWuXVYnXa2FpK0u6+qBuCmrm5byPNuiiddAHvQ==", + "requires": { + "hoek": "4.x.x", + "isemail": "3.x.x", + "topo": "2.x.x" + } + }, + "js-cookie": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.0.tgz", + "integrity": "sha1-Gywnmm7s44ChIWi5JIUmWzWx7/s=" + }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=" + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jsx-ast-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", + "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "requires": { + "array-includes": "^3.0.3" + } + }, + "kebab-hash": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/kebab-hash/-/kebab-hash-0.1.2.tgz", + "integrity": "sha512-BTZpq3xgISmQmAVzkISy4eUutsUA7s4IEFlCwOBJjvSFOwyR7I+fza+tBc/rzYWK/NrmFHjfU1IhO3lu29Ib/w==", + "requires": { + "lodash.kebabcase": "^4.1.1" + } + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "last-call-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", + "requires": { + "lodash": "^4.17.5", + "webpack-sources": "^1.1.0" + } + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "requires": { + "package-json": "^4.0.0" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "loader-fs-cache": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.2.tgz", + "integrity": "sha512-70IzT/0/L+M20jUlEqZhZyArTU6VKLRTYRDAYN26g4jfzpJqjipLL3/hgYpySqI9PwsVRHHFja0LfEmsx9X2Cw==", + "requires": { + "find-cache-dir": "^0.1.1", + "mkdirp": "0.5.1" + }, + "dependencies": { + "find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", + "requires": { + "commondir": "^1.0.1", + "mkdirp": "^0.5.1", + "pkg-dir": "^1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "requires": { + "find-up": "^1.0.0" + } + } + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lockfile": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", + "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", + "requires": { + "signal-exit": "^3.0.2" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "lodash.every": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.every/-/lodash.every-4.6.0.tgz", + "integrity": "sha1-64mYS+vENkJ5uzrvu9HKGb+mxqc=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=" + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" + }, + "lodash.maxby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.maxby/-/lodash.maxby-4.6.0.tgz", + "integrity": "sha1-CCJABo88eiJ6oAqDgOTzjPB4bj0=" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + }, + "loglevel": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", + "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "ltcdr": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltcdr/-/ltcdr-2.2.1.tgz", + "integrity": "sha1-Wrh60dTB2rjowIu/A37gwZAih88=" + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "requires": { + "charenc": "~0.0.1", + "crypt": "~0.0.1", + "is-buffer": "~1.1.1" + } + }, + "md5-file": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-3.2.3.tgz", + "integrity": "sha512-3Tkp1piAHaworfcCgH0jKbTvj1jWWFgbvh2cXaNCgHwyTCBxxvD1Y04rmfpvdPm1P4oXMOpm6+2H7sr7v9v8Fw==", + "requires": { + "buffer-alloc": "^1.1.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdn-data": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", + "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==" + }, + "meant": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/meant/-/meant-1.0.1.tgz", + "integrity": "sha512-UakVLFjKkbbUwNWJ2frVLnnAtbb7D7DsloxRd3s/gDpI8rdv8W5Hp3NaDb+POBI1fQdeussER6NB8vpcRURvlg==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "requires": { + "readable-stream": "^2.0.1" + } + }, + "merge2": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", + "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.2.tgz", + "integrity": "sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==" + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==" + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "requires": { + "mime-db": "~1.38.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "requires": { + "dom-walk": "^0.1.0" + } + }, + "mini-css-extract-plugin": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.5.tgz", + "integrity": "sha512-dqBanNfktnp2hwL2YguV9Jh91PFX7gu7nRLs4TGsbAfAG6WOtlynFRYzwDwmmeSb5uIwHo9nx1ta0f7vAZVp2w==", + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mitt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz", + "integrity": "sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==" + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "name-all-modules-plugin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/name-all-modules-plugin/-/name-all-modules-plugin-1.0.1.tgz", + "integrity": "sha1-Cr+2rYNXGLn7Te8GdOBmV6lUN1w=" + }, + "nan": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", + "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==", + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "neo-async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", + "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "requires": { + "lodash.toarray": "^4.4.0" + } + }, + "node-eta": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-eta/-/node-eta-0.9.0.tgz", + "integrity": "sha1-n7CwmbzSoCGUDmA8ZCVNwAPZp6g=" + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, + "node-forge": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", + "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==" + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" + }, + "node-libs-browser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", + "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.0", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "node-releases": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.13.tgz", + "integrity": "sha512-fKZGviSXR6YvVPyc011NHuJDSD8gFQvLPmc2d2V3BS4gr52ycyQ1Xzs7a8B+Ax3Ni/W+5h1h4SqmzeoA8WZRmA==", + "requires": { + "semver": "^5.3.0" + } + }, + "noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + }, + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "null-loader": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-0.1.1.tgz", + "integrity": "sha1-F76av80/8OFRL2/Er8sfUDk3j64=" + }, + "nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.fromentries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", + "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.11.0", + "function-bind": "^1.1.1", + "has": "^1.0.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "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" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "opentracing": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.3.tgz", + "integrity": "sha1-I+OtAp+mamU5Jq2+V+g0Rp+FUKo=" + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimism": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.9.6.tgz", + "integrity": "sha512-bWr/ZP32UgFCQAoSkz33XctHwpq2via2sBvGvO5JIlrU8gaiM0LvoKj3QMle9LWdSKlzKik8XGSerzsdfYLNxA==", + "requires": { + "@wry/context": "^0.4.0" + } + }, + "optimize-css-assets-webpack-plugin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-Rqm6sSjWtx9FchdP0uzTQDc7GXDKnwVEGoSxjezPkzMewx7gEWE9IMUYKmigTRC4U3RaNSwYVnUDLuIdtTpm0A==", + "requires": { + "cssnano": "^4.1.0", + "last-call-webpack-plugin": "^3.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==" + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==" + }, + "parallel-transform": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + } + } + }, + "parse-asn1": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=" + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "^2.0.0" + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "physical-cpu-count": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz", + "integrity": "sha1-GN4vl+S/epVRrXURlCtUlverpmA=" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + } + } + }, + "pnp-webpack-plugin": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.4.1.tgz", + "integrity": "sha512-S4kz+5rvWvD0w1O63eTJeXIxW4JHK0wPRMO7GmPhbZXJnTePcfrWZlni4BoglIf7pLSY18xtqo3MSnVkoAFXKg==", + "requires": { + "ts-pnp": "^1.0.0" + } + }, + "portfinder": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", + "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "postcss": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-calc": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz", + "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==", + "requires": { + "css-unit-converter": "^1.1.1", + "postcss": "^7.0.5", + "postcss-selector-parser": "^5.0.0-rc.4", + "postcss-value-parser": "^3.3.1" + } + }, + "postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", + "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "requires": { + "caniuse-lite": "^1.0.30000955", + "electron-to-chromium": "^1.3.122", + "node-releases": "^1.1.13" + } + } + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-flexbugs-fixes": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-3.3.1.tgz", + "integrity": "sha512-9y9kDDf2F9EjKX6x9ueNa5GARvsUbXw4ezH8vXItXHwKzljbu8awP7t5dCaabKYm18Vs1lo5bKQcnc0HkISt+w==", + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-load-config": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", + "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==", + "requires": { + "cosmiconfig": "^4.0.0", + "import-cwd": "^2.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", + "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0", + "require-from-string": "^2.0.1" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "postcss-loader": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.6.tgz", + "integrity": "sha512-hgiWSc13xVQAq25cVw80CH0l49ZKlAnU1hKPOdRrNj89bokRr/bZF2nT+hebPPF9c9xs8c3gw3Fr2nxtmXYnNg==", + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^6.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^0.4.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "requires": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + } + }, + "postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", + "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "requires": { + "caniuse-lite": "^1.0.30000955", + "electron-to-chromium": "^1.3.122", + "node-releases": "^1.1.13" + } + }, + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", + "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "requires": { + "caniuse-lite": "^1.0.30000955", + "electron-to-chromium": "^1.3.122", + "node-releases": "^1.1.13" + } + } + } + }, + "postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "requires": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz", + "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==", + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", + "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "requires": { + "caniuse-lite": "^1.0.30000955", + "electron-to-chromium": "^1.3.122", + "node-releases": "^1.1.13" + } + } + } + }, + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", + "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "requires": { + "caniuse-lite": "^1.0.30000955", + "electron-to-chromium": "^1.3.122", + "node-releases": "^1.1.13" + } + } + } + }, + "postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "dependencies": { + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" + } + } + }, + "postcss-svgo": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", + "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "requires": { + "is-svg": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + } + }, + "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==" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==" + }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "requires": { + "renderkid": "^2.0.1", + "utila": "~0.4" + } + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + }, + "process": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + }, + "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" + } + }, + "proxy-addr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.8.0" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + }, + "querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "raw-loader": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", + "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=" + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-apollo": { + "version": "2.5.8", + "resolved": "https://registry.npmjs.org/react-apollo/-/react-apollo-2.5.8.tgz", + "integrity": "sha512-60yOQrnNosxU/tRbOxGDaYNLFcOKmQqxHPhxyvKTlGIaF/rRCXQRKixUgWVffpEupSHHD7psY5k5ZOuZsdsSGQ==", + "requires": { + "apollo-utilities": "^1.3.0", + "fast-json-stable-stringify": "^2.0.0", + "hoist-non-react-statics": "^3.3.0", + "lodash.isequal": "^4.5.0", + "prop-types": "^15.7.2", + "ts-invariant": "^0.4.2", + "tslib": "^1.9.3" + }, + "dependencies": { + "apollo-utilities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.2.tgz", + "integrity": "sha512-JWNHj8XChz7S4OZghV6yc9FNnzEXj285QYp/nLNh943iObycI5GTDO3NGR9Dth12LRrSFMeDOConPfPln+WGfg==", + "requires": { + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + } + }, + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, + "react-dev-utils": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-4.2.3.tgz", + "integrity": "sha512-uvmkwl5uMexCmC0GUv1XGQP0YjfYePJufGg4YYiukhqk2vN1tQxwWJIBERqhOmSi80cppZg8mZnPP/kOMf1sUQ==", + "requires": { + "address": "1.0.3", + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "cross-spawn": "5.1.0", + "detect-port-alt": "1.1.3", + "escape-string-regexp": "1.0.5", + "filesize": "3.5.11", + "global-modules": "1.0.0", + "gzip-size": "3.0.0", + "inquirer": "3.3.0", + "is-root": "1.0.0", + "opn": "5.1.0", + "react-error-overlay": "^3.0.0", + "recursive-readdir": "2.2.1", + "shell-quote": "1.6.1", + "sockjs-client": "1.1.4", + "strip-ansi": "3.0.1", + "text-table": "0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "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" + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "detect-port-alt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.3.tgz", + "integrity": "sha1-pNLwYddXoDTs83xRQmCph1DysTE=", + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "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" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "opn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", + "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==", + "requires": { + "is-wsl": "^1.1.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + } + } + }, + "react-dom": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", + "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-error-overlay": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-3.0.0.tgz", + "integrity": "sha512-XzgvowFrwDo6TWcpJ/WTiarb9UI6lhA4PMzS7n1joK3sHfBBBOQHUc0U4u57D6DWO9vHv6lVSWx2Q/Ymfyv4hw==" + }, + "react-hot-loader": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.8.3.tgz", + "integrity": "sha512-Is8bKbSxuDLTqsWu1yjr+o1yA6yGDGjEQ2i1E8t/Nj1xJYC6QBRbyoofTn1xkMoKpcgXHuTJTqBhK0RY6moFJA==", + "requires": { + "fast-levenshtein": "^2.0.6", + "global": "^4.3.0", + "hoist-non-react-statics": "^3.3.0", + "loader-utils": "^1.1.0", + "lodash": "^4.17.11", + "prop-types": "^15.6.1", + "react-lifecycles-compat": "^3.0.4", + "shallowequal": "^1.0.2", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "react-is": { + "version": "16.8.3", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.3.tgz", + "integrity": "sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA==" + }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "requires": { + "mute-stream": "~0.0.4" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "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" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "recursive-readdir": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.1.tgz", + "integrity": "sha1-kO8jHQd4xc4JPJpI105cVCLROpk=", + "requires": { + "minimatch": "3.0.3" + }, + "dependencies": { + "minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "requires": { + "brace-expansion": "^1.0.0" + } + } + } + }, + "redux": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.1.tgz", + "integrity": "sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==", + "requires": { + "loose-envify": "^1.4.0", + "symbol-observable": "^1.2.0" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" + }, + "regenerate-unicode-properties": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz", + "integrity": "sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ==", + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + }, + "regenerator-transform": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.4.tgz", + "integrity": "sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A==", + "requires": { + "private": "^0.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp-tree": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.5.tgz", + "integrity": "sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ==" + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" + }, + "regexpu-core": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", + "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.0.2", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "requires": { + "rc": "^1.0.1" + } + }, + "regjsgen": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==" + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + } + } + }, + "relay-runtime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-2.0.0.tgz", + "integrity": "sha512-o/LPFHTI6+3FLJXM3Ec4N6hzkKYILVHYRJThNX0UQlMnqjTVPR6NO4qFE2QzzEiUS+lys+qfnvBzSmNbSh1zWQ==", + "requires": { + "@babel/runtime": "^7.0.0", + "fbjs": "^1.0.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "renderkid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", + "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "requires": { + "css-select": "^1.1.0", + "dom-converter": "^0.2", + "htmlparser2": "^3.3.0", + "strip-ansi": "^3.0.0", + "utila": "^0.4.0" + } + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "^2.1.0" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "requires": { + "aproba": "^1.1.1" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "requires": { + "rx-lite": "*" + } + }, + "rxjs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } + }, + "scroll-behavior": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/scroll-behavior/-/scroll-behavior-0.9.10.tgz", + "integrity": "sha512-JVJQkBkqMLEM4ATtbHTKare97zhz/qlla9mNttFYY/bcpyOb4BuBGEQ/N9AQWXvshzf6zo9jP60TlphnJ4YPoQ==", + "requires": { + "dom-helpers": "^3.2.1", + "invariant": "^2.2.2" + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + }, + "selfsigned": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", + "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", + "requires": { + "node-forge": "0.7.5" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "requires": { + "semver": "^5.0.3" + } + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "serialize-javascript": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz", + "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==" + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-compare": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/shallow-compare/-/shallow-compare-1.2.2.tgz", + "integrity": "sha512-LUMFi+RppPlrHzbqmFnINTrazo0lPNwhcgzuAXVVcfy/mqPDrQmHAyz5bvV0gDAuRFrk804V0HpQ6u9sZ0tBeg==" + }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "requires": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" + } + }, + "sift": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/sift/-/sift-5.1.0.tgz", + "integrity": "sha1-G78t+w63HlbEzH+1Z/vRNRtlAV4=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "signedsource": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz", + "integrity": "sha1-HdrOSYF5j5O9gzlzgD2A1S6TrWo=" + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "socket.io": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz", + "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==", + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.3.1", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.2.0", + "socket.io-parser": "~3.3.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" + }, + "socket.io-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", + "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.3.1", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "sockjs": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" + }, + "dependencies": { + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "requires": { + "websocket-driver": ">=0.5.1" + } + } + } + }, + "sockjs-client": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz", + "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=", + "requires": { + "debug": "^2.6.6", + "eventsource": "0.1.6", + "faye-websocket": "~0.11.0", + "inherits": "^2.0.1", + "json3": "^3.3.2", + "url-parse": "^1.1.8" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", + "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==" + }, + "spdy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", + "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "readable-stream": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", + "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" + }, + "stackframe": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.0.4.tgz", + "integrity": "sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw==" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + }, + "string-similarity": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-1.2.2.tgz", + "integrity": "sha512-IoHUjcw3Srl8nsPlW04U3qwWPk3oG2ffLM0tN853d/E/JlIvcmZmDY2Kz5HzKp4lEi2T7QD7Zuvjq/1rDw+XcQ==", + "requires": { + "lodash.every": "^4.6.0", + "lodash.flattendeep": "^4.4.0", + "lodash.foreach": "^4.5.0", + "lodash.map": "^4.6.0", + "lodash.maxby": "^4.6.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "style-loader": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", + "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==", + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^0.4.5" + } + }, + "stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.4.tgz", + "integrity": "sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==", + "requires": { + "caniuse-lite": "^1.0.30000955", + "electron-to-chromium": "^1.3.122", + "node-releases": "^1.1.13" + } + }, + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "subscriptions-transport-ws": { + "version": "0.9.16", + "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.16.tgz", + "integrity": "sha512-pQdoU7nC+EpStXnCfh/+ho0zE0Z+ma+i7xvj7bkXKb1dvYHSZxgRPaU6spRP+Bjzow67c/rRDoix5RT0uU9omw==", + "requires": { + "backo2": "^1.0.2", + "eventemitter3": "^3.1.0", + "iterall": "^1.2.1", + "symbol-observable": "^1.0.4", + "ws": "^5.2.0" + }, + "dependencies": { + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "superagent": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "requires": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + } + } + }, + "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" + } + }, + "svgo": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.2.1.tgz", + "integrity": "sha512-Y1+LyT4/y1ms4/0yxPMSlvx6dIbgklE9w8CIOnfeoFGB74MEkq8inSfEr6NhocTaFbyYp0a1dvNgRKGRmEBlzA==", + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.28", + "css-url-regex": "^1.1.0", + "csso": "^3.5.1", + "js-yaml": "^3.13.0", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "dependencies": { + "css-select": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", + "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^2.1.2", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + } + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, + "table": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz", + "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==", + "requires": { + "ajv": "^6.9.1", + "lodash": "^4.17.11", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "tapable": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", + "integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==" + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "requires": { + "execa": "^0.7.0" + } + }, + "terser": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", + "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", + "requires": { + "commander": "^2.19.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.10" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "terser-webpack-plugin": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz", + "integrity": "sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA==", + "requires": { + "cacache": "^11.0.2", + "find-cache-dir": "^2.0.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "terser": "^3.16.1", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "thunky": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", + "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==" + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + }, + "timers-browserify": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" + }, + "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=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "topo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz", + "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=", + "requires": { + "hoek": "4.x.x" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" + }, + "true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "requires": { + "glob": "^7.1.2" + } + }, + "ts-invariant": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.3.3.tgz", + "integrity": "sha512-UReOKsrJFGC9tUblgSRWo+BsVNbEd77Cl6WiV/XpMlkifXwNIJbknViCucHvVZkXSC/mcWeRnIGdY7uprcwvdQ==", + "requires": { + "tslib": "^1.9.3" + } + }, + "ts-pnp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.0.1.tgz", + "integrity": "sha512-Zzg9XH0anaqhNSlDRibNC8Kp+B9KNM0uRIpLpGkGyrgRIttA7zZBhotTSEoEyuDrz3QW2LGtu2dxuk34HzIGnQ==" + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "type-of": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-of/-/type-of-2.0.1.tgz", + "integrity": "sha1-5yoXQYllaOn2KDeNgW1pEvfyOXI=" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "ua-parser-js": { + "version": "0.7.19", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz", + "integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==" + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==" + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==" + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==" + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", + "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==" + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, + "url-join": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz", + "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=" + }, + "url-loader": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz", + "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", + "requires": { + "loader-utils": "^1.1.0", + "mime": "^2.0.3", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "url-parse": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", + "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", + "requires": { + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" + } + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "requires": { + "prepend-http": "^1.0.1" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "v8-compile-cache": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz", + "integrity": "sha512-ejdrifsIydN1XDH7EuR2hn8ZrkRKUYF7tUcBjBy/lhrCvs2K+zRlbW9UHc0IQ9RsYFZJFqJrieoIHfkCa0DBRA==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "vendors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", + "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "requires": { + "indexof": "0.0.1" + } + }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webpack": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.4.tgz", + "integrity": "sha512-NxjD61WsK/a3JIdwWjtIpimmvE6UrRi3yG54/74Hk9rwNj5FPkA4DJCf1z4ByDWLkvZhTZE+P3C/eh6UD5lDcw==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/wasm-edit": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", + "acorn": "^5.6.2", + "acorn-dynamic-import": "^3.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "chrome-trace-event": "^1.0.0", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.0", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "micromatch": "^3.1.8", + "mkdirp": "~0.5.0", + "neo-async": "^2.5.0", + "node-libs-browser": "^2.0.0", + "schema-utils": "^0.4.4", + "tapable": "^1.1.0", + "terser-webpack-plugin": "^1.1.0", + "watchpack": "^1.5.0", + "webpack-sources": "^1.3.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, + "webpack-dev-middleware": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.6.2.tgz", + "integrity": "sha512-A47I5SX60IkHrMmZUlB0ZKSWi29TZTcPz7cha1Z75yYOsgWh/1AcPmQEbC8ZIbU3A1ytSv1PMU0PyPz2Lmz2jg==", + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.3.1", + "range-parser": "^1.0.3", + "webpack-log": "^2.0.0" + } + }, + "webpack-dev-server": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.3.0.tgz", + "integrity": "sha512-75LTgV367MRDVIC+IBETrKEy9175+i5fy9nkw8MW+udnPCzNzSfZtKUIG5thQcooaNruPZZoEV8fCZqKJszOIw==", + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.5", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.0", + "express": "^4.16.4", + "html-entities": "^1.2.1", + "http-proxy-middleware": "^0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.2.0", + "ip": "^1.1.5", + "killable": "^1.0.1", + "loglevel": "^1.6.1", + "opn": "^5.5.0", + "portfinder": "^1.0.20", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.4", + "semver": "^6.0.0", + "serve-index": "^1.9.1", + "sockjs": "0.3.19", + "sockjs-client": "1.3.0", + "spdy": "^4.0.0", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.6.2", + "webpack-log": "^2.0.0", + "yargs": "12.0.5" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chokidar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz", + "integrity": "sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "del": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.0.tgz", + "integrity": "sha512-C4kvKNlYrwXhKxz97BuohF8YoGgQ23Xm9lvoHmgT7JaPGprSEjk3+XFled74Yt/x0ZABUHg2D67covzAPUKx5Q==", + "requires": { + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + } + }, + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "requires": { + "original": "^1.0.0" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "is-path-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.0.0.tgz", + "integrity": "sha512-m5dHHzpOXEiv18JEORttBO64UgTEypx99vCxQLjbBvGhOJxnTNglYoFXxwo6AbsQb79sqqycQEHv2hWkHZAijA==" + }, + "is-path-in-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.0.0.tgz", + "integrity": "sha512-6Vz5Gc9s/sDA3JBVu0FzWufm8xaBsqy1zn8Q6gmvGP6nSDMw78aS4poBNeatWjaRpTpxxLn1WOndAiOlk+qY8A==", + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", + "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==" + }, + "sockjs-client": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", + "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", + "requires": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "webpack-hot-middleware": { + "version": "2.24.3", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.24.3.tgz", + "integrity": "sha512-pPlmcdoR2Fn6UhYjAhp1g/IJy1Yc9hD+T6O9mjRcWV2pFbBjIFoJXhP0CoD0xPOhWJuWXuZXGBga9ybbOdzXpg==", + "requires": { + "ansi-html": "0.0.7", + "html-entities": "^1.2.0", + "querystring": "^0.2.0", + "strip-ansi": "^3.0.0" + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-merge": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz", + "integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==", + "requires": { + "lodash": "^4.17.5" + } + }, + "webpack-sources": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", + "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "webpack-stats-plugin": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/webpack-stats-plugin/-/webpack-stats-plugin-0.1.5.tgz", + "integrity": "sha1-KeXxLr/VMVjTHWVqETrB97hhedk=" + }, + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "requires": { + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" + }, + "whatwg-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", + "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "requires": { + "string-width": "^2.1.1" + } + }, + "winchan": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/winchan/-/winchan-0.2.1.tgz", + "integrity": "sha512-QrG9q+ObfmZBxScv0HSCqFm/owcgyR5Sgpiy1NlCZPpFXhbsmNHhTiLWoogItdBUi0fnU7Io/5ABEqRta5/6Dw==" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "worker-farm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", + "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, + "xstate": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/xstate/-/xstate-4.4.0.tgz", + "integrity": "sha512-MS638X5zCzEAZA/UOW9fUHSg4xAGfiHFkGMjtU5j/gmb1PtGBAVImv0iWqRZNwVqTALxxtQz655BVyNSNz2ThA==" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yaml-loader": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/yaml-loader/-/yaml-loader-0.5.0.tgz", + "integrity": "sha512-p9QIzcFSNm4mCw/m5NdyMfN4RE4aFZJWRRb01ERVNGCym8VNbKtw3OYZXnvUIkim6U/EjqE/2yIh9F/msShH9A==", + "requires": { + "js-yaml": "^3.5.2" + } + }, + "yargs": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", + "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "requires": { + "camelcase": "^4.1.0" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, + "yurnalist": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/yurnalist/-/yurnalist-1.0.5.tgz", + "integrity": "sha512-EuLjqX3Q15iVM0UtZa5Ju536uRmklKd2kKhdE5D5fIh8RZmh+pJ8c6wj2oGo0TA+T/Ii2o79cIHCTMfciW8jlA==", + "requires": { + "babel-runtime": "^6.26.0", + "chalk": "^2.1.0", + "cli-table3": "^0.5.1", + "debug": "^4.1.0", + "deep-equal": "^1.0.1", + "detect-indent": "^5.0.0", + "inquirer": "^6.2.0", + "invariant": "^2.2.0", + "is-builtin-module": "^3.0.0", + "is-ci": "^2.0.0", + "leven": "^2.0.0", + "loud-rejection": "^1.2.0", + "node-emoji": "^1.6.1", + "object-path": "^0.11.2", + "read": "^1.0.7", + "rimraf": "^2.5.0", + "semver": "^5.1.0", + "strip-ansi": "^5.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "zen-observable": { + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.13.tgz", + "integrity": "sha512-fa+6aDUVvavYsefZw0zaZ/v3ckEtMgCFi30sn91SEZea4y/6jQp05E3omjkX91zV6RVdn15fqnFZ6RKjRGbp2g==" + }, + "zen-observable-ts": { + "version": "0.8.18", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.18.tgz", + "integrity": "sha512-q7d05s75Rn1j39U5Oapg3HI2wzriVwERVo4N7uFGpIYuHB9ff02P/E92P9B8T7QVC93jCMHpbXH7X0eVR5LA7A==", + "requires": { + "tslib": "^1.9.3", + "zen-observable": "^0.8.0" + } + } + } +} diff --git a/community/sample-apps/gatsby-contentful-auth0/app/package.json b/community/sample-apps/gatsby-contentful-auth0/app/package.json new file mode 100644 index 00000000000..91d91f68f30 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/package.json @@ -0,0 +1,35 @@ +{ + "name": "gatsby-contentful-hasura", + "private": true, + "description": "A music playlist app built with Gatsby, Contentful and Hasura GraphQL", + "version": "0.1.0", + "license": "MIT", + "scripts": { + "build": "gatsby build", + "develop": "gatsby develop", + "format": "prettier --write src/**/*.{js,jsx}", + "start": "npm run develop", + "serve": "gatsby serve", + "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\"" + }, + "dependencies": { + "@reach/router": "^1.2.1", + "apollo-cache-inmemory": "^1.6.2", + "apollo-client": "^2.6.3", + "apollo-link-http": "^1.5.15", + "apollo-link-ws": "^1.0.18", + "auth0-js": "^9.10.1", + "gatsby": "^2.3.16", + "gatsby-source-graphql": "^2.1.3", + "graphql": "^14.4.2", + "graphql-tag": "^2.10.1", + "node-fetch": "^2.6.0", + "react": "^16.8.6", + "react-apollo": "^2.5.8", + "react-dom": "^16.8.6", + "subscriptions-transport-ws": "^0.9.16" + }, + "devDependencies": { + "prettier": "^1.16.4" + } +} diff --git a/community/sample-apps/gatsby-contentful-auth0/app/src/components/Playlist.js b/community/sample-apps/gatsby-contentful-auth0/app/src/components/Playlist.js new file mode 100644 index 00000000000..3ddce9093a6 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/src/components/Playlist.js @@ -0,0 +1,116 @@ +import React, { useState } from "react" +import { ApolloProvider } from 'react-apollo'; +import {Query} from 'react-apollo'; +import gql from 'graphql-tag'; +import './style.css'; + +const query = gql` + query PlaylistQuery { + playlist { + name + tracks { + track_details { + name + } + track { + items { + track { + url + } + } + } + } + } + } +`; + +const mutation = gql` + mutation insert_playlist($name: String!) { + insert_playlist(objects: [{ + name: $name + }]) { + affected_rows + } + } +`; + + +const Playlist = ({ client }) => { + const [showNewPlaylist, updateShowNewPlaylist] = useState(false); + const [playlistName, setPlaylistName] = useState(''); + const createPlaylist = (playlistName) => { + client.mutate({ + mutation: mutation, + variables: {name: playlistName} + }).then((data) => { + //TODO: update cache + }) + } + return ( + + + {({ loading, error, data, client}) => { + if (loading) { + return (
Loading...
); + } + /* + if (error) { + console.error(error); + return (
Error!
); + } + */ + return ( +
+
+ + {showNewPlaylist ? + ( +
+ Playlist name: + setPlaylistName(e.target.value)} /> + +
+ ) + : + null + } +
+

My Playlist

+ {data && data.playlist.length ? null :
No playlists available
} + {data && data.playlist.map((p, i) => ( +
+ {p.name} + {p.tracks.map((t,j) => { + let elem = null; + if (t.track) { + elem = ( +
+
{t.track_details.name}
+
+ {t.track.items[0] ? ( + + ) : null} +
+
+ ) + } + return elem; + })} +
+ ))} +
+ + ); + }} +
+
+ ) +}; + +export default Playlist; diff --git a/community/sample-apps/gatsby-contentful-auth0/app/src/components/style.css b/community/sample-apps/gatsby-contentful-auth0/app/src/components/style.css new file mode 100644 index 00000000000..ffd754df743 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/src/components/style.css @@ -0,0 +1,14 @@ +nav > a { + padding: 10px 5px; +} +.newPlaylistSection { + padding-top: 10px; +} +.newPlaylist { + padding: 10px 0px; +} +.playlistBtn { + padding: 5px 10px; + border-radius: 2px; + border-color: lightgreen; +} \ No newline at end of file diff --git a/community/sample-apps/gatsby-contentful-auth0/app/src/pages/account.js b/community/sample-apps/gatsby-contentful-auth0/app/src/pages/account.js new file mode 100644 index 00000000000..2f0068bf794 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/src/pages/account.js @@ -0,0 +1,59 @@ +import React from "react" +import { Router } from "@reach/router" +import { login, logout, isAuthenticated, getProfile } from "../utils/auth" +import { Link } from "gatsby" +import Playlist from "../components/Playlist"; + +import ApolloClient from 'apollo-client'; +import { HttpLink } from 'apollo-link-http'; +import { InMemoryCache } from 'apollo-cache-inmemory'; + +const createApolloClient = (authToken) => { + return new ApolloClient({ + link: new HttpLink({ + uri: 'http://localhost:8080/v1/graphql', + headers: { + Authorization: `Bearer ${authToken}` + // 'X-Hasura-Admin-Secret': 'myadminsecretkey' + } + }), + cache: new InMemoryCache(), + }); + }; + +const Home = ({ user }) => { + return

Hi, {user.name ? user.name : "friend"}!

+} + +const Account = ({ data }) => { + if (!isAuthenticated()) { + login() + return

Redirecting to login...

+ } + + const user = getProfile(); + const client = createApolloClient(user.idToken); + + return [ +
, + + + + + ]; +} + +export default Account; + diff --git a/community/sample-apps/gatsby-contentful-auth0/app/src/pages/callback.js b/community/sample-apps/gatsby-contentful-auth0/app/src/pages/callback.js new file mode 100644 index 00000000000..03fad54688c --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/src/pages/callback.js @@ -0,0 +1,10 @@ +import React from "react" +import { handleAuthentication } from "../utils/auth" + +const Callback = () => { + handleAuthentication() + + return

Loading...

+} + +export default Callback diff --git a/community/sample-apps/gatsby-contentful-auth0/app/src/pages/index.js b/community/sample-apps/gatsby-contentful-auth0/app/src/pages/index.js new file mode 100644 index 00000000000..f6fab638778 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/src/pages/index.js @@ -0,0 +1,9 @@ +import React from "react" +import { Link } from "gatsby" + +export default () => ( +
+

Hello Gatsby!

+ Go to your account +
+) diff --git a/community/sample-apps/gatsby-contentful-auth0/app/src/utils/auth.js b/community/sample-apps/gatsby-contentful-auth0/app/src/utils/auth.js new file mode 100644 index 00000000000..4cfa847779c --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/app/src/utils/auth.js @@ -0,0 +1,84 @@ +import auth0 from "auth0-js" +import { navigate } from "gatsby" + +const isBrowser = typeof window !== "undefined" + +const AUTH0_DOMAIN = process.env.AUTH0_DOMAIN; +const AUTH0_CLIENTID = process.env.AUTH0_CLIENTID; +const AUTH0_CALLBACK = process.env.AUTH0_CALLBACK; + +const auth = isBrowser + ? new auth0.WebAuth({ + domain: AUTH0_DOMAIN, + clientID: AUTH0_CLIENTID, + redirectUri: AUTH0_CALLBACK, + responseType: "token id_token", + scope: "openid profile email", + }) + : {} + +const tokens = { + accessToken: false, + idToken: false, + expiresAt: false, +} + +let user = {} + +export const isAuthenticated = () => { + if (!isBrowser) { + return + } + + return localStorage.getItem("isLoggedIn") === "true" +} + +export const login = () => { + if (!isBrowser) { + return + } + + auth.authorize() +} + +const setSession = (cb = () => {}) => (err, authResult) => { + if (err) { + navigate("/") + cb() + return + } + + if (authResult && authResult.accessToken && authResult.idToken) { + let expiresAt = authResult.expiresIn * 1000 + new Date().getTime() + tokens.accessToken = authResult.accessToken + tokens.idToken = authResult.idToken + tokens.expiresAt = expiresAt + user = authResult.idTokenPayload + user.idToken = authResult.idToken + localStorage.setItem("isLoggedIn", true) + navigate("/account") + cb() + } +} + +export const silentAuth = callback => { + if (!isAuthenticated()) return callback() + auth.checkSession({}, setSession(callback)) +} + +export const handleAuthentication = () => { + if (!isBrowser) { + return + } + + auth.parseHash(setSession()) +} + +export const getProfile = () => { + return user +} + +export const logout = () => { + localStorage.setItem("isLoggedIn", false) + auth.logout() +} diff --git a/community/sample-apps/gatsby-contentful-auth0/app/static/favicon.ico b/community/sample-apps/gatsby-contentful-auth0/app/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..1a466ba8852cf099ae40335e878897bde72e1735 GIT binary patch literal 2813 zcmV7wtO>0C#@O9*BXj0vnU3Txw<*2nLRVINq?LYz0THvB9>K0QA`=kA45 zH>rZGmlV#qnH$uCDPe+;0o=3Sp?kdq2WgKYI^SXKIZBYn-k+Edd<+6KvLh|TKS!{V zpmkAJ1tGJUk)?NIbT2}HbKK*+590b+#Ctc)-(n5gtDWwb65MI+Khl=Qpa}`SObc0D zcb3qzwnfCnoGI(U#i&M#k<6JI2B@4&y3QodXL{VnHQ%G>xde1yh{Cr~tOY{ox`SZ3 zFw9dcCna73B99M6W#~MX2swyNG~(c5oRRa8b|0Nk?#}ws8a4BarE2z<*Qz=9u2pl# zuVeW2SIYPvp5Yz5D+FN;y;dZLqypy9bp!1;&a#cc5n;b5oF_sa0%!7BRs4v9i?i=p zqX3V8cZ(`5*sFGw9ait`JF6NSE~)dUuQ7aZ^s+i!b5`wij;J+-`_z)}RWL!b=sS^| zO^BzKp+16XqQW+A10pY+rv>N1_&lQo@}62?LqfovcVD?$mA9J_zImft4fg10?@>o; zo7Cz>d(`}i5l|h2y!IA=7#7ARw4n>m6=zqgM&hh} z#G>&5kq^Fe?%k`ZWZ`a>$fLA2_RvJIZRJnhVu%oRO7cz?Wuo&BX|5aObF;!O>9V`< z{`Km>wvz^dXe6dw*G+Ku;~v#~qD3A4N0WN%_0#ID*G{p7nh4QbZGI`?TR9HxJfjvp z_#)d5_R>VKH`9!KL_3wy;w62^Lqz%k8LZQx2{6b*WtRSUtGd{D-EcA<^SIg5*{2Tf zcwdz+-m8kfvzgU`4OiO-u8F&<@LQYI3;BE0KdVlu&YQjbts8fZR4#wmu2%fKlE1Nt zh~;>08um9qVuc|h81)cb5(Z1iYkhzE7q1#U@9T{k&ed&wPd)j=m)W~$50h}6aH*bK z<$E9k>WBA!^Zg1{v-y~cX(q^;UAKDGA7{Mo5s^@*sFuPpg3(EKkTBZN677#8qVrIj zr9b+cx_P~eH;CwsuAFaIf0^@lHRJA5HIH0nu1405zNrB3;N5xmt>bT>nO5fMajV)(PZ_$2v<7h#4o znmJ7042Zk{znjUb$;OL4jve^WlSGfV$Mq{6>alNbV#7{Ea%NBu)ZAnU7WY@`AQBNj z4+QsDp74qIeL^13nd@2MAt9cM5Uc^UgGBzbzu9Nh3m@2^vM2HSI!=TlT0_FNEl6V4 zD%=-8zjFRg&tSElUcKo@{>d9AtKW=au9*NMa?WGi7G|C1kicPHsS+1 ze8-skgyi!%yL`TS|Enj}OftH3BOkO2R+&ueUedcxOh@PjyBO)#qG79to2%d5==o_1 zQoUUfwTxl_60@Ni?2w6=(jW3h3LpfwIv&P59X^)M9J-My7JYlOYQNTL461%tqx#jD z)hymm3;7{{Q6nNE4-zOY(B4Np&#K&AzP#lIxwL1dRdE0suIEV;#5|@u+d)9Bj&d;( z9XO3#hHaoPW^$ZAJiIO0i2pwl5O351U)rSeo;Y12rDc}}K+0lhAY!<&!y-gw zc-@1r6)e2qLQ$BB5J?y!hA9boA7^3IU;qiC^{oUpH^V~Ql}(U6B2Wnt>6V1}{l(wd zIA|#N+KV;=1lI%sILpGt3#vJoAVOxRTN1QB+%Zz~>z8k_w`*(ZRPDEc8&^A2C+&q4 z2DUkWQZfNuMyF_T6cnhms;Pbz*V&&Wp8n;~hya7;jw@5kfBFj70)ss+P(pb-2{ell zOB6mt#R-ne=l;df*CrxK5<^rcApq&}KnH@TxbpW7UEs{sO4*GO*NGcN0f8i{>V>z> zBHNy?=e#|gl91|b+p2o?8tqk8@;2`Yz;E2&vF@MX|sG!3A}Z@m1jshJ^(Wk1=DB2E!+sLOz&I+iC<5BC1M~iAaZwl>j

}uA3 zJBZ51Gh-{LePn)666(D9~}hFkGgt_C%~*Ee_( zDUfKEOKU|MTSzV78qq#Xmn8DYRpK2OEK&-wH9;QdKh4^XnBZF7Io5r;E)KR-OrsQI z9TdyjBSlSLls5hI?Cq+jD`JQU+C(ZBn@SR>?52OAgnOtv%a52wmZ%MoM>46aKhs*& zf$I!if5vXeCC$O;JPyMJJ&B3gM1X_W{(CdwUQ>9dfh5sJ*(HLM?dPTQfoI@+0Qq>r zW+F=s+jHQ+bf!=b7hHS50mFt}tS#Kf<0Jc!yruHFL!64|q$r9wvRi5NM`v%S z^5537F~eXjooD2=*I6MWfP}g`{f?NlIyr^NlXAQ?BdSMC>=htpc#pE88g_Tm@0SDh z#9ZBiG~TJklU#R4AE(F86SYhv{JfrQ8l8vAXa=qjo$q%}W*f7<7Mpm)8@z2w8uG!l zfsi>AFP`|pORDVg8ntJ`QFZjqW_AA5H69&td772zec~N7$#7pY!5h6M%G!ulUqH52 z@eub02b z+Kr!~dt$IYwGsRVm=!zr2hx5YP0yZ1f8NteQ7b2=%TZUS$Ka^R`2#7m8H8)Z^>jb1 z61kXDY`Mx&fw}eI|7zf=k&`s7$8Z7td9-7&sfe52je5pzBBsq<`(8}Ajc+x_dypPT zgtfiRfNC@N$$cpBw*zhpKSc;Ocu}%K|A`~a{hHJrwXjCILg(|&ab%VFCqSxyt=M)s zti%7`2_85H|86s$Hp-*(b~?BCC6FjW=(?58)u^QCdZLM@iD~@Ep>q9yx$uEL-Yj-E P00000NkvXXu0mjfF#vB* literal 0 HcmV?d00001 diff --git a/community/sample-apps/gatsby-contentful-auth0/auth0/insert_user_rule.js b/community/sample-apps/gatsby-contentful-auth0/auth0/insert_user_rule.js new file mode 100644 index 00000000000..be5dee6dacc --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/auth0/insert_user_rule.js @@ -0,0 +1,32 @@ +function userSyncRule(user, context, callback) { + const userId = user.user_id; + const nickname = user.nickname; + + const mutation = `mutation($userId: String!, $nickname: String) { + insert_users(objects: [{ + id: $userId, + name: $nickname + }], + on_conflict: { + constraint: users_pkey, + update_columns: [name] + }) { + affected_rows + } + }`; + + request.post( + { + headers: { + "content-type": "application/json", + "x-hasura-admin-secret": configuration.ADMIN_SECRET + }, + url: "https:///v1/graphql", + body: JSON.stringify({ query: mutation, variables: { userId, nickname } }) + }, + function(error, response, body) { + console.log(body); + callback(error, user, context); + } + ); +} \ No newline at end of file diff --git a/community/sample-apps/gatsby-contentful-auth0/hasura/config.yaml b/community/sample-apps/gatsby-contentful-auth0/hasura/config.yaml new file mode 100644 index 00000000000..ff4d3ad6a58 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/hasura/config.yaml @@ -0,0 +1 @@ +endpoint: http://localhost:8080 diff --git a/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1563970185567_init_schema.up.sql b/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1563970185567_init_schema.up.sql new file mode 100644 index 00000000000..8622cc1a1eb --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1563970185567_init_schema.up.sql @@ -0,0 +1,70 @@ +CREATE TABLE public.playlist ( + id integer NOT NULL, + name text NOT NULL, + user_id text NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL +); +CREATE TABLE public.playlist_track ( + track_id integer NOT NULL, + playlist_id integer NOT NULL +); +CREATE TABLE public.album ( + id integer NOT NULL, + name text NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL +); +CREATE SEQUENCE public.album_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; +ALTER SEQUENCE public.album_id_seq OWNED BY public.album.id; +CREATE SEQUENCE public.playlist_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; +ALTER SEQUENCE public.playlist_id_seq OWNED BY public.playlist.id; +CREATE TABLE public.track ( + id integer NOT NULL, + name text NOT NULL, + album_id integer NOT NULL +); +CREATE SEQUENCE public.track_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; +ALTER SEQUENCE public.track_id_seq OWNED BY public.track.id; +CREATE TABLE public.users ( + id text NOT NULL, + name text NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL +); +ALTER TABLE ONLY public.album ALTER COLUMN id SET DEFAULT nextval('public.album_id_seq'::regclass); +ALTER TABLE ONLY public.playlist ALTER COLUMN id SET DEFAULT nextval('public.playlist_id_seq'::regclass); +ALTER TABLE ONLY public.track ALTER COLUMN id SET DEFAULT nextval('public.track_id_seq'::regclass); +ALTER TABLE ONLY public.album + ADD CONSTRAINT album_pkey PRIMARY KEY (id); +ALTER TABLE ONLY public.playlist + ADD CONSTRAINT playlist_pkey PRIMARY KEY (id); +ALTER TABLE ONLY public.playlist_track + ADD CONSTRAINT playlist_track_pkey PRIMARY KEY (track_id, playlist_id); +ALTER TABLE ONLY public.track + ADD CONSTRAINT track_pkey PRIMARY KEY (id); +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_pkey PRIMARY KEY (id); +ALTER TABLE ONLY public.playlist_track + ADD CONSTRAINT playlist_track_playlist_id_fkey FOREIGN KEY (playlist_id) REFERENCES public.playlist(id) ON UPDATE RESTRICT ON DELETE RESTRICT; +ALTER TABLE ONLY public.playlist_track + ADD CONSTRAINT playlist_track_track_id_fkey FOREIGN KEY (track_id) REFERENCES public.track(id) ON UPDATE RESTRICT ON DELETE RESTRICT; +ALTER TABLE ONLY public.playlist + ADD CONSTRAINT playlist_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON UPDATE RESTRICT ON DELETE RESTRICT; +ALTER TABLE ONLY public.track + ADD CONSTRAINT track_album_id_fkey FOREIGN KEY (album_id) REFERENCES public.album(id) ON UPDATE RESTRICT ON DELETE RESTRICT; \ No newline at end of file diff --git a/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1563970259491_init_metadata.up.yaml b/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1563970259491_init_metadata.up.yaml new file mode 100644 index 00000000000..6f106344cc3 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1563970259491_init_metadata.up.yaml @@ -0,0 +1,169 @@ +- type: replace_metadata + args: + functions: [] + remote_schemas: + - name: contentful + definition: + url: + url_from_env: CONTENTFUL_API_ENDPOINT + headers: + - name: Authorization + value_from_env: CONTENTFUL_API_KEY + forward_client_headers: false + comment: + query_collections: [] + allowlist: [] + tables: + - table: users + object_relationships: [] + array_relationships: + - using: + foreign_key_constraint_on: + column: user_id + table: playlist + name: playlists + comment: + insert_permissions: [] + select_permissions: + - role: user + comment: + permission: + allow_aggregations: false + columns: + - id + - name + - created_at + filter: {} + update_permissions: [] + delete_permissions: [] + event_triggers: [] + - table: album + object_relationships: [] + array_relationships: + - using: + foreign_key_constraint_on: + column: album_id + table: track + name: tracks + comment: + insert_permissions: [] + select_permissions: + - role: user + comment: + permission: + allow_aggregations: false + columns: + - name + - created_at + - id + filter: {} + update_permissions: [] + delete_permissions: [] + event_triggers: [] + - table: playlist_track + object_relationships: + - using: + foreign_key_constraint_on: playlist_id + name: playlist + comment: + - using: + foreign_key_constraint_on: track_id + name: track_details + comment: + array_relationships: [] + insert_permissions: + - role: user + comment: + permission: + set: {} + check: + playlist: + user_id: + _eq: X-Hasura-User-Id + columns: + - playlist_id + - track_id + select_permissions: + - role: user + comment: + permission: + allow_aggregations: false + columns: + - track_id + - playlist_id + filter: + playlist: + user_id: + _eq: X-Hasura-User-Id + update_permissions: [] + delete_permissions: [] + event_triggers: [] + - table: playlist + object_relationships: + - using: + foreign_key_constraint_on: user_id + name: user + comment: + array_relationships: + - using: + foreign_key_constraint_on: + column: playlist_id + table: playlist_track + name: tracks + comment: + insert_permissions: + - role: user + comment: + permission: + set: + user_id: x-hasura-User-Id + check: + user_id: + _eq: X-Hasura-User-Id + columns: + - name + - user_id + select_permissions: + - role: user + comment: + permission: + allow_aggregations: false + columns: + - id + - name + - user_id + - created_at + filter: + user_id: + _eq: X-Hasura-User-Id + update_permissions: [] + delete_permissions: [] + event_triggers: [] + - table: track + object_relationships: + - using: + foreign_key_constraint_on: album_id + name: album + comment: + array_relationships: + - using: + foreign_key_constraint_on: + column: track_id + table: playlist_track + name: playlists + comment: + insert_permissions: [] + select_permissions: + - role: user + comment: + permission: + allow_aggregations: false + columns: + - id + - name + - album_id + filter: {} + update_permissions: [] + delete_permissions: [] + event_triggers: [] + diff --git a/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1564120661494_table_playlist_track_create_remote_relationship_track.down.yaml b/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1564120661494_table_playlist_track_create_remote_relationship_track.down.yaml new file mode 100644 index 00000000000..784517e43cb --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1564120661494_table_playlist_track_create_remote_relationship_track.down.yaml @@ -0,0 +1,6 @@ +- args: + name: track + table: + name: playlist_track + schema: public + type: delete_remote_relationship diff --git a/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1564120661494_table_playlist_track_create_remote_relationship_track.up.yaml b/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1564120661494_table_playlist_track_create_remote_relationship_track.up.yaml new file mode 100644 index 00000000000..12c78356349 --- /dev/null +++ b/community/sample-apps/gatsby-contentful-auth0/hasura/migrations/1564120661494_table_playlist_track_create_remote_relationship_track.up.yaml @@ -0,0 +1,14 @@ +- args: + hasura_fields: + - track_id + name: track + remote_field: + tracksCollection: + arguments: + where: + id: $track_id + remote_schema: contentful + table: + name: playlist_track + schema: public + type: create_remote_relationship From 50c6833cf043f9b274916932c0dfcc2181cc83b0 Mon Sep 17 00:00:00 2001 From: Tirumarai Selvan Date: Fri, 26 Jul 2019 07:54:38 -0400 Subject: [PATCH 04/27] add data clean-up docs for event triggers (#2596) --- .../manual/event-triggers/clean-up.rst | 73 +++++++++++++++++++ docs/graphql/manual/event-triggers/index.rst | 1 + 2 files changed, 74 insertions(+) create mode 100644 docs/graphql/manual/event-triggers/clean-up.rst diff --git a/docs/graphql/manual/event-triggers/clean-up.rst b/docs/graphql/manual/event-triggers/clean-up.rst new file mode 100644 index 00000000000..92eac7ae77f --- /dev/null +++ b/docs/graphql/manual/event-triggers/clean-up.rst @@ -0,0 +1,73 @@ +Clean-up event data +=================== +.. contents:: Table of contents + :backlinks: none + :depth: 1 + :local: + + +Hasura stores event data associated with Event Triggers in the metadata schema. If there are lots of events, the metadata tables can get huge and you may want to prune them. You can use any of the following options to prune your event data depending on your need. + +Tables +------ + +Event Triggers have 2 tables managed by Hasura: + +1. ``hdb_catalog.event_log``: This is the table that stores all captured events. +2. ``hdb_catalog.event_invocation_logs``: This is that table that stores all HTTP requests and responses. + +Option 1: Clear only HTTP logs +------------------------------ + +.. code-block:: SQL + + DELETE FROM hdb_catalog.event_invocation_logs; + +Option 2: Clear only processed events +------------------------------------- + +.. code-block:: SQL + + DELETE FROM hdb_catalog.event_log + WHERE delivered = true OR error = true; + +Option 3: Clear all processed events and HTTP logs +-------------------------------------------------- + +This is the combination of Option 1 and Option 2. + +.. code-block:: SQL + + DELETE FROM hdb_catalog.event_invocation_logs; + + DELETE FROM hdb_catalog.event_log + WHERE delivered = true OR error = true; + +Option 4: Clear all event data for a particular event trigger only +------------------------------------------------------------------ + +.. code-block:: SQL + + DELETE FROM + hdb_catalog.event_invocation_logs + WHERE event_id IN ( + SELECT id FROM hdb_catalog.event_log + WHERE trigger_name = '' ); + + DELETE FROM + hdb_catalog.event_log + WHERE trigger_name = '' + AND (delivered = true OR error = true); + + +Option 5: Clear everything +-------------------------- +.. admonition:: Warning + + This will clear all events including yet to be delivered events. + +.. code-block:: SQL + + DELETE FROM hdb_catalog.event_invocation_logs; + + DELETE FROM hdb_catalog.event_log; diff --git a/docs/graphql/manual/event-triggers/index.rst b/docs/graphql/manual/event-triggers/index.rst index 60bf12b5e4a..477782aab3a 100644 --- a/docs/graphql/manual/event-triggers/index.rst +++ b/docs/graphql/manual/event-triggers/index.rst @@ -30,3 +30,4 @@ Events can be of the following types: serverless samples Invoke trigger via console + Clean-up event data From a27488f463cadb3398c689369fa9c3205f0d06b7 Mon Sep 17 00:00:00 2001 From: AlbertGao Date: Mon, 29 Jul 2019 18:24:39 +1200 Subject: [PATCH 05/27] update heroku documentation (#2526) --- docs/graphql/manual/deployment/heroku/updating.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/graphql/manual/deployment/heroku/updating.rst b/docs/graphql/manual/deployment/heroku/updating.rst index 46c7413f1ee..cbc2fb341cb 100644 --- a/docs/graphql/manual/deployment/heroku/updating.rst +++ b/docs/graphql/manual/deployment/heroku/updating.rst @@ -32,7 +32,7 @@ Step 2: Attach your Heroku app Let's say your Heroku app is called ``hasura-heroku`` and is running on ``https://hasura-heroku.herokuapp.com``. -Use the `Heroku CLI `_ to configure the git repo you cloned in Step 1 +Navigate to your project directory, use the `Heroku CLI `_ to configure the git repo you cloned in Step 1 to be able to push to this app. .. code-block:: bash @@ -41,6 +41,8 @@ to be able to push to this app. $ heroku git:remote -a $ heroku stack:set container -a +You can find your Heroku git repo in your Heroku - Settings - Info - Heroku Git URL + Step 3: Git push to deploy the latest Hasura GraphQL engine ----------------------------------------------------------- From b9a88d509d33adc62cc8cf0769fe8496b0510569 Mon Sep 17 00:00:00 2001 From: Rikin Kachhia Date: Mon, 29 Jul 2019 14:50:27 +0530 Subject: [PATCH 06/27] allow using citext columns in row permission builder (#2622) --- .../Services/Data/TablePermissions/PermissionBuilder/utils.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/console/src/components/Services/Data/TablePermissions/PermissionBuilder/utils.js b/console/src/components/Services/Data/TablePermissions/PermissionBuilder/utils.js index 3447b878abe..634457c4c8e 100644 --- a/console/src/components/Services/Data/TablePermissions/PermissionBuilder/utils.js +++ b/console/src/components/Services/Data/TablePermissions/PermissionBuilder/utils.js @@ -1,8 +1,9 @@ /* Constants */ +// TODO: generate using SQL query to handle all types export const PGTypes = { boolean: ['boolean'], - character: ['character', 'character varying', 'text'], + character: ['character', 'character varying', 'text', 'citext'], dateTime: [ 'timestamp', 'timestamp with time zone', From e3f68dbb67de8b4c69138726d24a15eb27a2db0e Mon Sep 17 00:00:00 2001 From: Rikin Kachhia Date: Mon, 29 Jul 2019 14:58:27 +0530 Subject: [PATCH 07/27] add support for column comparision operators in permissions builder (close #2040) (#2606) --- .../integration/data/permissions/utils.js | 2 +- .../PermissionBuilder/PermissionBuilder.js | 31 ++++++++++++++++--- .../PermissionBuilder/utils.js | 30 ++++++++++++++++++ .../Data/TablePermissions/Permissions.js | 1 + .../schema-metadata-api/syntax-defs.rst | 2 ++ .../auth/authorization/permission-rules.rst | 4 +++ 6 files changed, 64 insertions(+), 6 deletions(-) diff --git a/console/cypress/integration/data/permissions/utils.js b/console/cypress/integration/data/permissions/utils.js index 576774386f0..18a3b77605c 100644 --- a/console/cypress/integration/data/permissions/utils.js +++ b/console/cypress/integration/data/permissions/utils.js @@ -30,7 +30,7 @@ export const permNoCheck = (tableName, query, first) => { // set filter { } // Toggle all columns in case if (query === 'select' || query === 'update') { - cy.get(getElementFromAlias('toggle-col-permission')).click(); + // cy.get(getElementFromAlias('toggle-col-permission')).click(); cy.get(getElementFromAlias('toggle-all-col-btn')).click(); } if (query === 'insert' || query === 'update') { diff --git a/console/src/components/Services/Data/TablePermissions/PermissionBuilder/PermissionBuilder.js b/console/src/components/Services/Data/TablePermissions/PermissionBuilder/PermissionBuilder.js index 65be2a6a7ca..830be2eb418 100644 --- a/console/src/components/Services/Data/TablePermissions/PermissionBuilder/PermissionBuilder.js +++ b/console/src/components/Services/Data/TablePermissions/PermissionBuilder/PermissionBuilder.js @@ -411,6 +411,7 @@ class PermissionBuilder extends React.Component { value, prefix, valueType, + tableColumns, showSuggestion = true ) => { const dispatchInput = val => { @@ -453,6 +454,8 @@ class PermissionBuilder extends React.Component { } else if (PGTypes.json.includes(valueType)) { input = inputBox(); suggestion = jsonSuggestion(); + } else if (valueType === 'column') { + input = renderSelect(dispatchInput, value, tableColumns); } else { input = wrapDoubleQuotes(inputBox()); suggestion = sessionVariableSuggestion(); @@ -465,7 +468,13 @@ class PermissionBuilder extends React.Component { ); }; - const renderValueArray = (dispatchFunc, values, prefix, valueType) => { + const renderValueArray = ( + dispatchFunc, + values, + prefix, + valueType, + tableColumns + ) => { const dispatchInput = val => { dispatchFunc({ prefix: prefix, value: val }); }; @@ -482,6 +491,7 @@ class PermissionBuilder extends React.Component { val, addToPrefix(prefix, i), valueType, + tableColumns, false ); inputArray.push(input); @@ -505,7 +515,13 @@ class PermissionBuilder extends React.Component { ); }; - const renderOperatorExp = (dispatchFunc, expression, prefix, valueType) => { + const renderOperatorExp = ( + dispatchFunc, + expression, + prefix, + valueType, + tableColumns + ) => { const dispatchColumnOperatorSelect = val => { dispatchFunc({ prefix: val }); }; @@ -541,14 +557,16 @@ class PermissionBuilder extends React.Component { dispatchFunc, operationValue, addToPrefix(prefix, operator), - operatorInputType + operatorInputType, + tableColumns ); } else { _valueInput = renderValue( dispatchFunc, operationValue, addToPrefix(prefix, operator), - operatorInputType + operatorInputType, + tableColumns ); } } @@ -576,10 +594,12 @@ class PermissionBuilder extends React.Component { tableSchemas, prefix ) => { + let tableColumns = []; let tableRelationships = []; let tableSchema; if (table) { tableSchema = getTableSchema(tableSchemas, table); + tableColumns = getTableColumnNames(tableSchema); tableRelationships = getTableRelationshipNames(tableSchema); } @@ -602,7 +622,8 @@ class PermissionBuilder extends React.Component { dispatchFunc, expression, prefix, - columnType + columnType, + tableColumns ); } diff --git a/console/src/components/Services/Data/TablePermissions/PermissionBuilder/utils.js b/console/src/components/Services/Data/TablePermissions/PermissionBuilder/utils.js index 634457c4c8e..51d106e127c 100644 --- a/console/src/components/Services/Data/TablePermissions/PermissionBuilder/utils.js +++ b/console/src/components/Services/Data/TablePermissions/PermissionBuilder/utils.js @@ -77,6 +77,36 @@ const columnOperatorsInfo = { inputType: 'boolean', PGTypes: ['boolean', 'character', 'dateTime', 'numeric', 'uuid'], }, + _ceq: { + type: 'object', + inputType: 'column', + PGTypes: ['boolean', 'character', 'dateTime', 'numeric', 'uuid'], + }, + _cne: { + type: 'object', + inputType: 'column', + PGTypes: ['boolean', 'character', 'dateTime', 'numeric', 'uuid'], + }, + _cgt: { + type: 'object', + inputType: 'column', + PGTypes: ['boolean', 'character', 'dateTime', 'numeric', 'uuid'], + }, + _clt: { + type: 'object', + inputType: 'column', + PGTypes: ['boolean', 'character', 'dateTime', 'numeric', 'uuid'], + }, + _cgte: { + type: 'object', + inputType: 'column', + PGTypes: ['boolean', 'character', 'dateTime', 'numeric', 'uuid'], + }, + _clte: { + type: 'object', + inputType: 'column', + PGTypes: ['boolean', 'character', 'dateTime', 'numeric', 'uuid'], + }, _like: { type: 'object', PGTypes: ['character'], diff --git a/console/src/components/Services/Data/TablePermissions/Permissions.js b/console/src/components/Services/Data/TablePermissions/Permissions.js index d220da51fa8..7d619076724 100644 --- a/console/src/components/Services/Data/TablePermissions/Permissions.js +++ b/console/src/components/Services/Data/TablePermissions/Permissions.js @@ -1015,6 +1015,7 @@ class Permissions extends Component { )} useDefaultTitleStyle testId={'toggle-col-permission'} + isOpen={colSectionStatus === 'no columns'} >

` to define permission rules. +See the :ref:`API reference ` for a list of all supported operators. + E.g. the following two images illustrate the different operators available for ``integer`` and ``text`` types: .. thumbnail:: ../../../../img/graphql/manual/auth/operators-for-integer-types.png + :width: 45% .. thumbnail:: ../../../../img/graphql/manual/auth/operators-for-text-types.png + :width: 45% Using boolean expressions ************************* From 4aef5b4c262e160c6333269930c56ccb3dd3259a Mon Sep 17 00:00:00 2001 From: IMRAN KHAN <30754328+strongSoda@users.noreply.github.com> Date: Mon, 29 Jul 2019 19:45:39 +0530 Subject: [PATCH 08/27] add About page to console to show versions info (#2334) --- console/.eslintrc | 3 +- console/src/Globals.js | 2 + console/src/components/Main/Main.js | 13 +- .../components/Main/images/console-logo.svg | 22 +++ .../src/components/Main/images/docs-logo.svg | 22 +++ console/src/components/Main/images/logo.svg | 29 ---- .../src/components/Services/About/About.js | 143 ++++++++++++++++++ .../src/components/Services/About/About.scss | 3 + .../PermissionBuilder/PermissionBuilder.js | 4 +- .../components/Services/Metadata/Sidebar.js | 2 +- .../{ => Services}/VoyagerView/VoyagerView.js | 4 +- .../VoyagerView/voyagerView.css | 0 console/src/routes.js | 15 +- console/webpack/dev.config.js | 10 ++ console/webpack/prod.config.js | 7 + 15 files changed, 238 insertions(+), 41 deletions(-) create mode 100644 console/src/components/Main/images/console-logo.svg create mode 100644 console/src/components/Main/images/docs-logo.svg delete mode 100644 console/src/components/Main/images/logo.svg create mode 100644 console/src/components/Services/About/About.js create mode 100644 console/src/components/Services/About/About.scss rename console/src/components/{ => Services}/VoyagerView/VoyagerView.js (89%) rename console/src/components/{ => Services}/VoyagerView/voyagerView.css (100%) diff --git a/console/.eslintrc b/console/.eslintrc index 5cc689831d9..7c25d02c336 100644 --- a/console/.eslintrc +++ b/console/.eslintrc @@ -100,6 +100,7 @@ "__DISABLE_SSR__": true, "__DEVTOOLS__": true, "socket": true, - "webpackIsomorphicTools": true + "webpackIsomorphicTools": true, + "CONSOLE_ASSET_VERSION": true } } diff --git a/console/src/Globals.js b/console/src/Globals.js index 09d192d07de..e13db418d8d 100644 --- a/console/src/Globals.js +++ b/console/src/Globals.js @@ -44,6 +44,7 @@ const globals = { window.__env.nodeEnv !== 'development' ? 'console' : 'console_test', assetsPath: window.__env.assetsPath, serverVersion: window.__env.serverVersion, + consoleAssetVersion: CONSOLE_ASSET_VERSION, featuresCompatibility: window.__env.serverVersion ? getFeaturesCompatibility(window.__env.serverVersion) : null, @@ -57,6 +58,7 @@ if (!window.__env.urlPrefix) { if (!window.__env.consoleMode) { globals.consoleMode = SERVER_CONSOLE_MODE; } + if (!globals.adminSecret) { globals.adminSecret = null; } diff --git a/console/src/components/Main/Main.js b/console/src/components/Main/Main.js index 219266253c2..ad06d21da5c 100644 --- a/console/src/components/Main/Main.js +++ b/console/src/components/Main/Main.js @@ -162,7 +162,8 @@ class Main extends React.Component { const github = require('./images/Github.svg'); const discord = require('./images/Discord.svg'); const mail = require('./images/mail.svg'); - const docs = require('./images/logo.svg'); + const docs = require('./images/docs-logo.svg'); + const about = require('./images/console-logo.svg'); const pixHeart = require('./images/pix-heart.svg'); const currentLocation = location.pathname; @@ -604,6 +605,16 @@ class Main extends React.Component { Head to docs +
  • + + {'about'} + About + +
  • diff --git a/console/src/components/Main/images/console-logo.svg b/console/src/components/Main/images/console-logo.svg new file mode 100644 index 00000000000..bb10f579bc3 --- /dev/null +++ b/console/src/components/Main/images/console-logo.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/console/src/components/Main/images/docs-logo.svg b/console/src/components/Main/images/docs-logo.svg new file mode 100644 index 00000000000..cf763b2fff3 --- /dev/null +++ b/console/src/components/Main/images/docs-logo.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/console/src/components/Main/images/logo.svg b/console/src/components/Main/images/logo.svg deleted file mode 100644 index 1caa11fa86a..00000000000 --- a/console/src/components/Main/images/logo.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/console/src/components/Services/About/About.js b/console/src/components/Services/About/About.js new file mode 100644 index 00000000000..1316225afac --- /dev/null +++ b/console/src/components/Services/About/About.js @@ -0,0 +1,143 @@ +import React, { Component } from 'react'; + +import Endpoints from '../../../Endpoints'; + +import globals from '../../../Globals'; + +import styles from './About.scss'; + +class About extends Component { + state = { + serverVersion: null, + latestServerVersion: null, + consoleAssetVersion: globals.consoleAssetVersion, + }; + + componentDidMount() { + fetch(Endpoints.version) + .then(response => response.json()) + .then(serverVersion => + this.setState({ + serverVersion: serverVersion.version, + }) + ); + + fetch(Endpoints.updateCheck) + .then(response => response.json()) + .then(latest => + this.setState({ + latestServerVersion: latest.latest, + }) + ); + } + + render() { + const { + serverVersion, + latestServerVersion, + consoleAssetVersion, + } = this.state; + + const spinner = ; + + const getServerVersionSection = () => { + return ( +
    + Server version: + + {serverVersion || spinner} + +
    + ); + }; + + const getLatestServerVersionSection = () => { + let updateLinks; + if ( + serverVersion && + latestServerVersion && + serverVersion !== latestServerVersion + ) { + updateLinks = ( + + + + View Changelog + + + +  ·  + + + + Update Now + + + + ); + } + + return ( +
    + Latest server version: + + {latestServerVersion || spinner} {updateLinks} + +
    + ); + }; + + const getConsoleAssetVersionSection = () => { + return ( +
    + Console asset version: + + {consoleAssetVersion || 'NA'} + +
    + ); + }; + + return ( +
    +
    +

    + About +

    +
    +
    + {getServerVersionSection()} +
    +
    + {getLatestServerVersionSection()} +
    +
    + {getConsoleAssetVersionSection()} +
    +
    +
    +
    + ); + } +} + +const mapStateToProps = () => { + return {}; +}; + +const aboutConnector = connect => connect(mapStateToProps)(About); + +export default aboutConnector; diff --git a/console/src/components/Services/About/About.scss b/console/src/components/Services/About/About.scss new file mode 100644 index 00000000000..cf1e3d14855 --- /dev/null +++ b/console/src/components/Services/About/About.scss @@ -0,0 +1,3 @@ +@import "../../Common/Common.scss"; + + diff --git a/console/src/components/Services/Data/TablePermissions/PermissionBuilder/PermissionBuilder.js b/console/src/components/Services/Data/TablePermissions/PermissionBuilder/PermissionBuilder.js index 830be2eb418..6f278ec060d 100644 --- a/console/src/components/Services/Data/TablePermissions/PermissionBuilder/PermissionBuilder.js +++ b/console/src/components/Services/Data/TablePermissions/PermissionBuilder/PermissionBuilder.js @@ -455,7 +455,9 @@ class PermissionBuilder extends React.Component { input = inputBox(); suggestion = jsonSuggestion(); } else if (valueType === 'column') { - input = renderSelect(dispatchInput, value, tableColumns); + input = wrapDoubleQuotes( + renderSelect(dispatchInput, value, tableColumns) + ); } else { input = wrapDoubleQuotes(inputBox()); suggestion = sessionVariableSuggestion(); diff --git a/console/src/components/Services/Metadata/Sidebar.js b/console/src/components/Services/Metadata/Sidebar.js index 277e811a60c..58eb8a630a4 100644 --- a/console/src/components/Services/Metadata/Sidebar.js +++ b/console/src/components/Services/Metadata/Sidebar.js @@ -33,7 +33,7 @@ const Sidebar = ({ location, metadata }) => { sectionsData.push({ key: 'allowed-queries', link: '/metadata/allowed-queries', - dataTestVal: 'metadata-allowed-queries-link', + dataTestVal: 'allowed-queries-link', title: 'Allowed Queries', }); diff --git a/console/src/components/VoyagerView/VoyagerView.js b/console/src/components/Services/VoyagerView/VoyagerView.js similarity index 89% rename from console/src/components/VoyagerView/VoyagerView.js rename to console/src/components/Services/VoyagerView/VoyagerView.js index b7d4356f981..f3aee36a9d9 100644 --- a/console/src/components/VoyagerView/VoyagerView.js +++ b/console/src/components/Services/VoyagerView/VoyagerView.js @@ -1,8 +1,8 @@ import React, { Component } from 'react'; import { GraphQLVoyager } from 'graphql-voyager'; import fetch from 'isomorphic-fetch'; -import Endpoints from '../../Endpoints'; -import '../../../node_modules/graphql-voyager/dist/voyager.css'; +import Endpoints from '../../../Endpoints'; +import '../../../../node_modules/graphql-voyager/dist/voyager.css'; import './voyagerView.css'; class VoyagerView extends Component { diff --git a/console/src/components/VoyagerView/voyagerView.css b/console/src/components/Services/VoyagerView/voyagerView.css similarity index 100% rename from console/src/components/VoyagerView/voyagerView.css rename to console/src/components/Services/VoyagerView/voyagerView.css diff --git a/console/src/routes.js b/console/src/routes.js index 293dbc17bc9..ab4393aceaa 100644 --- a/console/src/routes.js +++ b/console/src/routes.js @@ -21,9 +21,11 @@ import { getCustomResolverRouter } from './components/Services/CustomResolver'; import generatedApiExplorer from './components/Services/ApiExplorer/ApiExplorerGenerator'; -import generatedLoginConnector from './components/Login/Login'; +import generatedVoyagerConnector from './components/Services/VoyagerView/VoyagerView'; -import generatedVoyagerConnector from './components/VoyagerView/VoyagerView'; +import about from './components/Services/About/About'; + +import generatedLoginConnector from './components/Login/Login'; import metadataContainer from './components/Services/Metadata/Container'; import metadataOptionsContainer from './components/Services/Metadata/MetadataOptions/MetadataOptions'; @@ -91,14 +93,15 @@ const routes = store => { > - + + diff --git a/console/webpack/dev.config.js b/console/webpack/dev.config.js index a7747b16942..985ea99e213 100755 --- a/console/webpack/dev.config.js +++ b/console/webpack/dev.config.js @@ -20,6 +20,12 @@ const webpackIsomorphicToolsPlugin = new WebpackIsomorphicToolsPlugin( // const { UnusedFilesWebpackPlugin } = require('unused-files-webpack-plugin'); +const getRandomHexString = () => { + return Math.random() + .toString(16) + .slice(2); +}; + module.exports = { mode: 'development', devtool: 'inline-source-map', @@ -147,6 +153,10 @@ module.exports = { __DEVELOPMENT__: true, __DEVTOOLS__: true, // <-------- DISABLE redux-devtools HERE }), + // set global consts + new webpack.DefinePlugin({ + CONSOLE_ASSET_VERSION: JSON.stringify(getRandomHexString()), + }), webpackIsomorphicToolsPlugin.development(), ], }; diff --git a/console/webpack/prod.config.js b/console/webpack/prod.config.js index fc5d9b31b42..929c5a1f49d 100755 --- a/console/webpack/prod.config.js +++ b/console/webpack/prod.config.js @@ -22,6 +22,12 @@ const cleanOptions = { dry: false, }; +const getRandomHexString = () => { + return Math.random() + .toString(16) + .slice(2); +}; + module.exports = { mode: 'production', context: path.resolve(__dirname, '..'), @@ -187,6 +193,7 @@ module.exports = { // Useful to reduce the size of client-side libraries, e.g. react NODE_ENV: JSON.stringify('production'), }, + CONSOLE_ASSET_VERSION: JSON.stringify(getRandomHexString()), }), ], }; From 7f06470082751c978ce6f31e0535c65f43fc206a Mon Sep 17 00:00:00 2001 From: Daven Paul Casia Date: Tue, 30 Jul 2019 00:55:38 -0600 Subject: [PATCH 09/27] add flag to disable ci colors (close #2072) (#2634) * added log-level flag * fix up the colors * fix description --- cli/cli.go | 13 ++++++++++++- cli/commands/root.go | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cli/cli.go b/cli/cli.go index 0a362390913..a7fd975616b 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -21,7 +21,7 @@ import ( "github.com/briandowns/spinner" "github.com/gofrs/uuid" "github.com/hasura/graphql-engine/cli/version" - colorable "github.com/mattn/go-colorable" + "github.com/mattn/go-colorable" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/viper" @@ -171,6 +171,9 @@ type ExecutionContext struct { // LogLevel indicates the logrus default logging level LogLevel string + // NoColor indicates if the outputs shouldn't be colorized + NoColor bool + // Telemetry collects the telemetry data throughout the execution Telemetry *telemetry.Data @@ -343,6 +346,7 @@ func (ec *ExecutionContext) Spin(message string) { func (ec *ExecutionContext) setupLogger() { if ec.Logger == nil { logger := logrus.New() + logger.Formatter = &logrus.TextFormatter{ ForceColors: true, DisableTimestamp: true, @@ -351,6 +355,13 @@ func (ec *ExecutionContext) setupLogger() { ec.Logger = logger } + if ec.NoColor { + ec.Logger.Formatter = &logrus.TextFormatter{ + DisableColors: true, + DisableTimestamp: true, + } + } + if ec.LogLevel != "" { level, err := logrus.ParseLevel(ec.LogLevel) if err != nil { diff --git a/cli/commands/root.go b/cli/commands/root.go index 311abf95afc..c9517f58b06 100644 --- a/cli/commands/root.go +++ b/cli/commands/root.go @@ -70,6 +70,7 @@ func init() { f.StringVar(&ec.LogLevel, "log-level", "INFO", "log level (DEBUG, INFO, WARN, ERROR, FATAL)") f.StringVar(&ec.ExecutionDirectory, "project", "", "directory where commands are executed (default: current dir)") f.BoolVar(&ec.SkipUpdateCheck, "skip-update-check", false, "Skip automatic update check on command execution") + f.BoolVar(&ec.NoColor, "no-color", false, "do not colorize output (default: false)") } // Execute executes the command and returns the error From 5c0bd295a9dc39a3b1daadb9831bd470f8c9a0e5 Mon Sep 17 00:00:00 2001 From: Apoorv Vardhan Date: Tue, 30 Jul 2019 16:14:00 +0530 Subject: [PATCH 10/27] community: learn: react tutorial file path fixes (#2632) --- .../optimistic-update-mutations/3.3-clear-completed.md | 4 ++-- .../content/subscriptions/3-create-subscription.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/optimistic-update-mutations/3.3-clear-completed.md b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/optimistic-update-mutations/3.3-clear-completed.md index 965229f106b..3347dde768b 100644 --- a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/optimistic-update-mutations/3.3-clear-completed.md +++ b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/optimistic-update-mutations/3.3-clear-completed.md @@ -9,7 +9,7 @@ import YoutubeEmbed from "../../src/YoutubeEmbed.js"; -Open `src/Todo/TodoPrivateList.js` and set the client that we receive as prop. +Open `src/components/Todo/TodoPrivateList.js` and set the client that we receive as prop. @@ -58,4 +58,4 @@ clearCompleted() { } ``` -That's a wrap of the basic todo app. \ No newline at end of file +That's a wrap of the basic todo app. diff --git a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/subscriptions/3-create-subscription.md b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/subscriptions/3-create-subscription.md index 76b32619629..f990c09343b 100644 --- a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/subscriptions/3-create-subscription.md +++ b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/subscriptions/3-create-subscription.md @@ -13,7 +13,7 @@ So let's define the graphql subscription to be used. Open `src/components/OnlineUsers/OnlineUsersWrapper.js` and add the following code, below the other imports - + ```javascript - import React, { Component } from "react"; From b3807d8f984ecc4696fe4675c0d1f1cee6fedb01 Mon Sep 17 00:00:00 2001 From: Mike Wheaton Date: Tue, 30 Jul 2019 04:41:36 -0700 Subject: [PATCH 11/27] learn: fix a minor typo (pluralized name) (#2351) --- .../content/intro-to-graphql/3-writing-data-mutations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/intro-to-graphql/3-writing-data-mutations.md b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/intro-to-graphql/3-writing-data-mutations.md index 682a57e002c..91c91a1a366 100644 --- a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/intro-to-graphql/3-writing-data-mutations.md +++ b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/intro-to-graphql/3-writing-data-mutations.md @@ -36,7 +36,7 @@ will be a critical portion of our todo app. 😉 > Head to GraphiQL and on the right, click on the "docs" tab. > Type "todo" there and you'll see a list of GraphQL queries and types > that use todo. Read through their descriptions and you'll soon -> find that `insert_todo` is what you need. +> find that `insert_todos` is what you need. The mutation to create todos is titled `insert_todos`. From c4af1d73cd646ac27b58c72930ef88ec27d8b78c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Ekstr=C3=B6m?= Date: Tue, 30 Jul 2019 13:43:18 +0200 Subject: [PATCH 12/27] learn: fix typo in mutation documentation (#2185) --- .../update-delete-mutations/4-remove-todos-integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/content/update-delete-mutations/4-remove-todos-integration.md b/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/content/update-delete-mutations/4-remove-todos-integration.md index 75ec1e5e8bf..e9809c1fdac 100644 --- a/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/content/update-delete-mutations/4-remove-todos-integration.md +++ b/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/content/update-delete-mutations/4-remove-todos-integration.md @@ -33,7 +33,7 @@ Let us integrate the remove todos feature in our React Native app. Firstly impor +`; ``` -Now, in the render method of the `TodoItem` component, update the `deletetButton` function to wrap the button JSX with a `Mutation` component. +Now, in the render method of the `TodoItem` component, update the `deleteButton` function to wrap the button JSX with a `Mutation` component. ```js From dc52c0e5075b1171ec4ff76bf9b0f3eef174b730 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Wed, 31 Jul 2019 07:18:03 +0200 Subject: [PATCH 13/27] =?UTF-8?q?migrations=20image:=20use=20nc=20zero-i/o?= =?UTF-8?q?=20mode=20when=20waiting=20for=20po=E2=80=A6=20(#2594)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change adds the `-z` option to the nc command when waiting for a port to be ready. This ensures that we exit correctly reporting connection status. --- scripts/cli-migrations/docker-entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cli-migrations/docker-entrypoint.sh b/scripts/cli-migrations/docker-entrypoint.sh index ffb36f65a20..6ef0704f9dc 100755 --- a/scripts/cli-migrations/docker-entrypoint.sh +++ b/scripts/cli-migrations/docker-entrypoint.sh @@ -27,7 +27,7 @@ wait_for_port() { log "waiting $HASURA_GRAPHQL_MIGRATIONS_SERVER_TIMEOUT for $PORT to be ready" for i in `seq 1 $HASURA_GRAPHQL_MIGRATIONS_SERVER_TIMEOUT`; do - nc localhost $PORT > /dev/null 2>&1 && log "port $PORT is ready" && return + nc -z localhost $PORT > /dev/null 2>&1 && log "port $PORT is ready" && return sleep 1 done log "failed waiting for $PORT" && exit 1 From a8a18e04bbb232e668e9735a372be02951beea55 Mon Sep 17 00:00:00 2001 From: Vitalii Tverdokhlib Date: Wed, 31 Jul 2019 09:24:50 +0300 Subject: [PATCH 14/27] community: update remote schema boilerplate (#1938) --- .../remote-schemas/google-cloud-functions/nodejs/README.md | 2 +- .../google-cloud-functions/nodejs/localDev.js | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/community/boilerplates/remote-schemas/google-cloud-functions/nodejs/README.md b/community/boilerplates/remote-schemas/google-cloud-functions/nodejs/README.md index 733543691f9..dc4578152d2 100644 --- a/community/boilerplates/remote-schemas/google-cloud-functions/nodejs/README.md +++ b/community/boilerplates/remote-schemas/google-cloud-functions/nodejs/README.md @@ -33,7 +33,7 @@ $ cd graphql-engine/community/boilerplates/remote-schemas/google-cloud-functions Start a local development server (you may need to install dependencies from npm): ```bash -$ npm i --no-save apollo-server express +$ npm i --no-save apollo-server $ node localDev.js Output: diff --git a/community/boilerplates/remote-schemas/google-cloud-functions/nodejs/localDev.js b/community/boilerplates/remote-schemas/google-cloud-functions/nodejs/localDev.js index c0a857c8e6b..fcba2a9de03 100644 --- a/community/boilerplates/remote-schemas/google-cloud-functions/nodejs/localDev.js +++ b/community/boilerplates/remote-schemas/google-cloud-functions/nodejs/localDev.js @@ -1,11 +1,8 @@ const { ApolloServer } = require('apollo-server'); -const express = require('express'); -const app = express(); - const { typeDefs, resolvers } = require('./index'); -const helloSchema = new ApolloServer({ typeDefs, resolvers }); +const server = new ApolloServer({ typeDefs, resolvers }); -helloSchema.listen().then(({ url }) => { +server.listen().then(({ url }) => { console.log(`schema ready at ${url}`); }); From db24d3248fac6f2264b65dc411dfb1c604814621 Mon Sep 17 00:00:00 2001 From: Rakesh Emmadi <12475069+rakeshkky@users.noreply.github.com> Date: Wed, 31 Jul 2019 14:31:48 +0530 Subject: [PATCH 15/27] schema sync process will not generate garbage data (close #2542) (#2585) schema syncing logic now requires only a single row in `hdb_schema_update_event`. --- server/src-exec/Main.hs | 18 ++-- server/src-exec/Migrate.hs | 14 ++- server/src-lib/Hasura/Server/Init.hs | 16 ++-- server/src-lib/Hasura/Server/Query.hs | 18 ++-- server/src-lib/Hasura/Server/Telemetry.hs | 10 ++- server/src-rsr/initialise.sql | 9 +- server/src-rsr/migrate_from_18_to_19.sql | 15 ++++ server/stack.yaml.lock | 103 ++++++++++++++++++++++ 8 files changed, 161 insertions(+), 42 deletions(-) create mode 100644 server/src-rsr/migrate_from_18_to_19.sql create mode 100644 server/stack.yaml.lock diff --git a/server/src-exec/Main.hs b/server/src-exec/Main.hs index d03df0f7206..94e0d9ccbaf 100644 --- a/server/src-exec/Main.hs +++ b/server/src-exec/Main.hs @@ -38,7 +38,6 @@ import Hasura.Server.Logging import Hasura.Server.Query (peelRun) import Hasura.Server.SchemaUpdate import Hasura.Server.Telemetry -import Hasura.Server.Utils import Hasura.Server.Version (currentVersion) import qualified Database.PG.Query as Q @@ -119,7 +118,7 @@ main = do (HGEOptionsG rci hgeCmd) <- parseArgs -- global http manager httpManager <- HTTP.newManager HTTP.tlsManagerSettings - instanceId <- mkInstanceId + instanceId <- generateInstanceId case hgeCmd of HCServe so@(ServeOptions port host cp isoL mAdminSecret mAuthHook mJwtSecret mUnAuthRole corsCfg enableConsole consoleAssetsDir @@ -147,7 +146,7 @@ main = do pool <- Q.initPGPool ci cp pgLogger -- safe init catalog - initRes <- initialise pool sqlGenCtx logger httpManager + dbId <- initialise pool sqlGenCtx logger httpManager (app, cacheRef, cacheInitTime) <- mkWaiApp isoL loggerCtx sqlGenCtx enableAL pool ci httpManager am @@ -183,7 +182,7 @@ main = do -- start a background thread for telemetry when enableTelemetry $ do unLogger logger $ mkGenericStrLog LevelInfo "telemetry" telemetryNotice - void $ C.forkIO $ runTelemetry logger httpManager scRef initRes + void $ C.forkIO $ runTelemetry logger httpManager scRef dbId instanceId finishTime <- Clock.getCurrentTime let apiInitTime = realToFrac $ Clock.diffUTCTime finishTime initTime @@ -253,20 +252,15 @@ main = do migrateCatalog currentTime either printErrJExit (logger . mkGenericStrLog LevelInfo "db_migrate") migRes - -- generate and retrieve uuids - getUniqIds pool + -- retrieve database id + eDbId <- runTx pool getDbId + either printErrJExit return eDbId prepareEvents pool (Logger logger) = do logger $ mkGenericStrLog LevelInfo "event_triggers" "preparing data" res <- runTx pool unlockAllEvents either printErrJExit return res - getUniqIds pool = do - eDbId <- runTx pool getDbId - dbId <- either printErrJExit return eDbId - fp <- liftIO generateFingerprint - return (dbId, fp) - getFromEnv :: (Read a) => a -> String -> IO a getFromEnv defaults env = do mEnv <- lookupEnv env diff --git a/server/src-exec/Migrate.hs b/server/src-exec/Migrate.hs index 90684ce2173..05964267179 100644 --- a/server/src-exec/Migrate.hs +++ b/server/src-exec/Migrate.hs @@ -19,7 +19,7 @@ import qualified Data.Yaml.TH as Y import qualified Database.PG.Query as Q curCatalogVer :: T.Text -curCatalogVer = "18" +curCatalogVer = "19" migrateMetadata :: ( MonadTx m @@ -337,6 +337,13 @@ from17To18 = DROP table hdb_catalog.hdb_query_template |] +from18To19 :: MonadTx m => m () +from18To19 = do + -- Migrate database + Q.Discard () <- liftTx $ Q.multiQE defaultTxErrorHandler + $(Q.sqlFromFile "src-rsr/migrate_from_18_to_19.sql") + return () + migrateCatalog :: ( MonadTx m , CacheRWM m @@ -369,10 +376,13 @@ migrateCatalog migrationTime = do | preVer == "15" -> from15ToCurrent | preVer == "16" -> from16ToCurrent | preVer == "17" -> from17ToCurrent + | preVer == "18" -> from18ToCurrent | otherwise -> throw400 NotSupported $ "unsupported version : " <> preVer where - from17ToCurrent = from17To18 >> postMigrate + from18ToCurrent = from18To19 >> postMigrate + + from17ToCurrent = from17To18 >> from18ToCurrent from16ToCurrent = from16To17 >> from17ToCurrent diff --git a/server/src-lib/Hasura/Server/Init.hs b/server/src-lib/Hasura/Server/Init.hs index ba8966ca18d..ad5edce7d47 100644 --- a/server/src-lib/Hasura/Server/Init.hs +++ b/server/src-lib/Hasura/Server/Init.hs @@ -14,16 +14,14 @@ import qualified Data.ByteString.Lazy.Char8 as BLC import qualified Data.HashSet as Set import qualified Data.String as DataString import qualified Data.Text as T -import qualified Data.UUID as UUID -import qualified Data.UUID.V4 as UUID import qualified Hasura.GraphQL.Execute.LiveQuery as LQ import qualified Hasura.Logging as L import qualified Text.PrettyPrint.ANSI.Leijen as PP import Hasura.Prelude -import Hasura.RQL.Types ( RoleName (..) - , SchemaCache (..) - , mkNonEmptyText ) +import Hasura.RQL.Types (RoleName (..), + SchemaCache (..), + mkNonEmptyText) import Hasura.Server.Auth import Hasura.Server.Cors import Hasura.Server.Logging @@ -31,10 +29,10 @@ import Hasura.Server.Utils newtype InstanceId = InstanceId { getInstanceId :: Text } - deriving (Show, Eq, J.ToJSON, J.FromJSON) + deriving (Show, Eq, J.ToJSON, J.FromJSON, Q.FromCol, Q.ToPrepArg) -mkInstanceId :: IO InstanceId -mkInstanceId = InstanceId . UUID.toText <$> UUID.nextRandom +generateInstanceId :: IO InstanceId +generateInstanceId = InstanceId <$> generateFingerprint data StartupTimeInfo = StartupTimeInfo @@ -169,7 +167,7 @@ instance FromEnv AdminSecret where instance FromEnv RoleName where fromEnv string = case mkNonEmptyText (T.pack string) of - Nothing -> Left "empty string not allowed" + Nothing -> Left "empty string not allowed" Just neText -> Right $ RoleName neText instance FromEnv Bool where diff --git a/server/src-lib/Hasura/Server/Query.hs b/server/src-lib/Hasura/Server/Query.hs index 9640992dec9..dc6a2acaf82 100644 --- a/server/src-lib/Hasura/Server/Query.hs +++ b/server/src-lib/Hasura/Server/Query.hs @@ -121,27 +121,21 @@ instance HasSQLGenCtx Run where fetchLastUpdate :: Q.TxE QErr (Maybe (InstanceId, UTCTime)) fetchLastUpdate = do - l <- Q.listQE defaultTxErrorHandler + Q.withQE defaultTxErrorHandler [Q.sql| SELECT instance_id::text, occurred_at FROM hdb_catalog.hdb_schema_update_event ORDER BY occurred_at DESC LIMIT 1 |] () True - case l of - [] -> return Nothing - [(instId, occurredAt)] -> - return $ Just (InstanceId instId, occurredAt) - -- never happens - _ -> throw500 "more than one row returned by query" recordSchemaUpdate :: InstanceId -> Q.TxE QErr () recordSchemaUpdate instanceId = liftTx $ Q.unitQE defaultTxErrorHandler [Q.sql| - INSERT INTO - hdb_catalog.hdb_schema_update_event - (instance_id, occurred_at) - VALUES ($1::uuid, DEFAULT) - |] (Identity $ getInstanceId instanceId) True + INSERT INTO hdb_catalog.hdb_schema_update_event + (instance_id, occurred_at) VALUES ($1::uuid, DEFAULT) + ON CONFLICT ((occurred_at IS NOT NULL)) + DO UPDATE SET instance_id = $1::uuid, occurred_at = DEFAULT + |] (Identity instanceId) True peelRun :: SchemaCache diff --git a/server/src-lib/Hasura/Server/Telemetry.hs b/server/src-lib/Hasura/Server/Telemetry.hs index 1c22504c599..cd40cc09f31 100644 --- a/server/src-lib/Hasura/Server/Telemetry.hs +++ b/server/src-lib/Hasura/Server/Telemetry.hs @@ -19,6 +19,7 @@ import Hasura.HTTP import Hasura.Logging import Hasura.Prelude import Hasura.RQL.Types +import Hasura.Server.Init import Hasura.Server.Version import qualified CI @@ -68,7 +69,7 @@ $(A.deriveJSON (A.aesonDrop 3 A.snakeCase) ''Metrics) data HasuraTelemetry = HasuraTelemetry { _htDbUid :: !Text - , _htInstanceUid :: !Text + , _htInstanceUid :: !InstanceId , _htVersion :: !Text , _htCi :: !(Maybe CI.CI) , _htMetrics :: !Metrics @@ -85,7 +86,7 @@ $(A.deriveJSON (A.aesonDrop 3 A.snakeCase) ''TelemetryPayload) telemetryUrl :: Text telemetryUrl = "https://telemetry.hasura.io/v1/http" -mkPayload :: Text -> Text -> Text -> Metrics -> IO TelemetryPayload +mkPayload :: Text -> InstanceId -> Text -> Metrics -> IO TelemetryPayload mkPayload dbId instanceId version metrics = do ci <- CI.getCI return $ TelemetryPayload topic $ @@ -96,9 +97,10 @@ runTelemetry :: Logger -> HTTP.Manager -> IORef (SchemaCache, SchemaCacheVer) - -> (Text, Text) + -> Text + -> InstanceId -> IO () -runTelemetry (Logger logger) manager cacheRef (dbId, instanceId) = do +runTelemetry (Logger logger) manager cacheRef dbId instanceId = do let options = wreqOptions manager [] forever $ do schemaCache <- fmap fst $ readIORef cacheRef diff --git a/server/src-rsr/initialise.sql b/server/src-rsr/initialise.sql index 8807fe0d0ce..568e3b3b295 100644 --- a/server/src-rsr/initialise.sql +++ b/server/src-rsr/initialise.sql @@ -402,11 +402,13 @@ CREATE TABLE hdb_catalog.remote_schemas ( ); CREATE TABLE hdb_catalog.hdb_schema_update_event ( - id BIGSERIAL PRIMARY KEY, instance_id uuid NOT NULL, occurred_at timestamptz NOT NULL DEFAULT NOW() ); +CREATE UNIQUE INDEX hdb_schema_update_event_one_row + ON hdb_catalog.hdb_schema_update_event ((occurred_at IS NOT NULL)); + CREATE FUNCTION hdb_catalog.hdb_schema_update_event_notifier() RETURNS trigger AS $function$ DECLARE @@ -425,8 +427,9 @@ $function$ $function$ LANGUAGE plpgsql; -CREATE TRIGGER hdb_schema_update_event_notifier AFTER INSERT ON hdb_catalog.hdb_schema_update_event - FOR EACH ROW EXECUTE PROCEDURE hdb_catalog.hdb_schema_update_event_notifier(); +CREATE TRIGGER hdb_schema_update_event_notifier AFTER INSERT OR UPDATE ON + hdb_catalog.hdb_schema_update_event FOR EACH ROW EXECUTE PROCEDURE + hdb_catalog.hdb_schema_update_event_notifier(); CREATE VIEW hdb_catalog.hdb_table_info_agg AS ( select diff --git a/server/src-rsr/migrate_from_18_to_19.sql b/server/src-rsr/migrate_from_18_to_19.sql new file mode 100644 index 00000000000..31c0f668e44 --- /dev/null +++ b/server/src-rsr/migrate_from_18_to_19.sql @@ -0,0 +1,15 @@ +-- Make hdb_catalog.hdb_schema_update_event as single row table +-- Delete insert trigger and setup update trigger + +DELETE FROM hdb_catalog.hdb_schema_update_event; + +CREATE UNIQUE INDEX hdb_schema_update_event_one_row + ON hdb_catalog.hdb_schema_update_event ((occurred_at IS NOT NULL)); + +ALTER TABLE hdb_catalog.hdb_schema_update_event DROP COLUMN id; + +DROP TRIGGER hdb_schema_update_event_notifier ON hdb_catalog.hdb_schema_update_event; + +CREATE TRIGGER hdb_schema_update_event_notifier AFTER INSERT OR UPDATE ON + hdb_catalog.hdb_schema_update_event FOR EACH ROW EXECUTE PROCEDURE + hdb_catalog.hdb_schema_update_event_notifier(); diff --git a/server/stack.yaml.lock b/server/stack.yaml.lock new file mode 100644 index 00000000000..5367dd13598 --- /dev/null +++ b/server/stack.yaml.lock @@ -0,0 +1,103 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: +- completed: + cabal-file: + size: 2829 + sha256: 0ef7cf19d08caa11c690a732f14e4b7159c46cdda1d9e66dceb6d4bedd9fd9c1 + name: pg-client + version: 0.1.0 + git: https://github.com/hasura/pg-client-hs.git + pantry-tree: + size: 1051 + sha256: fbab919039158f3714c3f0ac3d605d3fb9c85061517b4b9fc67147403b0b9975 + commit: 16f27a134f12c4f24fee19d57f0ca179bdb4135b + original: + git: https://github.com/hasura/pg-client-hs.git + commit: 16f27a134f12c4f24fee19d57f0ca179bdb4135b +- completed: + cabal-file: + size: 3295 + sha256: 5c53f2e67996f9e3f85002f95a929a04b85a44e00ffbf1b7a8c034c5098aa630 + name: graphql-parser + version: 0.1.0.0 + git: https://github.com/hasura/graphql-parser-hs.git + pantry-tree: + size: 1771 + sha256: 6e506a5dbf965325c515efc523e63bbc15640c994a5dbe21448d328c7ba619a1 + commit: 1ccdbb4c4d743b679f3141992df39feaee971640 + original: + git: https://github.com/hasura/graphql-parser-hs.git + commit: 1ccdbb4c4d743b679f3141992df39feaee971640 +- completed: + cabal-file: + size: 1253 + sha256: d0356b65cbe17a2fecf9334aa133de238161ef9c22af015d67ab622e08eb8ed1 + name: ci-info + version: 0.1.0.0 + git: https://github.com/hasura/ci-info-hs.git + pantry-tree: + size: 512 + sha256: 78d311887af8c825aa21563635fbe31503febcc490e0e5d81919835d83ef9046 + commit: ad6df731584dc89b72a6e131687d37ef01714fe8 + original: + git: https://github.com/hasura/ci-info-hs.git + commit: ad6df731584dc89b72a6e131687d37ef01714fe8 +- completed: + hackage: ginger-0.8.4.0@sha256:21c3051af3c90af39c40a50400c9a1a0fcccb544528e37cde30bdd30048437d8,3151 + pantry-tree: + size: 1375 + sha256: f8a7cb091ea4d8011bd530f83a22941a009d97ee7ccd4c93d0528aa72f3636ea + original: + hackage: ginger-0.8.4.0 +- completed: + hackage: select-0.4.0.1@sha256:d409315752a069693bdd4169fa9a8ea7777d814da77cd8604f367cf0741de295,2492 + pantry-tree: + size: 1256 + sha256: b6ae36ccba2a7cdd1ad130575931364002682e532d7043da62771e58294ddb7a + original: + hackage: select-0.4.0.1 +- completed: + hackage: primitive-extras-0.7.1@sha256:23905c57089418b1a2d324cfee3e81bbd5a344a0fa56a827867b2dce275fdb5e,2945 + pantry-tree: + size: 1181 + sha256: f788dae21ca4f0d0377d97a5ba7fd008d4b0af8991a745f94c29f2caa11dc6bd + original: + hackage: primitive-extras-0.7.1 +- completed: + hackage: stm-hamt-1.2.0.2@sha256:18126db7bf2d9c967a6020c677b3005dd957a4c39d69aeaea3c29c90de8f6124,3972 + pantry-tree: + size: 1009 + sha256: ef426797655d6b4b9238b1200c4129d44e91f996f26b92a035b1333b8b8a6f62 + original: + hackage: stm-hamt-1.2.0.2 +- completed: + hackage: stm-containers-1.1.0.4@sha256:f83a683357b6e3b1dda3e70d2077a37224ed534df1f74c4e11f3f6daa7945c5b,3248 + pantry-tree: + size: 761 + sha256: 059c5a2d657d392aca0a887648f57380d6321734dc8879c056a44d4414308ac6 + original: + hackage: stm-containers-1.1.0.4 +- completed: + hackage: reroute-0.5.0.0@sha256:3360747cdc700c9808a38bff48b75926efa443d4af282396082329a218a8d9d3,2446 + pantry-tree: + size: 660 + sha256: 52afcff0a5dba2fb746be4fa8cfa56cf774272872b61130537fe0e7ad463c0cd + original: + hackage: reroute-0.5.0.0 +- completed: + hackage: Spock-core-0.13.0.0@sha256:06e007f23c47bdda52d2927da54160d73f1b6f51a977f3ca9087275698db8f0a,3400 + pantry-tree: + size: 1113 + sha256: 86140298020f68bb09d07b26a6a6f1666fc3a02715d7986b09150727247a1a84 + original: + hackage: Spock-core-0.13.0.0 +snapshots: +- completed: + size: 498167 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/13/20.yaml + sha256: cda928d57b257a5f17bcad796843c9daa674fef47d600dbea3aa7b0e49d64a11 + original: lts-13.20 From 93737916a9aa06b72df41b0e138dfe71a9e9acd4 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelhas Date: Wed, 31 Jul 2019 17:18:32 +0100 Subject: [PATCH 16/27] community: learn: ReasonML tutorial bug fixes (#2642) --- .../app-final/src/todo/TodoPublicList.re | 6 +++--- .../tutorial-site/content/apollo-client.md | 2 +- .../tutorial-site/content/subscriptions/1-subscription.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/app-final/src/todo/TodoPublicList.re b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/app-final/src/todo/TodoPublicList.re index 5d0040a22fd..a083d406b87 100644 --- a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/app-final/src/todo/TodoPublicList.re +++ b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/app-final/src/todo/TodoPublicList.re @@ -60,7 +60,7 @@ let make = (~client, ~latestTodoId) => { "query": ApolloClient.gql(. fetchOlderTodosQuery##query), "variables": fetchOlderTodosQuery##variables }; - let apolloData = c##query(query); + let apolloData = client##query(query); apolloData |> Js.Promise.then_(gqlResp => { let resp = toApolloResult(gqlResp); @@ -81,7 +81,7 @@ let make = (~client, ~latestTodoId) => { "query": ApolloClient.gql(. fetchNewerTodosQuery##query), "variables": fetchNewerTodosQuery##variables }; - let apolloData = c##query(query); + let apolloData = client##query(query); apolloData |> Js.Promise.then_(gqlResp => { let resp = toApolloResult(gqlResp); @@ -131,4 +131,4 @@ let make = (~client, ~latestTodoId) => { } -} \ No newline at end of file +} diff --git a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/apollo-client.md b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/apollo-client.md index 8140dd42b17..22907319c79 100644 --- a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/apollo-client.md +++ b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/apollo-client.md @@ -45,7 +45,7 @@ Finally, you need a `graphql_schema.json` in the root of your project so that th 3. Run this command from the root of your project: ```js - npx send-introspection-query https://learn.hasura.io/graphql --haders "Authorization: Bearer " + npx send-introspection-query https://learn.hasura.io/graphql --headers "Authorization: Bearer " ``` ## Setup diff --git a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/subscriptions/1-subscription.md b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/subscriptions/1-subscription.md index 1b254d3857a..fbd3e765a18 100644 --- a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/subscriptions/1-subscription.md +++ b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/subscriptions/1-subscription.md @@ -18,7 +18,7 @@ Now we need to update our `ApolloClient` instance to point to the subscription s Open `src/ApolloClient.re` and update the `link` as follows: - + ```javascript @@ -40,4 +40,4 @@ Open `src/ApolloClient.re` and update the `link` as follows: +) ``` -Note that we are replacing HttpLink with WebSocketLink and hence all GraphQL queries go through a single websocket connection. Look at how we are passing the headers. While initializing websocket link, we need to pass headers in the `headers` key in the `connectionParams` accepted by `ApolloLinks.webSocketLink`. \ No newline at end of file +Note that we are replacing HttpLink with WebSocketLink and hence all GraphQL queries go through a single websocket connection. Look at how we are passing the headers. While initializing websocket link, we need to pass headers in the `headers` key in the `connectionParams` accepted by `ApolloLinks.webSocketLink`. From 6b8a6ca48f419c849552a82005e9d7286572940b Mon Sep 17 00:00:00 2001 From: Rakesh Emmadi <12475069+rakeshkky@users.noreply.github.com> Date: Thu, 1 Aug 2019 10:39:52 +0530 Subject: [PATCH 17/27] dont use sub-query for perm limit if aggregations are absent (#2630) --- .../src-lib/Hasura/RQL/DML/Select/Internal.hs | 140 +++++++++++------ server/src-lib/Hasura/RQL/DML/Select/Types.hs | 7 + .../agg_perm/author_post_agg_order_by.yaml | 27 ++++ .../queries/graphql_query/agg_perm/setup.yaml | 143 ++++++++++++------ .../graphql_query/agg_perm/teardown.yaml | 1 + server/tests-py/test_graphql_queries.py | 3 + 6 files changed, 230 insertions(+), 91 deletions(-) create mode 100644 server/tests-py/queries/graphql_query/agg_perm/author_post_agg_order_by.yaml diff --git a/server/src-lib/Hasura/RQL/DML/Select/Internal.hs b/server/src-lib/Hasura/RQL/DML/Select/Internal.hs index ad2242cc5be..8b523939c99 100644 --- a/server/src-lib/Hasura/RQL/DML/Select/Internal.hs +++ b/server/src-lib/Hasura/RQL/DML/Select/Internal.hs @@ -78,10 +78,14 @@ asSingleRowExtr col = , S.SEUnsafe "0" ] -withJsonAggExtr :: Maybe Int -> Maybe S.OrderByExp -> S.Alias -> S.SQLExp -withJsonAggExtr permLimitM ordBy alias = - maybe (mkSimpleJsonAgg rowIdenExp ordBy) withPermLimit permLimitM +withJsonAggExtr + :: Bool -> Maybe Int -> Maybe S.OrderByExp -> S.Alias -> S.SQLExp +withJsonAggExtr subQueryReq permLimitM ordBy alias = + -- if select has aggregations then use subquery to apply permission limit + if subQueryReq then maybe simpleJsonAgg withPermLimit permLimitM + else simpleJsonAgg where + simpleJsonAgg = mkSimpleJsonAgg rowIdenExp ordBy rowIdenExp = S.SEIden $ S.getAlias alias subSelAls = Iden "sub_query" unnestTable = Iden "unnest_table" @@ -128,12 +132,13 @@ withJsonAggExtr permLimitM ordBy alias = , iden ) - asJsonAggExtr - :: Bool -> S.Alias -> Maybe Int -> Maybe S.OrderByExp -> S.Extractor -asJsonAggExtr singleObj als permLimit ordByExpM = + :: Bool -> S.Alias -> Bool -> Maybe Int -> Maybe S.OrderByExp -> S.Extractor +asJsonAggExtr singleObj als subQueryReq permLimit ordByExpM = flip S.Extractor (Just als) $ - bool (withJsonAggExtr permLimit ordByExpM als) (asSingleRowExtr als) singleObj + bool (withJsonAggExtr subQueryReq permLimit ordByExpM als) + (asSingleRowExtr als) + singleObj -- array relationships are not grouped, so have to be prefixed by -- parent's alias @@ -194,8 +199,8 @@ buildJsonObject pfx parAls arrRelCtx strfyNum flds = let qual = mkObjRelTableAls pfx $ aarName objSel in S.mkQIdenExp qual fldAls FArr arrSel -> - let arrPfx = snd $ mkArrNodePfx pfx parAls arrRelCtx $ - ANIField (fldAls, arrSel) + let arrPfx = _aniPrefix $ mkArrNodeInfo pfx parAls arrRelCtx $ + ANIField (fldAls, arrSel) in S.mkQIdenExp arrPfx fldAls toSQLCol :: PGColInfo -> Maybe ColOp -> S.SQLExp @@ -308,15 +313,16 @@ processAnnOrderByCol pfx parAls arrRelCtx strfyNum = \case , OBNObjNode rn relNode ) AOCAgg (RelInfo rn _ colMapping relTab _ ) relFltr annAggOb -> - let (arrAls, arrPfx) = - mkArrNodePfx pfx parAls arrRelCtx $ ANIAggOrdBy rn + let ArrNodeInfo arrAls arrPfx _ = + mkArrNodeInfo pfx parAls arrRelCtx $ ANIAggOrdBy rn fldName = mkAggObFld annAggOb qOrdBy = S.mkQIdenExp arrPfx $ toIden fldName tabFrom = TableFrom relTab Nothing tabPerm = TablePerm relFltr Nothing (extr, arrFlds) = mkAggObExtrAndFlds annAggOb selFld = TAFAgg arrFlds - bn = mkBaseNode arrPfx fldName selFld tabFrom tabPerm noTableArgs strfyNum + bn = mkBaseNode False arrPfx fldName selFld tabFrom + tabPerm noTableArgs strfyNum aggNode = ArrNode [extr] colMapping $ mergeBaseNodes bn $ mkEmptyBaseNode arrPfx tabFrom obAls = arrPfx <> Iden "." <> toIden fldName @@ -367,44 +373,61 @@ aggSelToArrNode pfx als aggSel = mergedBN = foldr mergeBaseNodes emptyBN allBNs mkAggBaseNode (fn, selFld) = - mkBaseNode pfx fn selFld tabFrm tabPerm tabArgs strfyNum + mkBaseNode subQueryReq pfx fn selFld tabFrm tabPerm tabArgs strfyNum selFldToExtr (FieldName t, fld) = (:) (S.SELit t) $ pure $ case fld of TAFAgg flds -> aggFldToExp flds - TAFNodes _ -> withJsonAggExtr permLimit ordBy $ S.Alias $ Iden t + TAFNodes _ -> + withJsonAggExtr subQueryReq permLimit ordBy $ S.Alias $ Iden t TAFExp e -> -- bool_or to force aggregation S.SEFnApp "coalesce" [ S.SELit e , S.SEUnsafe "bool_or('true')::text"] Nothing -mkArrNodePfx + subQueryReq = hasAggFld aggFlds + +hasAggFld :: Foldable t => t (a, TableAggFldG v) -> Bool +hasAggFld = any (isTabAggFld . snd) + where + isTabAggFld (TAFAgg _) = True + isTabAggFld _ = False + +mkArrNodeInfo :: Iden -> FieldName -> ArrRelCtx -> ArrNodeItem - -> (S.Alias, Iden) -mkArrNodePfx pfx parAls (ArrRelCtx arrFlds obRels) = \case + -> ArrNodeInfo +mkArrNodeInfo pfx parAls (ArrRelCtx arrFlds obRels) = \case ANIField aggFld@(fld, annArrSel) -> let (rn, tabArgs) = fetchRNAndTArgs annArrSel similarFlds = getSimilarAggFlds rn tabArgs $ delete aggFld + similarFldNames = map fst similarFlds similarOrdByFound = rn `elem` obRels && tabArgs == noTableArgs extraOrdByFlds = bool [] [ordByFldName] similarOrdByFound - sortedFlds = sort $ fld : (similarFlds <> extraOrdByFlds) - in ( S.Alias $ mkUniqArrRelAls parAls sortedFlds - , mkArrRelTableAls pfx parAls sortedFlds - ) + sortedFlds = sort $ fld : (similarFldNames <> extraOrdByFlds) + alias = S.Alias $ mkUniqArrRelAls parAls sortedFlds + prefix = mkArrRelTableAls pfx parAls sortedFlds + in ArrNodeInfo alias prefix $ + subQueryRequired similarFlds similarOrdByFound ANIAggOrdBy rn -> - let similarFlds = getSimilarAggFlds rn noTableArgs id + let similarFlds = map fst $ getSimilarAggFlds rn noTableArgs id sortedFlds = sort $ ordByFldName:similarFlds - in ( S.Alias $ mkUniqArrRelAls parAls sortedFlds - , mkArrRelTableAls pfx parAls sortedFlds - ) + alias = S.Alias $ mkUniqArrRelAls parAls sortedFlds + prefix = mkArrRelTableAls pfx parAls sortedFlds + in ArrNodeInfo alias prefix False where - getSimilarAggFlds rn tabArgs f = map fst $ + getSimilarAggFlds rn tabArgs f = flip filter (f arrFlds) $ \(_, annArrSel) -> let (lrn, lTabArgs) = fetchRNAndTArgs annArrSel in (lrn == rn) && (lTabArgs == tabArgs) + subQueryRequired similarFlds hasSimOrdBy = + hasSimOrdBy || any hasAgg similarFlds + + hasAgg (_, ASSimple _) = False + hasAgg (_, ASAgg (AnnRelG _ _ annSel)) = hasAggFld $ _asnFields annSel + fetchRNAndTArgs (ASSimple (AnnRelG rn _ annSel)) = (rn, _asnArgs annSel) fetchRNAndTArgs (ASAgg (AnnRelG rn _ annSel)) = @@ -458,14 +481,37 @@ mkOrdByItems pfx fldAls orderByM strfyNum arrRelCtx = getOrdByAggNode _ = Nothing mkBaseNode - :: Iden -> FieldName -> TableAggFld -> TableFrom - -> TablePerm -> TableArgs -> Bool -> BaseNode -mkBaseNode pfx fldAls annSelFlds tableFrom tablePerm tableArgs strfyNum = - BaseNode pfx distExprM fromItem finalWhere ordByExpM limitM offsetM + :: Bool + -> Iden + -> FieldName + -> TableAggFld + -> TableFrom + -> TablePerm + -> TableArgs + -> Bool + -> BaseNode +mkBaseNode subQueryReq pfx fldAls annSelFlds tableFrom + tablePerm tableArgs strfyNum = + BaseNode pfx distExprM fromItem finalWhere ordByExpM finalLimit offsetM allExtrs allObjsWithOb allArrsWithOb where - fltr = _tpFilter tablePerm - TableArgs whereM orderByM limitM offsetM distM = tableArgs + TablePerm permFilter permLimit = tablePerm + TableArgs whereM orderByM inpLimitM offsetM distM = tableArgs + + -- if sub query is used, then only use input limit + -- because permission limit is being applied in subquery + -- else compare input and permission limits + finalLimit = + if subQueryReq then inpLimitM + else withPermLimit + + withPermLimit = + case (inpLimitM, permLimit) of + (inpLim, Nothing) -> inpLim + (Nothing, permLim) -> permLim + (Just inp, Just perm) -> Just $ if inp < perm then inp else perm + + aggOrdByRelNames = fetchOrdByAggRels orderByM (allExtrs, allObjsWithOb, allArrsWithOb, ordByExpM) = @@ -523,8 +569,8 @@ mkBaseNode pfx fldAls annSelFlds tableFrom tablePerm tableArgs strfyNum = in Just (S.Alias colAls, qualCol) mkColExp _ = Nothing - finalWhere = - toSQLBoolExp tableQual $ maybe fltr (andAnnBoolExps fltr) whereM + finalWhere = toSQLBoolExp tableQual $ + maybe permFilter (andAnnBoolExps permFilter) whereM fromItem = tableFromToFromItem tableFrom tableQual = tableFromToQual tableFrom @@ -545,9 +591,9 @@ mkBaseNode pfx fldAls annSelFlds tableFrom tablePerm tableArgs strfyNum = -- process an array/array-aggregate item mkArrItem arrRelCtx (fld, arrSel) = - let (arrAls, arrPfx) = mkArrNodePfx pfx fldAls arrRelCtx $ - ANIField (fld, arrSel) - arrNode = mkArrNode arrPfx (fld, arrSel) + let ArrNodeInfo arrAls arrPfx subQReq = + mkArrNodeInfo pfx fldAls arrRelCtx $ ANIField (fld, arrSel) + arrNode = mkArrNode subQReq arrPfx (fld, arrSel) in (arrAls, arrNode) getAnnObj (f, annFld) = case annFld of @@ -558,22 +604,22 @@ mkBaseNode pfx fldAls annSelFlds tableFrom tablePerm tableArgs strfyNum = FArr ar -> Just (f, ar) _ -> Nothing -annSelToBaseNode :: Iden -> FieldName -> AnnSimpleSel -> BaseNode -annSelToBaseNode pfx fldAls annSel = - mkBaseNode pfx fldAls (TAFNodes selFlds) tabFrm tabPerm tabArgs strfyNum +annSelToBaseNode :: Bool -> Iden -> FieldName -> AnnSimpleSel -> BaseNode +annSelToBaseNode subQueryReq pfx fldAls annSel = + mkBaseNode subQueryReq pfx fldAls (TAFNodes selFlds) tabFrm tabPerm tabArgs strfyNum where AnnSelG selFlds tabFrm tabPerm tabArgs strfyNum = annSel mkObjNode :: Iden -> (FieldName, ObjSel) -> ObjNode mkObjNode pfx (fldName, AnnRelG _ rMapn rAnnSel) = - ObjNode rMapn $ annSelToBaseNode pfx fldName rAnnSel + ObjNode rMapn $ annSelToBaseNode False pfx fldName rAnnSel -mkArrNode :: Iden -> (FieldName, ArrSel) -> ArrNode -mkArrNode pfx (fldName, annArrSel) = case annArrSel of +mkArrNode :: Bool -> Iden -> (FieldName, ArrSel) -> ArrNode +mkArrNode subQueryReq pfx (fldName, annArrSel) = case annArrSel of ASSimple annArrRel -> - let bn = annSelToBaseNode pfx fldName $ aarAnnSel annArrRel + let bn = annSelToBaseNode subQueryReq pfx fldName $ aarAnnSel annArrRel permLimit = getPermLimit $ aarAnnSel annArrRel - extr = asJsonAggExtr False (S.toAlias fldName) permLimit $ + extr = asJsonAggExtr False (S.toAlias fldName) subQueryReq permLimit $ _bnOrderBy bn in ArrNode [extr] (aarMapping annArrRel) bn @@ -650,9 +696,9 @@ mkSQLSelect isSingleObject annSel = prefixNumToAliases $ arrNodeToSelect baseNode extrs $ S.BELit True where permLimit = getPermLimit annSel - extrs = pure $ asJsonAggExtr isSingleObject rootFldAls permLimit + extrs = pure $ asJsonAggExtr isSingleObject rootFldAls False permLimit $ _bnOrderBy baseNode - baseNode = annSelToBaseNode (toIden rootFldName) rootFldName annSel + baseNode = annSelToBaseNode False (toIden rootFldName) rootFldName annSel rootFldName = FieldName "root" rootFldAls = S.Alias $ toIden rootFldName diff --git a/server/src-lib/Hasura/RQL/DML/Select/Types.hs b/server/src-lib/Hasura/RQL/DML/Select/Types.hs index 90530789a4e..ca735502c6b 100644 --- a/server/src-lib/Hasura/RQL/DML/Select/Types.hs +++ b/server/src-lib/Hasura/RQL/DML/Select/Types.hs @@ -389,3 +389,10 @@ mergeArrNodes lNode rNode = where ArrNode lExtrs colMapping lBN = lNode ArrNode rExtrs _ rBN = rNode + +data ArrNodeInfo + = ArrNodeInfo + { _aniAlias :: !S.Alias + , _aniPrefix :: !Iden + , _aniSubQueryRequired :: !Bool + } deriving (Show, Eq) diff --git a/server/tests-py/queries/graphql_query/agg_perm/author_post_agg_order_by.yaml b/server/tests-py/queries/graphql_query/agg_perm/author_post_agg_order_by.yaml new file mode 100644 index 00000000000..3628807dbf3 --- /dev/null +++ b/server/tests-py/queries/graphql_query/agg_perm/author_post_agg_order_by.yaml @@ -0,0 +1,27 @@ +description: Query author along with posts with order by posts count +url: /v1/graphql +status: 200 +headers: + X-Hasura-Role: user +response: + data: + author: + - id: 2 + name: Author 2 + posts: + - id: 4 + title: Post 4 + content: Post 4 Content +query: + query: | + query { + author(order_by: {posts_aggregate: {count: asc}}){ + id + name + posts{ + id + title + content + } + } + } diff --git a/server/tests-py/queries/graphql_query/agg_perm/setup.yaml b/server/tests-py/queries/graphql_query/agg_perm/setup.yaml index efd830b764a..a0b7c2170d6 100644 --- a/server/tests-py/queries/graphql_query/agg_perm/setup.yaml +++ b/server/tests-py/queries/graphql_query/agg_perm/setup.yaml @@ -1,23 +1,15 @@ type: bulk args: -#Author table - type: run_sql args: sql: | + -- author table create table author( id serial primary key, name text unique ); -- type: track_table - args: - schema: public - name: author - -#Article table -- type: run_sql - args: - sql: | + -- article table CREATE TABLE article ( id SERIAL PRIMARY KEY, title TEXT, @@ -25,13 +17,89 @@ args: author_id INTEGER REFERENCES author(id), is_published BOOLEAN, published_on TIMESTAMP NOT NULL DEFAULT NOW() - ) + ); + -- post table + CREATE TABLE post ( + id SERIAL PRIMARY KEY, + title TEXT, + content TEXT, + author_id INTEGER REFERENCES author(id) + ); + + -- insert data + INSERT INTO author (name) + VALUES + ('Author 1'), + ('Author 2') + ; + + INSERT INTO article (title,content,author_id,is_published) + VALUES + ( + 'Article 1', + 'Sample article content 1', + 1, + false + ), + ( + 'Article 2', + 'Sample article content 2', + 1, + true + ), + ( + 'Article 3', + 'Sample article content 3', + 2, + true + ) + ; + + INSERT INTO post (title, content, author_id) + VALUES + ( + 'Post 1', + 'Post 1 Content', + 1 + ), + ( + 'Post 2', + 'Post 2 Content', + 1 + ), + ( + 'Post 3', + 'Post 3 Content', + 1 + ), + ( + 'Post 4', + 'Post 4 Content', + 2 + ), + ( + 'Post 5', + 'Post 5 Content', + 2 + ) + ; + +- type: track_table + args: + schema: public + name: author + - type: track_table args: schema: public name: article -#Object relationship +- type: track_table + args: + schema: public + name: post + +#Object relationship article <-> author - type: create_object_relationship args: table: article @@ -39,7 +107,7 @@ args: using: foreign_key_constraint_on: author_id -#Array relationship +#Array relationship author <-> article - type: create_array_relationship args: table: author @@ -49,6 +117,16 @@ args: table: article column: author_id +#Array relationship author <-> post +- type: create_array_relationship + args: + table: author + name: posts + using: + foreign_key_constraint_on: + table: post + column: author_id + #Select pemissions on User - type: create_select_permission args: @@ -70,35 +148,12 @@ args: allow_aggregations: false limit: 1 -#Insert values -- type: run_sql +- type: create_select_permission args: - sql: | - insert into author (name) - values - ('Author 1'), - ('Author 2') - -- type: run_sql - args: - sql: | - insert into article (title,content,author_id,is_published) - values - ( - 'Article 1', - 'Sample article content 1', - 1, - false - ), - ( - 'Article 2', - 'Sample article content 2', - 1, - true - ), - ( - 'Article 3', - 'Sample article content 3', - 2, - true - ) + table: post + role: user + permission: + columns: '*' + filter: {} + allow_aggregations: true + limit: 1 diff --git a/server/tests-py/queries/graphql_query/agg_perm/teardown.yaml b/server/tests-py/queries/graphql_query/agg_perm/teardown.yaml index 278daa3ea5e..823e94bfc5a 100644 --- a/server/tests-py/queries/graphql_query/agg_perm/teardown.yaml +++ b/server/tests-py/queries/graphql_query/agg_perm/teardown.yaml @@ -12,5 +12,6 @@ args: args: sql: | DROP TABLE article; + DROP TABLE post; DROP TABLE author; cascade: true diff --git a/server/tests-py/test_graphql_queries.py b/server/tests-py/test_graphql_queries.py index 56d812162aa..bbaa5f50ba1 100644 --- a/server/tests-py/test_graphql_queries.py +++ b/server/tests-py/test_graphql_queries.py @@ -90,6 +90,9 @@ class TestGraphQLQueryAggPerm(DefaultTestSelectQueries): def test_author_articles_agg_fail(self, hge_ctx, transport): check_query_f(hge_ctx, self.dir() + '/author_articles_agg_fail.yaml', transport) + def test_author_post_agg_order_by(self, hge_ctx, transport): + check_query_f(hge_ctx, self.dir() + '/author_post_agg_order_by.yaml', transport) + @classmethod def dir(cls): return 'queries/graphql_query/agg_perm' From 727eee8493bbf135bb40036242ee023c1dcddc57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20T=C3=B6rnros?= Date: Thu, 1 Aug 2019 07:11:44 +0200 Subject: [PATCH 18/27] fix typo on event triggers boilerplates for Netlify Functions (#2493) --- community/boilerplates/event-triggers/README.md | 2 ++ .../{netlfy-functions => netlify-functions}/README.md | 0 2 files changed, 2 insertions(+) rename community/boilerplates/event-triggers/{netlfy-functions => netlify-functions}/README.md (100%) diff --git a/community/boilerplates/event-triggers/README.md b/community/boilerplates/event-triggers/README.md index 6866648a8e2..252d2b5abf5 100644 --- a/community/boilerplates/event-triggers/README.md +++ b/community/boilerplates/event-triggers/README.md @@ -12,6 +12,8 @@ Examples in this repository support the following cloud function platforms: * Zeit Now +* Netlify Functions + Note: *If you want to add support for other platforms, please submit a PR or create an issue and tag it with `help-wanted`* diff --git a/community/boilerplates/event-triggers/netlfy-functions/README.md b/community/boilerplates/event-triggers/netlify-functions/README.md similarity index 100% rename from community/boilerplates/event-triggers/netlfy-functions/README.md rename to community/boilerplates/event-triggers/netlify-functions/README.md From 84ff3ff01b8189a3cd81ef4ec72aaf81087e605c Mon Sep 17 00:00:00 2001 From: Alexis King Date: Thu, 1 Aug 2019 02:30:07 -0500 Subject: [PATCH 19/27] Set LANG=C.UTF-8 in the docker container (fix #2571) (#2647) --- server/Makefile | 2 +- server/packaging/build/Dockerfile | 3 ++- server/packaging/packager.df | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/server/Makefile b/server/Makefile index 617650f1572..a1384470bac 100644 --- a/server/Makefile +++ b/server/Makefile @@ -6,7 +6,7 @@ nproc := $(shell nproc) # TODO: needs to be replaced with something like yq stack_resolver := $(shell awk '/^resolver:/ {print $$2;}' stack.yaml) -packager_ver := 20190326 +packager_ver := 20190731 pg_dump_ver := 11 project_dir := $(shell pwd) build_dir := $(project_dir)/$(shell stack path --dist-dir)/build diff --git a/server/packaging/build/Dockerfile b/server/packaging/build/Dockerfile index 9cd54e19214..79daf7874e3 100644 --- a/server/packaging/build/Dockerfile +++ b/server/packaging/build/Dockerfile @@ -1,3 +1,4 @@ FROM scratch COPY rootfs/ / -CMD ["graphql-engine", "serve"] \ No newline at end of file +ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 +CMD ["graphql-engine", "serve"] diff --git a/server/packaging/packager.df b/server/packaging/packager.df index f56e06396d2..3d853c0415d 100644 --- a/server/packaging/packager.df +++ b/server/packaging/packager.df @@ -1,8 +1,8 @@ -FROM hasura/haskell-docker-packager:20190326 +FROM hasura/haskell-docker-packager:20190731 MAINTAINER vamshi@hasura.io RUN apt-get update && apt-get install -y libpq5 upx \ && update-ca-certificates \ && mkdir -p /usr/src/busybox/rootfs/etc/ssl/certs \ && cp -L /etc/ssl/certs/* /usr/src/busybox/rootfs/etc/ssl/certs/ \ - && rm -rf /var/lib/apt/lists/* \ No newline at end of file + && rm -rf /var/lib/apt/lists/* From b4a0a0363149c5ea426c00c7260afa92a3174929 Mon Sep 17 00:00:00 2001 From: Anon Ray Date: Thu, 1 Aug 2019 16:21:59 +0530 Subject: [PATCH 20/27] log when request body parsing fails (fix #2555) (#2556) --- .../Hasura/GraphQL/Transport/WebSocket.hs | 2 +- server/src-lib/Hasura/Server/App.hs | 68 +++++++++++-------- server/src-lib/Hasura/Server/Auth/JWT.hs | 28 ++++++-- .../src-lib/Hasura/Server/Auth/JWT/Logging.hs | 28 +++++--- server/src-lib/Hasura/Server/Utils.hs | 2 +- server/tests-py/test_logging.py | 25 +++++++ 6 files changed, 105 insertions(+), 48 deletions(-) diff --git a/server/src-lib/Hasura/GraphQL/Transport/WebSocket.hs b/server/src-lib/Hasura/GraphQL/Transport/WebSocket.hs index 84b6afa56d5..983b3c7c104 100644 --- a/server/src-lib/Hasura/GraphQL/Transport/WebSocket.hs +++ b/server/src-lib/Hasura/GraphQL/Transport/WebSocket.hs @@ -136,7 +136,7 @@ data WSLogInfo , _wsliConnectionInfo :: !WsConnInfo , _wsliEvent :: !WSEvent } deriving (Show, Eq) -$(J.deriveToJSON (J.aesonDrop 4 J.snakeCase) ''WSLogInfo) +$(J.deriveToJSON (J.aesonDrop 5 J.snakeCase) ''WSLogInfo) data WSLog = WSLog diff --git a/server/src-lib/Hasura/Server/App.hs b/server/src-lib/Hasura/Server/App.hs index 229eed905d3..6c8472d62cd 100644 --- a/server/src-lib/Hasura/Server/App.hs +++ b/server/src-lib/Hasura/Server/App.hs @@ -205,9 +205,19 @@ logResult logger userInfoM reqId httpReq req res qTime = do let logline = case res of Right res' -> mkHttpAccessLog userInfoM reqId httpReq res' qTime Left e -> mkHttpErrorLog userInfoM reqId httpReq e req qTime - liftIO $ L.unLogger logger $ logline --- logResult userInfoM req reqBody logger res qTime = --- liftIO $ L.unLogger logger $ mkAccessLog userInfoM req (reqBody, res) qTime + liftIO $ L.unLogger logger logline + +logSuccess + :: (MonadIO m) + => L.Logger + -> Maybe UserInfo + -> RequestId + -> Wai.Request + -> BL.ByteString + -> Maybe (UTCTime, UTCTime) + -> m () +logSuccess logger userInfoM reqId httpReq res qTime = + liftIO $ L.unLogger logger $ mkHttpAccessLog userInfoM reqId httpReq res qTime logError :: (MonadIO m) @@ -233,10 +243,12 @@ mkSpockAction qErrEncoder qErrModifier serverCtx apiHandler = do let headers = requestHeaders req authMode = scAuthMode serverCtx manager = scManager serverCtx + -- convert ByteString to Maybe Value for logging + reqTxt = Just $ String $ bsToTxt $ BL.toStrict reqBody requestId <- getRequestId headers userInfoE <- liftIO $ runExceptT $ getUserInfo logger manager headers authMode - userInfo <- either (logAndThrow requestId req reqBody False . qErrModifier) + userInfo <- either (logErrorAndResp Nothing requestId req reqTxt False . qErrModifier) return userInfoE let handlerState = HandlerCtx serverCtx userInfo headers requestId @@ -250,7 +262,7 @@ mkSpockAction qErrEncoder qErrModifier serverCtx apiHandler = do return (res, Nothing) AHPost handler -> do parsedReqE <- runExceptT $ parseBody reqBody - parsedReq <- either (qErrToResp (isAdmin curRole) . qErrModifier) return parsedReqE + parsedReq <- either (logErrorAndResp (Just userInfo) requestId req reqTxt (isAdmin curRole) . qErrModifier) return parsedReqE res <- liftIO $ runReaderT (runExceptT $ handler parsedReq) handlerState return (res, Just parsedReq) @@ -259,36 +271,34 @@ mkSpockAction qErrEncoder qErrModifier serverCtx apiHandler = do -- apply the error modifier let modResult = fmapL qErrModifier result - -- log result - logResult logger (Just userInfo) requestId req (toJSON <$> q) - (apiRespToLBS <$> modResult) $ Just (t1, t2) - either (qErrToResp (isAdmin curRole)) (resToResp requestId) modResult + -- log and return result + case modResult of + Left err -> logErrorAndResp (Just userInfo) requestId req (toJSON <$> q) (isAdmin curRole) err + Right res -> logSuccessAndResp (Just userInfo) requestId req res (Just (t1, t2)) where - logger = scLogger serverCtx + logger = scLogger serverCtx - logAndThrow reqId req reqBody includeInternal qErr = do - let reqTxt = Just $ toJSON $ String $ bsToTxt $ BL.toStrict reqBody - logError logger Nothing reqId req reqTxt qErr - qErrToResp includeInternal qErr - - -- encode error response - qErrToResp :: (MonadIO m) => Bool -> QErr -> ActionCtxT ctx m b - qErrToResp includeInternal qErr = do + logErrorAndResp + :: (MonadIO m) + => Maybe UserInfo -> RequestId -> Wai.Request -> Maybe Value -> Bool -> QErr -> ActionCtxT ctx m a + logErrorAndResp userInfo reqId req reqBody includeInternal qErr = do + logError logger userInfo reqId req reqBody qErr setStatus $ qeStatus qErr json $ qErrEncoder includeInternal qErr - resToResp reqId = \case - JSONResp (HttpResponse j h) -> do - uncurry setHeader jsonHeader - uncurry setHeader (requestIdHeader, unRequestId reqId) - mapM_ (mapM_ (uncurry setHeader . unHeader)) h - lazyBytes $ encJToLBS j - RawResp (HttpResponse b h) -> do - uncurry setHeader (requestIdHeader, unRequestId reqId) - mapM_ (mapM_ (uncurry setHeader . unHeader)) h - lazyBytes b - + logSuccessAndResp userInfo reqId req result qTime = do + logSuccess logger userInfo reqId req (apiRespToLBS result) qTime + case result of + JSONResp (HttpResponse j h) -> do + uncurry setHeader jsonHeader + uncurry setHeader (requestIdHeader, unRequestId reqId) + mapM_ (mapM_ (uncurry setHeader . unHeader)) h + lazyBytes $ encJToLBS j + RawResp (HttpResponse b h) -> do + uncurry setHeader (requestIdHeader, unRequestId reqId) + mapM_ (mapM_ (uncurry setHeader . unHeader)) h + lazyBytes b v1QueryHandler :: RQLQuery -> Handler (HttpResponse EncJSON) v1QueryHandler query = do diff --git a/server/src-lib/Hasura/Server/Auth/JWT.hs b/server/src-lib/Hasura/Server/Auth/JWT.hs index 5032a56a231..490bbb1cd7c 100644 --- a/server/src-lib/Hasura/Server/Auth/JWT.hs +++ b/server/src-lib/Hasura/Server/Auth/JWT.hs @@ -98,6 +98,13 @@ defaultRoleClaim = "x-hasura-default-role" defaultClaimNs :: T.Text defaultClaimNs = "https://hasura.io/jwt/claims" +-- | if the time is greater than 100 seconds, should refresh the JWK 10 seonds +-- before the expiry, else refresh at given seconds +computeDiffTime :: NominalDiffTime -> Int +computeDiffTime t = + let intTime = diffTimeToMicro t + in if intTime > 100 then intTime - 10 else intTime + -- | create a background thread to refresh the JWK jwkRefreshCtrl :: (MonadIO m) @@ -113,7 +120,9 @@ jwkRefreshCtrl lggr mngr url ref time = forever $ do res <- runExceptT $ updateJwkRef lggr mngr url ref mTime <- either (const $ return Nothing) return res - C.threadDelay $ maybe (60 * aSecond) diffTimeToMicro mTime + -- if can't parse time from header, defaults to 1 min + let delay = maybe (60 * aSecond) computeDiffTime mTime + C.threadDelay delay where aSecond = 1000 * 1000 @@ -130,7 +139,7 @@ updateJwkRef updateJwkRef (Logger logger) manager url jwkRef = do let options = wreqOptions manager [] urlT = T.pack $ show url - infoMsg = "refreshing JWK from endpoint: " <> urlT + infoMsg = JLNInfo $ "refreshing JWK from endpoint: " <> urlT liftIO $ logger $ JwkRefreshLog LevelInfo infoMsg Nothing res <- liftIO $ try $ Wreq.getWith options $ show url resp <- either logAndThrowHttp return res @@ -156,18 +165,23 @@ updateJwkRef (Logger logger) manager url jwkRef = do return $ diffUTCTime expires currTime where - logAndThrow :: (MonadIO m, MonadError T.Text m) => T.Text -> Maybe JwkRefreshHttpError -> m a + logAndThrow + :: (MonadIO m, MonadError T.Text m) + => T.Text -> Maybe JwkRefreshHttpError -> m a logAndThrow err httpErr = do - liftIO $ logger $ JwkRefreshLog (LevelOther "critical") err httpErr + liftIO $ logger $ JwkRefreshLog (LevelOther "critical") (JLNError err) httpErr throwError err logAndThrowHttp :: (MonadIO m, MonadError T.Text m) => HTTP.HttpException -> m a logAndThrowHttp err = do - let httpErr = JwkRefreshHttpError Nothing (T.pack $ show url) - (Just $ HttpException err) Nothing - errMsg = "Error fetching JWK: " <> T.pack (show err) + let httpErr = JwkRefreshHttpError Nothing (T.pack $ show url) (Just $ HttpException err) Nothing + errMsg = "Error fetching JWK: " <> T.pack (getHttpExceptionMsg err) logAndThrow errMsg (Just httpErr) + getHttpExceptionMsg = \case + HTTP.HttpExceptionRequest _ reason -> show reason + HTTP.InvalidUrlException _ reason -> show reason + timeFmt = "%a, %d %b %Y %T GMT" diff --git a/server/src-lib/Hasura/Server/Auth/JWT/Logging.hs b/server/src-lib/Hasura/Server/Auth/JWT/Logging.hs index b532a8487b1..6892b228f64 100644 --- a/server/src-lib/Hasura/Server/Auth/JWT/Logging.hs +++ b/server/src-lib/Hasura/Server/Auth/JWT/Logging.hs @@ -1,7 +1,7 @@ module Hasura.Server.Auth.JWT.Logging ( JwkRefreshLog (..) , JwkRefreshHttpError (..) - , mkJwkRefreshLog + , JwkLogNotice (..) ) where @@ -12,15 +12,21 @@ import Hasura.Logging (EngineLogType (..), LogLevel (..), ToEngineLog (..)) import Hasura.Prelude import Hasura.Server.Logging () +import Hasura.Server.Utils (httpExceptToJSON) import qualified Data.Text as T import qualified Network.HTTP.Types as HTTP +data JwkLogNotice + = JLNInfo !Text + | JLNError !Text + deriving (Show) + data JwkRefreshLog = JwkRefreshLog { jrlLogLevel :: !LogLevel - , jrlError :: !T.Text + , jrlNotice :: !JwkLogNotice , jrlHttpError :: !(Maybe JwkRefreshHttpError) } deriving (Show) @@ -37,18 +43,20 @@ instance ToJSON JwkRefreshHttpError where object [ "status_code" .= (HTTP.statusCode <$> jrheStatus jhe) , "url" .= jrheUrl jhe , "response" .= jrheResponse jhe - , "http_exception" .= (toJSON <$> jrheHttpException jhe) + , "http_exception" .= (httpExceptToJSON . unHttpException <$> jrheHttpException jhe) ] instance ToJSON JwkRefreshLog where - toJSON jrl = - object [ "error" .= jrlError jrl - , "http_error" .= (toJSON <$> jrlHttpError jrl) - ] + toJSON jrl = case jrlNotice jrl of + JLNInfo info -> + object [ "message" .= info + , "http_error" .= (toJSON <$> jrlHttpError jrl) + ] + JLNError err -> + object [ "error" .= err + , "http_error" .= (toJSON <$> jrlHttpError jrl) + ] instance ToEngineLog JwkRefreshLog where toEngineLog jwkRefreshLog = (jrlLogLevel jwkRefreshLog, ELTJwkRefreshLog, toJSON jwkRefreshLog) - -mkJwkRefreshLog :: LogLevel -> T.Text -> Maybe JwkRefreshHttpError -> JwkRefreshLog -mkJwkRefreshLog = JwkRefreshLog diff --git a/server/src-lib/Hasura/Server/Utils.hs b/server/src-lib/Hasura/Server/Utils.hs index 90c562f086e..391325d8168 100644 --- a/server/src-lib/Hasura/Server/Utils.hs +++ b/server/src-lib/Hasura/Server/Utils.hs @@ -180,7 +180,7 @@ fmapL _ (Right x) = pure x -- diff time to micro seconds diffTimeToMicro :: NominalDiffTime -> Int diffTimeToMicro diff = - (floor (realToFrac diff :: Double) - 10) * aSecond + floor (realToFrac diff :: Double) * aSecond where aSecond = 1000 * 1000 diff --git a/server/tests-py/test_logging.py b/server/tests-py/test_logging.py index 43f5fb790cf..0af46eebb6d 100644 --- a/server/tests-py/test_logging.py +++ b/server/tests-py/test_logging.py @@ -21,6 +21,8 @@ class TestLogging(): # setup some tables st_code, resp = hge_ctx.v1q_f(self.dir + '/setup.yaml') assert st_code == 200, resp + + # make a successful query q = {'query': 'query { hello {code name} }'} headers = {} if hge_ctx.hge_key: @@ -28,6 +30,17 @@ class TestLogging(): resp = hge_ctx.http.post(hge_ctx.hge_url + '/v1/graphql', json=q, headers=headers) assert resp.status_code == 200 and 'data' in resp.json() + + # make a query where JSON body parsing fails + q = {'quer': 'query { hello {code name} }'} + headers = {'x-request-id': 'json-parse-fail-log-test'} + if hge_ctx.hge_key: + headers['x-hasura-admin-secret'] = hge_ctx.hge_key + resp = hge_ctx.http.post(hge_ctx.hge_url + '/v1/graphql', json=q, + headers=headers) + assert resp.status_code == 200 and 'errors' in resp.json() + + # gather and parse the logs now self.logs = self._parse_logs(hge_ctx) # sometimes the log might take time to buffer time.sleep(2) @@ -115,3 +128,15 @@ class TestLogging(): assert 'query' in onelog assert 'query' in onelog['query'] assert 'generated_sql' in onelog + + def test_http_parse_failed_log(self, hge_ctx): + def _get_parse_failed_logs(x): + return x['type'] == 'http-log' and \ + x['detail']['operation']['request_id'] == 'json-parse-fail-log-test' + + http_logs = list(filter(_get_parse_failed_logs, self.logs)) + print('parse failed logs', http_logs) + assert len(http_logs) > 0 + print(http_logs[0]) + assert 'error' in http_logs[0]['detail']['operation'] + assert http_logs[0]['detail']['operation']['error']['code'] == 'parse-failed' From bfc6fc8a5ec7020afe9f5f422348249a941e4cc5 Mon Sep 17 00:00:00 2001 From: Shahidh K Muhammed Date: Thu, 1 Aug 2019 16:26:32 +0530 Subject: [PATCH 21/27] update manifests to v1.0.0-beta.4 --- install-manifests/azure-container-with-pg/azuredeploy.json | 2 +- install-manifests/azure-container/azuredeploy.json | 2 +- install-manifests/docker-compose-https/docker-compose.yaml | 2 +- install-manifests/docker-compose-pgadmin/docker-compose.yaml | 2 +- install-manifests/docker-compose-postgis/docker-compose.yaml | 2 +- install-manifests/docker-compose/docker-compose.yaml | 3 ++- install-manifests/docker-run/docker-run.sh | 2 +- install-manifests/google-cloud-k8s-sql/deployment.yaml | 2 +- install-manifests/kubernetes/deployment.yaml | 2 +- scripts/cli-migrations/Dockerfile | 2 +- 10 files changed, 11 insertions(+), 10 deletions(-) diff --git a/install-manifests/azure-container-with-pg/azuredeploy.json b/install-manifests/azure-container-with-pg/azuredeploy.json index 8a4adf64121..7c239832811 100644 --- a/install-manifests/azure-container-with-pg/azuredeploy.json +++ b/install-manifests/azure-container-with-pg/azuredeploy.json @@ -97,7 +97,7 @@ "firewallRuleName": "allow-all-azure-firewall-rule", "containerGroupName": "[concat(parameters('name'), '-container-group')]", "containerName": "hasura-graphql-engine", - "containerImage": "hasura/graphql-engine:v1.0.0-beta.3" + "containerImage": "hasura/graphql-engine:v1.0.0-beta.4" }, "resources": [ { diff --git a/install-manifests/azure-container/azuredeploy.json b/install-manifests/azure-container/azuredeploy.json index 3404cca3f5b..8276a2aa422 100644 --- a/install-manifests/azure-container/azuredeploy.json +++ b/install-manifests/azure-container/azuredeploy.json @@ -55,7 +55,7 @@ "dbName": "[parameters('postgresDatabaseName')]", "containerGroupName": "[concat(parameters('name'), '-container-group')]", "containerName": "hasura-graphql-engine", - "containerImage": "hasura/graphql-engine:v1.0.0-beta.3" + "containerImage": "hasura/graphql-engine:v1.0.0-beta.4" }, "resources": [ { diff --git a/install-manifests/docker-compose-https/docker-compose.yaml b/install-manifests/docker-compose-https/docker-compose.yaml index 83233b91627..a7631fb2109 100644 --- a/install-manifests/docker-compose-https/docker-compose.yaml +++ b/install-manifests/docker-compose-https/docker-compose.yaml @@ -6,7 +6,7 @@ services: volumes: - db_data:/var/lib/postgresql/data graphql-engine: - image: hasura/graphql-engine:v1.0.0-beta.3 + image: hasura/graphql-engine:v1.0.0-beta.4 depends_on: - "postgres" restart: always diff --git a/install-manifests/docker-compose-pgadmin/docker-compose.yaml b/install-manifests/docker-compose-pgadmin/docker-compose.yaml index 380f91a7076..61e6b75d5b1 100644 --- a/install-manifests/docker-compose-pgadmin/docker-compose.yaml +++ b/install-manifests/docker-compose-pgadmin/docker-compose.yaml @@ -17,7 +17,7 @@ services: PGADMIN_DEFAULT_EMAIL: pgadmin@example.com PGADMIN_DEFAULT_PASSWORD: admin graphql-engine: - image: hasura/graphql-engine:v1.0.0-beta.3 + image: hasura/graphql-engine:v1.0.0-beta.4 ports: - "8080:8080" depends_on: diff --git a/install-manifests/docker-compose-postgis/docker-compose.yaml b/install-manifests/docker-compose-postgis/docker-compose.yaml index f7a62b0f466..9a876c56615 100644 --- a/install-manifests/docker-compose-postgis/docker-compose.yaml +++ b/install-manifests/docker-compose-postgis/docker-compose.yaml @@ -6,7 +6,7 @@ services: volumes: - db_data:/var/lib/postgresql/data graphql-engine: - image: hasura/graphql-engine:v1.0.0-beta.3 + image: hasura/graphql-engine:v1.0.0-beta.4 ports: - "8080:8080" depends_on: diff --git a/install-manifests/docker-compose/docker-compose.yaml b/install-manifests/docker-compose/docker-compose.yaml index a0f91162b1d..9c339722a5a 100644 --- a/install-manifests/docker-compose/docker-compose.yaml +++ b/install-manifests/docker-compose/docker-compose.yaml @@ -6,7 +6,7 @@ services: volumes: - db_data:/var/lib/postgresql/data graphql-engine: - image: hasura/graphql-engine:v1.0.0-beta.3 + image: hasura/graphql-engine:v1.0.0-beta.4 ports: - "8080:8080" depends_on: @@ -15,6 +15,7 @@ services: environment: HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:@postgres:5432/postgres HASURA_GRAPHQL_ENABLE_CONSOLE: "true" # set to "false" to disable console + HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log ## uncomment next line to set an admin secret # HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey volumes: diff --git a/install-manifests/docker-run/docker-run.sh b/install-manifests/docker-run/docker-run.sh index c450844d46d..4aada48c4c1 100755 --- a/install-manifests/docker-run/docker-run.sh +++ b/install-manifests/docker-run/docker-run.sh @@ -2,4 +2,4 @@ docker run -d -p 8080:8080 \ -e HASURA_GRAPHQL_DATABASE_URL=postgres://username:password@hostname:port/dbname \ -e HASURA_GRAPHQL_ENABLE_CONSOLE=true \ - hasura/graphql-engine:v1.0.0-beta.3 \ No newline at end of file + hasura/graphql-engine:v1.0.0-beta.4 \ No newline at end of file diff --git a/install-manifests/google-cloud-k8s-sql/deployment.yaml b/install-manifests/google-cloud-k8s-sql/deployment.yaml index fb5998bddf3..3b8eb89a4b4 100644 --- a/install-manifests/google-cloud-k8s-sql/deployment.yaml +++ b/install-manifests/google-cloud-k8s-sql/deployment.yaml @@ -16,7 +16,7 @@ spec: spec: containers: - name: graphql-engine - image: hasura/graphql-engine:v1.0.0-beta.3 + image: hasura/graphql-engine:v1.0.0-beta.4 ports: - containerPort: 8080 # The following environment variables will contain the database host, diff --git a/install-manifests/kubernetes/deployment.yaml b/install-manifests/kubernetes/deployment.yaml index b7ab200fc18..7538272e6c3 100644 --- a/install-manifests/kubernetes/deployment.yaml +++ b/install-manifests/kubernetes/deployment.yaml @@ -18,7 +18,7 @@ spec: app: hasura spec: containers: - - image: hasura/graphql-engine:v1.0.0-beta.3 + - image: hasura/graphql-engine:v1.0.0-beta.4 imagePullPolicy: IfNotPresent name: hasura env: diff --git a/scripts/cli-migrations/Dockerfile b/scripts/cli-migrations/Dockerfile index eb7edac261b..774083798fc 100644 --- a/scripts/cli-migrations/Dockerfile +++ b/scripts/cli-migrations/Dockerfile @@ -1,4 +1,4 @@ -FROM hasura/graphql-engine:v1.0.0-beta.3 +FROM hasura/graphql-engine:v1.0.0-beta.4 # set an env var to let the cli know that # it is running in server environment From 1115d0c9a065b3184a3553e2cfb0a5aed23b31f1 Mon Sep 17 00:00:00 2001 From: surendran82 Date: Thu, 1 Aug 2019 18:16:43 +0530 Subject: [PATCH 22/27] community: learn: home page design updates (#2588) --- .../homepage/src/components/AllState.js | 8 +- .../homepage/src/components/Featured.js | 35 ++ .../src/components/Styles.module.scss | 322 ------------------ .../homepage/src/components/Testimonials.js | 297 ++++------------ .../homepage/src/components/TopBanner.js | 2 +- .../homepage/src/components/WillLearn.js | 2 +- .../src/components/images/Left-Arrow.png | Bin 2098 -> 0 bytes .../src/components/images/Right-Arrow.png | Bin 2070 -> 0 bytes .../src/components/images/quote-left.svg | 21 -- .../src/components/images/quote-right.svg | 21 -- .../src/components/images/twitter.svg | 1 - .../homepage/src/pages/index.js | 2 + .../homepage/src/styles/styles.scss | 234 +++++++++++-- .../android-apollo/tutorial-site/Dockerfile | 2 +- .../tutorial-site/Dockerfile.localdev | 2 +- .../android-apollo/tutorial-site/config.js | 9 +- .../tutorial-site/content/apollo-client.md | 8 +- .../tutorial-site/content/introduction.md | 15 +- .../elm-graphql/tutorial-site/Dockerfile | 2 +- .../tutorial-site/Dockerfile.localdev | 2 +- .../elm-graphql/tutorial-site/config.js | 17 +- .../tutorial-site/content/introduction.md | 2 +- .../content/realtime-feed/2-sync-todo.md | 2 +- .../ios-apollo/tutorial-site/Dockerfile | 2 +- .../tutorial-site/Dockerfile.localdev | 2 +- .../ios-apollo/tutorial-site/config.js | 11 +- .../tutorial-site/content/apollo-client.md | 4 +- .../tutorial-site/content/introduction.md | 2 +- .../content/queries/2-create-query.md | 2 +- .../react-apollo/tutorial-site/Dockerfile | 2 +- .../tutorial-site/Dockerfile.localdev | 2 +- .../react-apollo/tutorial-site/config.js | 11 +- .../tutorial-site/content/introduction.md | 2 +- .../tutorial-site/Dockerfile | 2 +- .../tutorial-site/Dockerfile.localdev | 2 +- .../tutorial-site/config.js | 9 +- .../tutorial-site/content/introduction.md | 2 +- .../tutorial-site/Dockerfile | 2 +- .../tutorial-site/Dockerfile.localdev | 2 +- .../tutorial-site/config.js | 9 +- .../tutorial-site/content/introduction.md | 2 +- .../vue-apollo/tutorial-site/Dockerfile | 2 +- .../tutorial-site/Dockerfile.localdev | 2 +- .../vue-apollo/tutorial-site/config.js | 11 +- .../tutorial-site/content/introduction.md | 2 +- 45 files changed, 406 insertions(+), 687 deletions(-) create mode 100644 community/learn/graphql-tutorials/backend-services/homepage/src/components/Featured.js delete mode 100644 community/learn/graphql-tutorials/backend-services/homepage/src/components/images/Left-Arrow.png delete mode 100644 community/learn/graphql-tutorials/backend-services/homepage/src/components/images/Right-Arrow.png delete mode 100644 community/learn/graphql-tutorials/backend-services/homepage/src/components/images/quote-left.svg delete mode 100644 community/learn/graphql-tutorials/backend-services/homepage/src/components/images/quote-right.svg delete mode 100644 community/learn/graphql-tutorials/backend-services/homepage/src/components/images/twitter.svg diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/components/AllState.js b/community/learn/graphql-tutorials/backend-services/homepage/src/components/AllState.js index 0389c9fd083..690821dbb8f 100644 --- a/community/learn/graphql-tutorials/backend-services/homepage/src/components/AllState.js +++ b/community/learn/graphql-tutorials/backend-services/homepage/src/components/AllState.js @@ -15,8 +15,8 @@ const frontendTutorial = [ }, { name: 'Angular', - url: 'https://learn.hasura.io/graphql/angular', - comingSoon: true, + url: 'https://learn.hasura.io/graphql/angular-apollo', + comingSoon: false, bgClassName: 'angularBg', disableBgClassName: 'angularDisableBg', }, @@ -75,8 +75,8 @@ const mobileTutorial = [ }, { name: 'Flutter', - url: 'https://learn.hasura.io/graphql/flutter', - comingSoon: true, + url: 'https://learn.hasura.io/graphql/flutter-graphql', + comingSoon: false, bgClassName: 'flutterBg', disableBgClassName: 'flutterDisableBg', }, diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/components/Featured.js b/community/learn/graphql-tutorials/backend-services/homepage/src/components/Featured.js new file mode 100644 index 00000000000..38263a2318d --- /dev/null +++ b/community/learn/graphql-tutorials/backend-services/homepage/src/components/Featured.js @@ -0,0 +1,35 @@ +import React from 'react'; +import '../styles/styles.scss'; +class Featured extends React.Component { + render() { + return ( +
    +
    +
    +
    + We’ve been featured! +
    +
    +
    +
    +
    + {'Frontend +
    +
    + {'JSK'}/ +
    +
    + {'React +
    +
    + {'Vue +
    +
    +
    +
    +
    + ); + } +} + +export default Featured; diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/components/Styles.module.scss b/community/learn/graphql-tutorials/backend-services/homepage/src/components/Styles.module.scss index cce3b31649d..e69de29bb2d 100644 --- a/community/learn/graphql-tutorials/backend-services/homepage/src/components/Styles.module.scss +++ b/community/learn/graphql-tutorials/backend-services/homepage/src/components/Styles.module.scss @@ -1,322 +0,0 @@ -/* Testimonial section start here */ -.Testimonials { - background-color: #f7f7f7; -} -.TestimonialsSection { - padding: 75px 0; -} -.pageSubHeader -{ - font-weight: 600; - font-size: 26px; - text-align: center; - color: #102261; - padding-bottom: 20px; - line-height: normal; -} -.TestimonialsWrapper -{ - clear: both; - .pageSubHeader - { - text-align: center; - color: #2b0785; - padding-bottom: 40px; - } - .testimonialsCarouselWrapper - { - // padding-top: 20px; - .testimonialsCarousel - { - .quoteImg - { - position: absolute; - top: -66px; - } - .quoteLeft - { - left: -30px; - } - .quoteright - { - right: -30px; - } - .carouselIndicators - { - bottom: -65px; - li - { - margin: 0 16px; - border: 1px solid #2b0785; - width: 8px; - height: 8px; - } - } - .carouselInner - { - width: 90%; - margin: 0 auto; - min-height: 188px; - .carouselInnerItems - { - margin-bottom: 5px; - padding: 0 20px; - width: 100%; - float: left; - // min-height: 618px; - .indivRectBox - { - background-color: #fff; - border-radius: 2px; - box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.16); - padding: 15px; - position: relative; - // margin-top: 30px; - min-height: 180px; - .pageDescription - { - font-weight: 600; - padding-bottom: 10px; - line-height: 1.5; - width: 97%; - font-size: 14px; - a - { - color: #1f88e5; - } - a:hover - { - text-decoration: none; - color: #1f88e5 !important; - border-bottom: 1px solid #1f88e5 !important; - } - } - .pageDescriptionSmall - { - padding-bottom: 0px; - line-height: normal; - font-weight: 300; - color: #505050; - text-align: left; - a - { - color: #1f88e5; - text-decoration: none; - } - a:hover - { - text-decoration: none; - border-bottom: 1px solid #1f88e5; - } - } - .pageDescription, .pageDescription1 - { - text-align: left; - color: #fff; - } - .quotes - { - position: absolute; - top: 20px; - right: 20px; - img - { - width: 23px; - } - .imgSmall - { - width: 20px; - } - } - } - } - } - .carouselControl - { - width: 50px; - display: flex; - align-items: center; - justify-content: center; - background-image: inherit !important; - img - { - height: 25px; - display: inline-block; - } - } - .prodImgSmall - { - max-height: 62px; - } - } - .graphql_discription - { - padding-top: 20px; - color: #fff; - text-align: center; - } - } -} -/* Testimonial section ends here */ -@media (max-width: 767px) -{ - /* Testimonial section start here */ - .TestimonialsWrapper - { - // padding-top: 30px; - .pageSubHeader - { - padding: 0 15px; - padding-bottom: 0; - } - .testimonialsCarouselWrapper - { - padding-top: 0; - .testimonialsCarousel - { - .quoteImg - { - width: 30px; - top: 5px; - } - .quoteLeft - { - left: -15px; - } - .quoteright - { - right: -15px; - } - .carouselInner - { - width: 100%; - padding-bottom: 3px; - .carouselInnerItems - { - padding: 0 0px; - .indivRectBox - { - min-height: auto; - margin-top: 30px; - .pageDescription - { - font-size: 14px; - width: 93%; - } - .pageDescriptionSmall - { - word-break: break-word; - font-size: 15px; - } - .pageDescription1 - { - font-size: 13px; - } - .quotes - { - img - { - width: 15px; - } - .imgSmall - { - width: 15px; - } - } - } - } - } - } - } - } - /* Testimonial section ends here */ -} -@media (min-width: 768px) and (max-width: 991px) -{ - /* Testimonial section start here */ - .TestimonialsWrapper - { - .testimonialsCarouselWrapper - { - .testimonialsCarousel - { - .quoteImg - { - width: 60px; - top: -49px; - } - .quoteLeft - { - left: -20px; - } - .quoteright - { - right: -20px; - } - .carouselInner - { - width: 90%; - min-height: 230px; - .carouselInnerItems - { - padding: 0 0px; - // min-height: 768px; - .indivRectBox - { - min-height: 222px; - .pageDescription - { - font-size: 15px; - } - .pageDescriptionSmall - { - word-break: break-word; - font-size: 15px; - } - .quotes - { - img - { - width: 18px; - } - .imgSmall - { - width: 18px; - } - } - .pageDescription1 - { - line-height: 1.4; - } - } - } - } - } - } - } - /* Testimonial section ends here */ -} -@media(width: 1024px) -{ - .TestimonialsWrapper - { - .testimonialsCarouselWrapper - { - .testimonialsCarousel - { - .carouselInner - { - width: 90%; - .carouselInnerItems - { - padding: 0 0px; - .indivRectBox - { - min-height: 213px; - } - } - } - } - } - } -} diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/components/Testimonials.js b/community/learn/graphql-tutorials/backend-services/homepage/src/components/Testimonials.js index 5073d55e60a..13bc9ed85ae 100644 --- a/community/learn/graphql-tutorials/backend-services/homepage/src/components/Testimonials.js +++ b/community/learn/graphql-tutorials/backend-services/homepage/src/components/Testimonials.js @@ -1,241 +1,72 @@ import React from 'react'; - +import '../styles/styles.scss'; class Testimonials extends React.Component { + constructor() { + super(); + this.state = { + testimonial: [ + { + description: (“This is one of the best tutorials I have seen for getting started with GraphQL and React. This is an incredible roadmap for learning these concepts in a linear and digestible way.), + img: 'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/Eve-Porcello.png', + name: 'Eve Porcello', + twitterLink: 'https://twitter.com/eveporcello', + designation: (Instructor @egghead.io), + }, + { + description: (“This is a really great tutorial for people keen to learn more about GraphQL 🚀 I just went through the React one, but they have tutorials for Vue, iOS and RN too 💙 #2Hours2GraphQL.), + img: 'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/Sibylle.png', + name: 'Sibylle', + twitterLink: 'https://twitter.com/s_ibylle/status/1138143802831585280', + designation: (Typeface @brandung), + }, + { + description: (Check out this GraphQL #ReasonML course for Reason React developers by @HasuraHQ https://learn.hasura.io/graphql/reason-react-apollo... “Will this course teach ReasonReact concepts as well?” Hell yes. There are some programming patterns on display in this app that are different from what you see in generally.), + img: 'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/Imani.png', + name: 'Imani’s Father', + twitterLink: 'https://twitter.com/_idkjs/status/1151765251991453696', + designation: (Freelance software developer), + }, + ] + } + } render() { - const styles = require('./Styles.module.scss'); - const twitter = require('./images/twitter.svg'); - const LeftArrow = require('./images/Left-Arrow.png'); - const RightArrow = require('./images/Right-Arrow.png'); - const quoteLeft = require('./images/quote-left.svg'); - const quoteRight = require('./images/quote-right.svg'); + const listWrapper = this.state.testimonial.map((list, index) => { + return ( +
    +
    + {'Quote'} +
    +
    + {list.description} +
    +
    +
    + {list.name} +
    +
    + +
    + {list.designation} +
    +
    +
    +
    + ); + }); return ( /* Use global styles normally */ -
    -
    -
    -
    -
    - Some testimonials from our users -
    -
    -
    -
    - {'Quote -
    -
    - {'Quote -
    -
    -
    -
    -
    -
    -
    - -
    - This is one of the best tutorials I have seen for getting started with GraphQL and React. This is an incredible roadmap for learning these concepts in a linear and digestible way. If you are a React developer who is curious about Hasura and GraphQL, this is the place to start. -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - Damn, a free 2 hour course on GraphQL and @vuejs - https://learn.hasura.io/graphql/vue/introduction. I can't wait to go through this! (When I can escape meeting hell.) -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - Great introduction to #GraphQL and covers @HasuraHQ. If you’re new to either it’s a good read. -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - Use @hasurahq to get a production ready self hosted graphql api for a postgres db, see their video course -
    -
    -
    -
    -
    -
    - {'Twitter'} -
    - -
    - learn.hasura.io/graphql/react #GraphQL course for #react peeps is very well done by @HasuraHQ 👌🤘 -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - I've heard great things about Hasura and also this training material -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - I just completed this GraphQL course for React developers by @HasuraHQ. Check it out here - - https://learn.hasura.io/graphql/react

    That was awesome time spending.

    - #GraphQL #reactjs #react -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - This is a really great tutorial for people keen to learn more about GraphQL 🚀 I just went through the React one, but they have tutorials for Vue, iOS and RN too 💙 Thanks for the folk at Hasura for putting that together #2Hours2GraphQL -
    -
    -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - Great introduction to #GraphQL and covers @HasuraHQ. If you’re new to either it’s a good read. -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - Use @hasurahq to get a production ready self hosted graphql api for a postgres db, see their video course -
    -
    -
    -
    -
    -
    -
    -
    - {'Twitter'} -
    - -
    - learn.hasura.io/graphql/react #GraphQL course for #react peeps is very well done by @HasuraHQ 👌🤘 -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - I've heard great things about Hasura and also this training material -
    -
    -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - I just completed this GraphQL course for React developers by @HasuraHQ. Check it out here - - https://learn.hasura.io/graphql/react

    That was awesome time spending.

    - #GraphQL #reactjs #react -
    -
    -
    -
    -
    -
    - {'twitter'} -
    - -
    - This is a really great tutorial for people keen to learn more about GraphQL 🚀 I just went through the React one, but they have tutorials for Vue, iOS and RN too 💙 Thanks for the folk at Hasura for putting that together #2Hours2GraphQL -
    -
    -
    -
    -
    - - {/* - - */} - Previous - {'Left - - - {/* - - Next - */} - {'Right - -
    -
    +
    +
    +
    +
    + Testimonials +
    +
    +
    +
    + {listWrapper}
    diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/components/TopBanner.js b/community/learn/graphql-tutorials/backend-services/homepage/src/components/TopBanner.js index 98059b3c50a..ba7e77873cf 100755 --- a/community/learn/graphql-tutorials/backend-services/homepage/src/components/TopBanner.js +++ b/community/learn/graphql-tutorials/backend-services/homepage/src/components/TopBanner.js @@ -15,7 +15,7 @@ class TopBanner extends React.Component {
    - With these open-source tutorials, you will move from the basics of GraphQL to building a real-time application in 2 hours + With these open-source community maintained tutorials, you will move from the basics of GraphQL to building a real-time application in 2 hours
    diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/components/WillLearn.js b/community/learn/graphql-tutorials/backend-services/homepage/src/components/WillLearn.js index 9a73c4a0c30..ac188a3cce4 100644 --- a/community/learn/graphql-tutorials/backend-services/homepage/src/components/WillLearn.js +++ b/community/learn/graphql-tutorials/backend-services/homepage/src/components/WillLearn.js @@ -33,7 +33,7 @@ class WillLearn extends React.Component { ) }) return ( -
    +
    diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/components/images/Left-Arrow.png b/community/learn/graphql-tutorials/backend-services/homepage/src/components/images/Left-Arrow.png deleted file mode 100644 index ae52beb41498e565bd29b77bb81c4d478e3319db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2098 zcmXw33sjQn79}64z3_3HGz-%*r__9nV_6O(>Zo_d2LcLO=?{qJ+v}^WfgiNU#x!%X zOv`IIrk0v5HD}V83k{i0Syyy2Ei-&uHlU>x!u>w<{_FeUeCO=5_daK_$O{hiUB71Y z8Vm-r-rvtV1bjz)({aKT`-8iRiz`+zHoqERRsLPtXoc!&sx$UrHn1t2DY z49GK37Hg$SsjDMul8K4u52gP^)O1l$loAITAsA-p0AEU{=fNw2MkKBzAvqnTuud;` zMWtxu=xF#6K2*_A0cr417@8{`Jsf{(nU)3&XxJ!-CWD}AwVD{a0;4fcE|WuMU_K5q zlR(Tmx$K9kF$Sn8vAM7W_?at)sd2fG85)CZu#1rkMG=&$;fEOn4P)gjJNdsiE-5Al zQX$;1Xw85OE`^>0sTf?6W?dvYm!cUtgw7>J^8lELaKV631%O#RkSEf4K$-}UfCK^{ zA&CJ>zy_DXgjK);JZRLpA%F+QToR(e0GMVF03$EkfDE9Q2loJ~&=1@RREJ<-i3c2N zq#-krxx7Ot0mosWWK95K=rfv2MnDGmgnmd&l+5IkK|4q?;jYNgAs3c_Tc834XFw8w zTwWJ+&OpPMInWO?2VB9S(0Q;OPP*a^B;m;L0B^7bDz0pAB>;p~Nq7GMKiRSLkU$bf zNB?e4o0@Cz8~fggH61P5f@Zz7zu#HCPS_-B)Ls9eeuMbt!#eDv8pEz?qwcE5*R_nF zRGRcu{Nve`jsGoM^+j*#CdtMA64SqaHhX@4^T0Xt7X@2}^0&S`gL`$_V))dy*H$Cj z-=I6BKU$9--#K>7W<2Z5iHzNoX|_|TcGJoBi4HUIj&D^*oZiK_%tn9pp5eNLxcwcq zS9aK4t~|Iu{JC)4RB=hI@KM{&2|8xfQK}w?rD1%h`tuESg+kkN$#N1qQ|QR~sv4iP&Deiw z*LYCOd`v0+;$M+bD!M1i7i;rGv%cCsT`$+`R<&Aa+ys#{?Q_-R~}=^ z2~`apkUH3PMbedH8z&kYoK(LpxS4X&x)l+F`2y)ufOwdiq3Uv%HXh@Y%CaWP1#Q1C z&b=CDD9seTqT=`5}jGtHOOR)>?oXOKNz0rkv7gf{3Ju`LHfa1#5e9mq`{RLUX zs9U)coAIkMTijS286jHiliz$|CLpkByQGnw4twaz?h1LMsXCl}c#m|rv*!t28KE$n z%IDbNKU|d+kJ(r|vw6zJy<+vd&l5SG$LDqDFK6qYt+KE>q1*9q+_gT>?ur_I+YXNd zWli?Y?FHFwJ+I@=WyiPT!fW_;8@tCz)0TIsSR09mQi}Uj!@uU-u(q~6v?;ptZF?w| zFYyY{rt&3`1K%(+`>XlKrYl>D>&*zLh4l5X$abE4Ob+pb5QjGERx`-)z8xxEtMD&OegQ;IuaUp z+F7RG{a!eFfZ$tf{pYskSfLIf?TWRx;dHlkWt>iBxXEgx-Dh@K-oskf8F=Xbv9IK5 z-nnFh#CrW-2TBZk&ojvkZGY#WnvsE=(3T6)v?R(e$y(O4K3h_*(+0smDaPL?(7S;U G#rq%Iisu3V diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/components/images/Right-Arrow.png b/community/learn/graphql-tutorials/backend-services/homepage/src/components/images/Right-Arrow.png deleted file mode 100644 index cca9e94c47005ffeb16c868652d7c4a93606a9ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2070 zcmXw32UwF=8x0DSFhn9)NNt5mgn+4G6@O_25o%XceTbD6)zc5wM^j{#2$U`S1P0|2!G@zVCU@d(QdtB$wf{$3Pdai@{(F zyuEg_z;`%!-_ltNK7%I*9WafOxdUm$K35*f1#A;zGeFI6}fkG0-Mo%#D;VQ2>)K0c=nt@D%}8Lmsw30(juK zPy%_tE~pu{SP`HC)v|ejVbus5&6WelQBwj5x<$kVNFn5b!Ge}R%;l{zqh25(Q@EOp z+9^cxL>#_|1C~aJ)do3yFOa=W6E+7YZ4=*Yizmgt-5#x+B1cWzMZ9wm%sBECPT}vJL;t%Y zcxC7QS(ku+zw!V0VHekxJ?G9`rZVPt`z$SZe!FMyqBq@_=Em`(1ciisZ6EVhTtdYdbi+@{1aq&YyVaG$E)Me_t(m0YLYe*N?}p-;~*lNSSN z=Ep3IBMpr7pO{7;vm#qY({yP&Y52-*IlDc>|duwAn~#S{NpPru6~Hb5{C7ude8U3nj0VCqxje#S2NM$Jghh%(&3 zSHISfG@oLwy$esxKpWY-6g7vAv?A2v=4{ zxW%AeLz>d)6DPX|J+Ln*xO8HLFI9yh=+jN{mysgomb`qn95LBS0MHV zXkkz6mEF9H19?_OolA0fAMBlkGOP{OJXw*J(uFW8DTB z*@476j+=j&M^1Ocj{5DWL@ruv`Jm5|yR{;_=o5`{J3>k-zG4Z%{WWBHh9wV_B3tPP zWDGxFY-%Ge#(Lxqok}2ZWP7bIAvoJ$hCHIqXjcf6nsp9|rFV3mN}^#)&2S0Ck*~ON z3ZatVefT_r9L5&P-dmb4I`p(QHP4k!@1Z&`$j|vrjNg+@Haw{JClbY(^z@nm=A#yA zR`K#+cN?YmZKqT@oxA*7_uXl~)|Fy~*EnIyqgrxrx?;KUpDFj4D*}~KYFt!rqKjad zX_XTDQ}4_Szm@5l664&v86RH$WWXpTFE0Cx!lS3VBBWknHg7_rewXH{=p{^S*w+x% z7kYs-(e*`soqw8}VNAqP1?^dp;)3$I|Aawmz4Lrcer6r%O<|Vw24n3<-s9N0Pb>6- zLVnvdfE!Y+dvX5IS&xaXTFE2L~_ICY9sd<<1Mx_k8O)=eLj0s;~ z5bsiIx?w14=*`OCff1Wj8`Ja_cLqEt92 - - - - - - - - - - - - - - - - - - diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/components/images/quote-right.svg b/community/learn/graphql-tutorials/backend-services/homepage/src/components/images/quote-right.svg deleted file mode 100644 index 55c8a5c8209..00000000000 --- a/community/learn/graphql-tutorials/backend-services/homepage/src/components/images/quote-right.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/components/images/twitter.svg b/community/learn/graphql-tutorials/backend-services/homepage/src/components/images/twitter.svg deleted file mode 100644 index 7ccd91019ff..00000000000 --- a/community/learn/graphql-tutorials/backend-services/homepage/src/components/images/twitter.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/pages/index.js b/community/learn/graphql-tutorials/backend-services/homepage/src/pages/index.js index 3751f07c282..6aa01b3e6aa 100644 --- a/community/learn/graphql-tutorials/backend-services/homepage/src/pages/index.js +++ b/community/learn/graphql-tutorials/backend-services/homepage/src/pages/index.js @@ -2,6 +2,7 @@ import React from 'react'; import '../styles/styles.scss'; import Header from '../components/Header'; import TopBanner from '../components/TopBanner'; +import Featured from '../components/Featured'; import Tutorials from '../components/Tutorials'; import WillLearn from '../components/WillLearn'; import SubscribeNewsletter from '../components/SubscribeNewsletter'; @@ -14,6 +15,7 @@ class Index extends React.Component {
    + diff --git a/community/learn/graphql-tutorials/backend-services/homepage/src/styles/styles.scss b/community/learn/graphql-tutorials/backend-services/homepage/src/styles/styles.scss index 5bae3d82612..d685481bbcf 100644 --- a/community/learn/graphql-tutorials/backend-services/homepage/src/styles/styles.scss +++ b/community/learn/graphql-tutorials/backend-services/homepage/src/styles/styles.scss @@ -15,6 +15,11 @@ body width: 100%; float: left; } +.wd80 +{ + width: 80%; + margin: 0 auto; +} .noPadd { padding-left: 0 !important; @@ -490,82 +495,82 @@ ul } .reactBg { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/react-purple.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/react-original.svg'); &:hover { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/react-original.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/react-purple.svg'); } } .vueBg { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/vue-purple.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/vue-original.svg'); &:hover { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/vue-original.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/vue-purple.svg'); } } .angularBg { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/angular-purple.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/angular-original.svg'); &:hover { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/angular-original.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/angular-purple.svg'); } } .elmBg { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/elm-purple.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/elm-original.jpg'); &:hover { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/elm-original.jpg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/elm-purple.svg'); } } .reBg { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/reasonml-purple.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/reasonml-original.svg'); &:hover { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/reasonml-original.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/reasonml-purple.svg'); } } .hasuraBg { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/hasura-purple.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/hasura-original.svg'); &:hover { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/hasura-original.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/hasura-purple.svg'); } } .postgresBg { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/postgres-purple.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/postgres-original.svg'); &:hover { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/postgres-original.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/postgres-purple.svg'); } } .iosBg { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/ios-purple.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/ios-original.png'); &:hover { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/ios-original.png'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/ios-purple.svg'); } } .androidBg { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/android-purple.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/android-original.svg'); &:hover { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/android-original.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/android-purple.svg'); } } .flutterBg { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/flutter-purple.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/flutter-original.svg'); &:hover { - background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/flutter-original.svg'); + background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/flutter-purple.svg'); } } .reactDisableBg @@ -999,6 +1004,112 @@ ul clear: both; font-size: 12px; } +.testimoialsWrapper +{ + .sectionHeader + { + text-align: center; + padding-bottom: 20px; + } + .purpleLineSeperator + { + margin: 0 auto; + } + .testimonialListWrapper + { + .testimonialList + { + padding: 40px 0; + border-bottom: 1px solid #cbcbcb; + .testimonialContent + { + font-family: 'Raleway'; + font-size: 28px; + font-weight: bold; + color: #606060; + line-height: 1.36; + padding: 24px 0; + } + .authorWrapper + { + display: flex; + align-items: center; + .authorImg + { + img + { + width: 90px; + height: 90px; + border-radius: 50%; + } + } + .author + { + padding-left: 24px; + .name + { + font-family: 'Roboto'; + font-size: 18px; + font-weight: bold; + line-height: 1.33; + color: #1f88e5; + padding-bottom: 4px; + a + { + color: #1f88e5; + } + a:hover + { + text-decoration: none; + } + } + .designation + { + font-family: 'Roboto'; + font-size: 16px; + font-weight: normal; + color: #303030; + line-height: 1.31; + a + { + color: #1f88e5; + } + a:hover + { + text-decoration: none; + } + } + } + } + } + } +} +.featuredWrapper +{ + .sectionHeader + { + text-align: center; + padding-bottom: 20px; + } + .purpleLineSeperator + { + margin: 0 auto; + } + .featuredIconWrapper + { + text-align: center; + padding-top: 60px; + .featuredIcon + { + display: inline-block; + padding: 0 35px; + img + { + max-height: 90px; + } + } + } +} @media (max-width: 767px) { .commonSectionWrapper @@ -1245,6 +1356,76 @@ ul { padding-top: 30px; } + .wd80 + { + width: 100%; + } + .testimoialsWrapper + { + padding: 0 15px; + .testimonialListWrapper + { + .testimonialList + { + .quotes + { + img + { + width: 30px; + } + } + .testimonialContent + { + font-size: 16px; + padding: 15px 0; + line-height: 1.6; + a + { + word-break: break-all; + } + } + .authorWrapper + { + .authorImg + { + img + { + width: 75px; + height: 75px; + } + } + .author + { + padding-left: 15px; + .name + { + font-size: 16px; + } + .designation + { + font-size: 14px; + } + } + } + } + } + } + .featuredWrapper + { + .featuredIconWrapper + { + padding-top: 40px; + .featuredIcon + { + padding: 0 10px; + img + { + max-height: 50px; + max-width: 75px; + } + } + } + } } @media (min-width: 768px) and (max-width: 991px) { @@ -1348,4 +1529,17 @@ ul { padding-top: 30px; } + .testimoialsWrapper + { + .testimonialListWrapper + { + .testimonialList + { + .testimonialContent + { + font-size: 20px; + } + } + } + } } diff --git a/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/Dockerfile b/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/Dockerfile index 712c12e2a7b..fc87f035866 100644 --- a/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/Dockerfile +++ b/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/Dockerfile @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/Dockerfile.localdev b/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/Dockerfile.localdev index 93b2803c4e1..553c99654cf 100644 --- a/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/Dockerfile.localdev +++ b/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/Dockerfile.localdev @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/config.js b/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/config.js index aee8f43654a..5dc204979a4 100644 --- a/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/config.js +++ b/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/config.js @@ -5,8 +5,9 @@ const config = { "gaTrackingId": "UA-59768903-1" }, "header": { - "logo": "https://graphql-engine-cdn.hasura.io/img/hasura_icon_white.svg", - "title": "/ graphql / android", + "logo": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/logo.png", + "logoLink": "https://learn.hasura.io", + "title": "/ graphql / android", "githubUrl": "https://github.com/hasura/graphql-engine", "helpUrl": "https://discordapp.com/invite/vBPpJkS", "tweetText": "Check out this GraphQL course for Android Developers by @HasuraHQ https://learn.hasura.io/graphql/android", @@ -37,7 +38,9 @@ const config = { "text": "GraphQL Docs", "link": "https://graphql.org/learn" } - ] + ], + "frontline": false, + "ignoreIndex": true }, "siteMetadata": { "title": "2 hour GraphQL course for Android Developers | Hasura", diff --git a/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/content/apollo-client.md b/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/content/apollo-client.md index 925f030b0d3..dd5fe718d49 100644 --- a/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/content/apollo-client.md +++ b/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/content/apollo-client.md @@ -8,7 +8,7 @@ import GithubLink from '../src/GithubLink.js' Apollo gives a neat abstraction layer and an interface to your GraphQL server. You don't need to worry about constructing your queries with request body, headers and options, that you might have done with `OkHttp` or `Retrofit` say. You can directly write queries and mutations in GraphQL and they will automatically be sent to your server via your apollo client instance. -### Android Apollo Installation +## Android Apollo Installation Let's get started by adding apollo client & peer graphql dependenices to the project: - The latest gradle plugin version is [ ![Download](https://api.bintray.com/packages/apollographql/android/apollo-gradle-plugin/images/download.svg) ](https://bintray.com/apollographql/android/apollo-gradle-plugin/_latestVersion). We will use the latest snapshot. @@ -44,7 +44,7 @@ dependencies { apply plugin: 'com.apollographql.android' ``` -\*\*Note: The Android Plugin must be applied before the Apollo plugin +**Note:** The Android Plugin must be applied before the Apollo plugin ### Adding code generation @@ -59,7 +59,7 @@ dependencies { - Now create a `graphql`inside the `main`directory and create new directory structure like `graphql/com/hasura/todo`so that the **Apollo plugin can generate java classes with valid package**. -### Create `.graphql` files with your queries or mutations +### Create .graphql files with your queries or mutations Apollo generates code from queries and mutations contained in `.graphql` files in your target. @@ -94,7 +94,7 @@ implementation 'javax.annotation:jsr250-api:1.0' - Compile your project to have Apollo generate the appropriate Java classes with nested classes for reading from the network response. In the sample project, a `GetAllTodosQuery` Java class is created here `app/build/generated/source/apollo/classes/com.hasura.todo/` -\*\*Note: This is an autogenerated file by Apollo and should not be changed manually +**Note:** This is an autogenerated file by Apollo and should not be changed manually - Before we start making requests, we need to add couple of more dependencies in app's build.gradle. OkHttp for networking interface diff --git a/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/content/introduction.md b/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/content/introduction.md index 5b7bacac529..75d707a4ed7 100644 --- a/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/content/introduction.md +++ b/community/learn/graphql-tutorials/tutorials/android-apollo/tutorial-site/content/introduction.md @@ -1,5 +1,5 @@ --- -title: "Course introduction" +title: "Course Introduction" metaTitle: "Course Introduction | GraphQL Android Apollo Tutorial" metaDescription: "A powerful and concise tutorial that will introduce you to GraphQL and integrating GraphQL into your Android app with Apollo and Kotlin, in the shortest amount of time possible." --- @@ -9,7 +9,6 @@ This course is a concise and powerful introduction to GraphQL for android develo We’ve structured this course to cover fundamental concepts of both GraphQL and using GraphQL in Android, in the shortest amount of time possible. The course is light on opinions so that once you grok the fundamentals you can go on to choose your favourite tools and tailor your workflow. ## Key topics and takeways: - - GraphQL vs REST - GraphQL queries, mutations, subscriptions - Setting up a GraphQL client with Apollo @@ -21,24 +20,26 @@ We’ve structured this course to cover fundamental concepts of both GraphQL and - Building a real-time feed with notifications using mutations and subscriptions ## What will be building? - We will be building a realtime todo app using authenticated GraphQL APIs. Try this deployed version of the frontend app to see what we'll be building: https://learn-hasura-todo-app.netlify.com/ This is built on React but the functionality will be the same for android. -## Will this course teach android concepts as well? - +## Will this course teach Android concepts as well? No, we will be simulating a scenario where we already have a GraphQL API and the basic UI of a android app built. Our task in this scenario is to integrate the GraphQL APIs into our android app to build a complete and working app. ## What do I need to take this tutorial? - You need to have npm/yarn & node 8+ running. ## How long will this tutorial take? - Less than 2 hours + +## Other courses + +**Frontend**: GraphQL for: [Vue](https://learn.hasura.io/graphql/vue), [React Native](https://learn.hasura.io/graphql/react-native), [iOS](https://learn.hasura.io/graphql/ios) + +**Backend**: [Building a realtime GraphQL backend with Hasura](https://learn.hasura.io/graphql/hasura) in 30 mins (ideal for frontend, backend or fullstack developers) diff --git a/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/Dockerfile b/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/Dockerfile index 712c12e2a7b..fc87f035866 100644 --- a/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/Dockerfile +++ b/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/Dockerfile @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/Dockerfile.localdev b/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/Dockerfile.localdev index 93b2803c4e1..553c99654cf 100644 --- a/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/Dockerfile.localdev +++ b/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/Dockerfile.localdev @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/config.js b/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/config.js index 763d928b5f5..9fc4bead9dc 100644 --- a/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/config.js +++ b/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/config.js @@ -5,8 +5,9 @@ const config = { "gaTrackingId": "UA-59768903-1" }, "header": { - "logo": "https://graphql-engine-cdn.hasura.io/img/hasura_icon_white.svg", - "title": "/ graphql / elm-graphql", + "logo": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/logo.png", + "logoLink": "https://learn.hasura.io", + "title": "/ graphql / elm-graphql", "githubUrl": "https://github.com/hasura/graphql-engine", "helpUrl": "https://discordapp.com/invite/vBPpJkS", "tweetText": "Check out this GraphQL course for Elm developers by @HasuraHQ https://learn.hasura.io/graphql/elm-graphql", @@ -17,17 +18,17 @@ const config = { }, "sidebar": { "forcedNavOrder": [ - "/introduction", + "/introduction", "/intro-to-graphql", "/setup", "/elm-graphql", "/queries", "/mutations-variables", - "/apollo-client", + "/apollo-client", "/subscriptions", "/realtime-feed", "/what-next" - ], + ], "links": [ { "text": "Hasura Docs", @@ -37,14 +38,16 @@ const config = { "text": "GraphQL Docs", "link": "https://graphql.org/learn" } - ] + ], + "frontline": false, + "ignoreIndex": true }, "siteMetadata": { "title": "2 hour GraphQL course for Elm developers | Hasura", "description": "A concise and powerful tutorial that covers fundamental concepts of both GraphQL and using GraphQL in Elm", "ogImage": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/social-media/twitter-card-elm.jpg", "docsLocation": "https://github.com/hasura/graphql-engine/tree/master/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/content", - "favicon": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-elm/favicon.ico" + "favicon": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-elm/favicon.ico" }, }; diff --git a/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/content/introduction.md b/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/content/introduction.md index 6a18b65cbaa..3c844b863a4 100644 --- a/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/content/introduction.md +++ b/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/content/introduction.md @@ -40,7 +40,7 @@ You need to have elm 0.19.0, npm/yarn & node 8+ running. ## How long will this tutorial take? Less than 2 hours -## Other courses: +## Other courses **Frontend**: GraphQL for: [React](https://learn.hasura.io/graphql/react), [Vue](https://learn.hasura.io/graphql/vue), [React Native](https://learn.hasura.io/graphql/react-native), [iOS](https://learn.hasura.io/graphql/ios) diff --git a/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/content/realtime-feed/2-sync-todo.md b/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/content/realtime-feed/2-sync-todo.md index b4d5e0da557..a97ca89c5da 100644 --- a/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/content/realtime-feed/2-sync-todo.md +++ b/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/content/realtime-feed/2-sync-todo.md @@ -234,7 +234,7 @@ Lets add it to our update function to update the models appropriately ``` -### Update `loadLatestPublicTodo` and `loadOldPublicTodos` +### Update loadLatestPublicTodo and loadOldPublicTodos Lets update our render functions to invoke relevant actions on click diff --git a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/Dockerfile b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/Dockerfile index 712c12e2a7b..fc87f035866 100644 --- a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/Dockerfile +++ b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/Dockerfile @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/Dockerfile.localdev b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/Dockerfile.localdev index 93b2803c4e1..553c99654cf 100644 --- a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/Dockerfile.localdev +++ b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/Dockerfile.localdev @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/config.js b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/config.js index 4494777c243..3386674cdf2 100644 --- a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/config.js +++ b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/config.js @@ -5,8 +5,9 @@ const config = { "gaTrackingId": "UA-59768903-1" }, "header": { - "logo": "https://graphql-engine-cdn.hasura.io/img/hasura_icon_white.svg", - "title": "/ graphql / ios", + "logo": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/logo.png", + "logoLink": "https://learn.hasura.io", + "title": "/ graphql / ios", "githubUrl": "https://github.com/hasura/graphql-engine", "helpUrl": "https://discordapp.com/invite/vBPpJkS", "tweetText": "Check out this GraphQL course for iOS developers by @HasuraHQ https://learn.hasura.io/graphql/ios", @@ -27,7 +28,7 @@ const config = { "/subscriptions", "/realtime-feed", "/what-next" - ], + ], "links": [ { "text": "Hasura Docs", @@ -37,7 +38,9 @@ const config = { "text": "GraphQL Docs", "link": "https://graphql.org/learn" } - ] + ], + "frontline": false, + "ignoreIndex": true }, "siteMetadata": { "title": "2 hour GraphQL course for iOS developers | Hasura", diff --git a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/apollo-client.md b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/apollo-client.md index 6d6f55e7ff9..8f36b33eea3 100644 --- a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/apollo-client.md +++ b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/apollo-client.md @@ -88,7 +88,7 @@ At this point, you can try building your target in Xcode. This will verify that You may receive a warning when you first start up Xcode after installing these add-ons. -### Create `.graphql` files with your queries or mutations +### Create .graphql files with your queries or mutations Apollo iOS generates code from queries and mutations contained in `.graphql` files in your target. @@ -96,7 +96,7 @@ A useful convention is to colocate queries, mutations or fragments with the Swif If you have the Xcode add-ons installed, you can use the Xcode companion view to show a `.swift` file and the corresponding `.graphql` file side by side. -### Create apollo client with +### Create apollo client Open LoginVC.swift and add below diff --git a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/introduction.md b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/introduction.md index 79a57cc1e5d..6f6fb55cfac 100644 --- a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/introduction.md +++ b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/introduction.md @@ -41,7 +41,7 @@ You need to have npm/yarn & node 8+ running. ## How long will this tutorial take? Less than 2 hours -## Other courses: +## Other courses **Frontend**: GraphQL for: [Vue](https://learn.hasura.io/graphql/vue), [React Native](https://learn.hasura.io/graphql/react-native), [React](https://learn.hasura.io/graphql/react) diff --git a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/queries/2-create-query.md b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/queries/2-create-query.md index e60be8c349a..ca0da0f842d 100644 --- a/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/queries/2-create-query.md +++ b/community/learn/graphql-tutorials/tutorials/ios-apollo/tutorial-site/content/queries/2-create-query.md @@ -8,7 +8,7 @@ import GithubLink from '../../src/GithubLink.js' In this section, we will implement GraphQL Queries and integrate with the ios app UI. -### Create `.graphql` files with your queries or mutations +### Create .graphql files with your queries or mutations Apollo iOS generates code from queries and mutations contained in `.graphql` files in your target. diff --git a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/Dockerfile b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/Dockerfile index 712c12e2a7b..fc87f035866 100644 --- a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/Dockerfile +++ b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/Dockerfile @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/Dockerfile.localdev b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/Dockerfile.localdev index 93b2803c4e1..4c32a68e402 100644 --- a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/Dockerfile.localdev +++ b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/Dockerfile.localdev @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 21:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/config.js b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/config.js index 1bbc6fe182f..d38dbccaf0f 100644 --- a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/config.js +++ b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/config.js @@ -5,8 +5,9 @@ const config = { "gaTrackingId": "UA-59768903-1" }, "header": { - "logo": "https://graphql-engine-cdn.hasura.io/img/hasura_icon_white.svg", - "title": "/ graphql / react", + "logo": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/logo.png", + "logoLink": "https://learn.hasura.io", + "title": "/ graphql / react", "githubUrl": "https://github.com/hasura/graphql-engine", "helpUrl": "https://discordapp.com/invite/vBPpJkS", "tweetText": "Check out this GraphQL course for React developers by @HasuraHQ https://learn.hasura.io/graphql/react", @@ -27,7 +28,7 @@ const config = { "/subscriptions", "/realtime-feed", "/what-next" - ], + ], "links": [ { "text": "Hasura Docs", @@ -37,7 +38,9 @@ const config = { "text": "GraphQL Docs", "link": "https://graphql.org/learn" } - ] + ], + "frontline": false, + "ignoreIndex": true }, "siteMetadata": { "title": "2 hour GraphQL course for React developers | Hasura", diff --git a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/introduction.md b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/introduction.md index d0f7f4b1a4a..c23061b0f8c 100644 --- a/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/introduction.md +++ b/community/learn/graphql-tutorials/tutorials/react-apollo/tutorial-site/content/introduction.md @@ -41,7 +41,7 @@ You need to have npm/yarn & node 8+ running. ## How long will this tutorial take? Less than 2 hours -## Other courses: +## Other courses **Frontend**: GraphQL for: [Vue](https://learn.hasura.io/graphql/vue), [React Native](https://learn.hasura.io/graphql/react-native), [iOS](https://learn.hasura.io/graphql/ios) diff --git a/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/Dockerfile b/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/Dockerfile index 712c12e2a7b..fc87f035866 100644 --- a/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/Dockerfile +++ b/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/Dockerfile @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/Dockerfile.localdev b/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/Dockerfile.localdev index 93b2803c4e1..553c99654cf 100644 --- a/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/Dockerfile.localdev +++ b/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/Dockerfile.localdev @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/config.js b/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/config.js index 8d7bd2a7e6d..98d06d702e8 100644 --- a/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/config.js +++ b/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/config.js @@ -5,8 +5,9 @@ const config = { "gaTrackingId": "UA-59768903-1" }, "header": { - "logo": "https://graphql-engine-cdn.hasura.io/img/hasura_icon_white.svg", - "title": "/ graphql / react-native", + "logo": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/logo.png", + "logoLink": "https://learn.hasura.io", + "title": "/ graphql / react-native", "githubUrl": "https://github.com/hasura/graphql-engine", "helpUrl": "https://discordapp.com/invite/vBPpJkS", "tweetText": "Check out this GraphQL course for React Native developers by @HasuraHQ https://learn.hasura.io/graphql/react-native", @@ -39,7 +40,9 @@ const config = { "text": "GraphQL Docs", "link": "https://graphql.org/learn" } - ] + ], + "frontline": false, + "ignoreIndex": true }, "siteMetadata": { "title": "2 hour GraphQL course for React Native developers | Hasura", diff --git a/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/content/introduction.md b/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/content/introduction.md index 143f7e44373..208187ed425 100644 --- a/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/content/introduction.md +++ b/community/learn/graphql-tutorials/tutorials/react-native-apollo/tutorial-site/content/introduction.md @@ -40,7 +40,7 @@ You need to have npm/yarn & node 8+ running. ## How long will this tutorial take? Less than 2 hours -## Other courses: +## Other courses **Frontend**: GraphQL for: [Vue](https://learn.hasura.io/graphql/vue), [React](https://learn.hasura.io/graphql/react), [iOS](https://learn.hasura.io/graphql/ios) diff --git a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/Dockerfile b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/Dockerfile index 712c12e2a7b..fc87f035866 100644 --- a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/Dockerfile +++ b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/Dockerfile @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/Dockerfile.localdev b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/Dockerfile.localdev index 93b2803c4e1..553c99654cf 100644 --- a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/Dockerfile.localdev +++ b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/Dockerfile.localdev @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/config.js b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/config.js index 3680eda0102..45396aa7557 100644 --- a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/config.js +++ b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/config.js @@ -5,8 +5,9 @@ const config = { "gaTrackingId": "UA-59768903-1" }, "header": { - "logo": "https://graphql-engine-cdn.hasura.io/img/hasura_icon_white.svg", - "title": "/ graphql / reason-react-apollo", + "logo": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/logo.png", + "logoLink": "https://learn.hasura.io", + "title": "/ graphql / reason-react-apollo", "githubUrl": "https://github.com/hasura/graphql-engine", "helpUrl": "https://discordapp.com/invite/vBPpJkS", "tweetText": "Check out this GraphQL course for Reason React developers by @HasuraHQ https://learn.hasura.io/graphql/reason-react-apollo", @@ -37,7 +38,9 @@ const config = { "text": "GraphQL Docs", "link": "https://graphql.org/learn" } - ] + ], + "frontline": false, + "ignoreIndex": true }, "siteMetadata": { "title": "2 hour GraphQL course for React developers | Hasura", diff --git a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/introduction.md b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/introduction.md index 9ec72c9a7d0..20f0ccdc295 100644 --- a/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/introduction.md +++ b/community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site/content/introduction.md @@ -39,7 +39,7 @@ You need to have npm/yarn & node 8+ running. ## How long will this tutorial take? Less than 2 hours -## Other courses: +## Other courses **Frontend**: GraphQL for: [React](https://learn.hasura.io/graphql/react), [Vue](https://learn.hasura.io/graphql/vue), [React Native](https://learn.hasura.io/graphql/react-native), [iOS](https://learn.hasura.io/graphql/ios) diff --git a/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/Dockerfile b/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/Dockerfile index 712c12e2a7b..fc87f035866 100644 --- a/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/Dockerfile +++ b/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/Dockerfile @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/Dockerfile.localdev b/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/Dockerfile.localdev index 93b2803c4e1..553c99654cf 100644 --- a/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/Dockerfile.localdev +++ b/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/Dockerfile.localdev @@ -1,7 +1,7 @@ FROM node:carbon # update this line when gatsby-gitbook-starter repo changes -RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"' +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' # Install global dependencies RUN npm -g install gatsby-cli diff --git a/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/config.js b/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/config.js index 51d45625a5a..4f596f84f2a 100644 --- a/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/config.js +++ b/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/config.js @@ -5,8 +5,9 @@ const config = { "gaTrackingId": "UA-59768903-1" }, "header": { - "logo": "https://graphql-engine-cdn.hasura.io/img/hasura_icon_white.svg", - "title": "/ graphql / vue", + "logo": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/logo.png", + "logoLink": "https://learn.hasura.io", + "title": "/ graphql / vue", "githubUrl": "https://github.com/hasura/graphql-engine", "helpUrl": "https://discordapp.com/invite/vBPpJkS", "tweetText": "Check out this GraphQL course for Vue developers by @HasuraHQ https://learn.hasura.io/graphql/vue", @@ -27,7 +28,7 @@ const config = { "/subscriptions", "/realtime-feed", "/what-next" - ], + ], "links": [ { "text": "Hasura Docs", @@ -37,7 +38,9 @@ const config = { "text": "GraphQL Docs", "link": "https://graphql.org/learn" } - ] + ], + "frontline": false, + "ignoreIndex": true }, "siteMetadata": { "title": "2 hour GraphQL course for Vue developers | Hasura", diff --git a/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/content/introduction.md b/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/content/introduction.md index f12ec1668f0..40fafa2bf19 100644 --- a/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/content/introduction.md +++ b/community/learn/graphql-tutorials/tutorials/vue-apollo/tutorial-site/content/introduction.md @@ -41,7 +41,7 @@ You need to have npm/yarn & node 8+ running. ## How long will this tutorial take? Less than 2 hours -## Other courses: +## Other courses **Frontend**: GraphQL for: [React](https://learn.hasura.io/graphql/react), [React Native](https://learn.hasura.io/graphql/react-native), [iOS](https://learn.hasura.io/graphql/ios) From c1d4f76c1f5c257dd1b1a108ed7efd552bbd8de6 Mon Sep 17 00:00:00 2001 From: Rikin Kachhia Date: Fri, 2 Aug 2019 14:01:30 +0530 Subject: [PATCH 23/27] allow adding frequently used columns from table modify page (close #2545) (#2593) --- .../Services/Data/Add/AddActions.js | 2 +- .../components/Services/Data/Add/AddTable.js | 84 +++---- .../Services/Data/Add/AddWarning.js | 20 +- .../src/components/Services/Data/Add/utils.js | 66 ----- .../FrequentlyUsedColumnSelector.js | 122 ++++++++++ .../Data/TableModify/ColumnCreator.js | 228 +++++++++++------- .../Data/TableModify/ModifyActions.js | 71 ++++-- 7 files changed, 355 insertions(+), 238 deletions(-) create mode 100644 console/src/components/Services/Data/Common/ReusableComponents/FrequentlyUsedColumnSelector.js diff --git a/console/src/components/Services/Data/Add/AddActions.js b/console/src/components/Services/Data/Add/AddActions.js index d86f6b4bc0d..2b1405dd4bf 100644 --- a/console/src/components/Services/Data/Add/AddActions.js +++ b/console/src/components/Services/Data/Add/AddActions.js @@ -301,7 +301,7 @@ const createTableSql = () => { if (columnSpecificSql.length) { columnSpecificSql.forEach(csql => { - sqlCreateTable += csql; + sqlCreateTable += csql.upSql; }); } diff --git a/console/src/components/Services/Data/Add/AddTable.js b/console/src/components/Services/Data/Add/AddTable.js index b080e4ee14d..ed4406e8a2c 100644 --- a/console/src/components/Services/Data/Add/AddTable.js +++ b/console/src/components/Services/Data/Add/AddTable.js @@ -6,6 +6,7 @@ import Button from '../../../Common/Button/Button'; import PrimaryKeySelector from '../Common/ReusableComponents/PrimaryKeySelector'; import ForeignKeyWrapper from './ForeignKeyWrapper'; import UniqueKeyWrapper from './UniqueKeyWrapper'; +import FrequentlyUsedColumnSelector from '../Common/ReusableComponents/FrequentlyUsedColumnSelector'; import { showErrorNotification } from '../../Common/Notification'; @@ -40,16 +41,15 @@ import gqlPattern, { import { tableNameNullNotif, - tableEnufColumns, - tableColumnNoDups, - tableColumnTypes, - tableColumnDefaults, - tableMinPrimaryKey, + tableEnufColumnsNotif, + tableColumnNoDupsNotif, + tableColumnTypesNotif, + tableColumnDefaultsNotif, + tableMinPrimaryKeyNotif, } from './AddWarning'; import styles from '../../../Common/TableCommon/Table.scss'; -import { frequentlyUsedColumns, getFreqUsedColDisplayInfo } from './utils'; -import Dropdown from '../../../Common/Dropdown/Dropdown'; + /* AddTable is a wrapper which wraps * 1) Table Name input * 2) Columns inputs @@ -74,7 +74,7 @@ class AddTable extends Component { this.setColDefaultValue = this.setColDefaultValue.bind(this); this.trimEmptyColumns = this.trimEmptyColumns.bind(this); - this.checkAndDispatch = this.checkAndDispatch.bind(this); + this.checkAndNotify = this.checkAndNotify.bind(this); this.validateAndSubmit = this.validateAndSubmit.bind(this); this.tableNameCheck = this.tableNameCheck.bind(this); @@ -154,12 +154,12 @@ class AddTable extends Component { return this.props.primaryKeys.filter(key => key !== '').length > 0; } - // check the validity and if invalid, dispatch + // check the validity and if invalid, notify // valid values are true and "" // strings get interpolated with notificationArray // and objects are assumed to be an array like notificationArray // and the second arg is ignored - checkAndDispatch(validated, notificationArray) { + checkAndNotify(validated, notificationArray) { if (validated === true || validated === '') return true; else if (validated === false) { this.props.dispatch( @@ -189,6 +189,10 @@ class AddTable extends Component { } } + tableNameEmptyCheck() { + return this.props.tableName !== null; + } + tableNameCheck() { return gqlPattern.test(this.props.tableName); } @@ -350,32 +354,29 @@ class AddTable extends Component { const validColumns = this.trimEmptyColumns(this.props.columns); if ( - this.checkAndDispatch( - this.props.tableName !== null, - tableNameNullNotif - ) && - this.checkAndDispatch(this.tableNameCheck(), gqlTableErrorNotif) && - this.checkAndDispatch( + this.checkAndNotify(this.tableNameEmptyCheck(), tableNameNullNotif) && + this.checkAndNotify(this.tableNameCheck(), gqlTableErrorNotif) && + this.checkAndNotify( this.validateEnoughColumns(validColumns), - tableEnufColumns + tableEnufColumnsNotif ) && - this.checkAndDispatch( + this.checkAndNotify( this.validateColumnNames(validColumns), gqlColumnErrorNotif ) && - this.checkAndDispatch( + this.checkAndNotify( this.validateNoDupNames(validColumns), - tableColumnNoDups + tableColumnNoDupsNotif ) && - this.checkAndDispatch( + this.checkAndNotify( this.validateColumnTypes(validColumns), - tableColumnTypes + tableColumnTypesNotif ) && - this.checkAndDispatch( + this.checkAndNotify( this.validateColumnDefaults(validColumns), - tableColumnDefaults + tableColumnDefaultsNotif ) && - this.checkAndDispatch(this.minPrimaryKeyCheck(), tableMinPrimaryKey) + this.checkAndNotify(this.minPrimaryKeyCheck(), tableMinPrimaryKeyNotif) ) { this.props.dispatch(createTableSql()); } @@ -416,23 +417,6 @@ class AddTable extends Component { return createBtnText; }; - const frequentlyUsedColumnsOptions = () => { - return frequentlyUsedColumns.map(fuc => { - const { title, subTitle } = getFreqUsedColDisplayInfo(fuc); - return { - content: ( -
    -
    - {title} -
    -
    {subTitle}
    -
    - ), - onClick: () => dispatch(setFreqUsedColumn(fuc)), - }; - }); - }; - return (
    - - - +

    diff --git a/console/src/components/Services/Data/Add/AddWarning.js b/console/src/components/Services/Data/Add/AddWarning.js index c7bd7e47372..5263479be0c 100644 --- a/console/src/components/Services/Data/Add/AddWarning.js +++ b/console/src/components/Services/Data/Add/AddWarning.js @@ -1,4 +1,4 @@ -const tableColumnNoDups = [ +const tableColumnNoDupsNotif = [ 'Error adding column', 'Column name is duplicated', { @@ -6,7 +6,7 @@ const tableColumnNoDups = [ }, ]; -const tableMinPrimaryKey = [ +const tableMinPrimaryKeyNotif = [ 'Error adding table', 'A primary key is required', { @@ -22,7 +22,7 @@ const tableNameNullNotif = [ }, ]; -const tableEnufColumns = [ +const tableEnufColumnsNotif = [ 'Error creating table!', 'Table must have at least one column', { @@ -30,7 +30,7 @@ const tableEnufColumns = [ }, ]; -const tableColumnDefaults = [ +const tableColumnDefaultsNotif = [ 'Error creating table!', 'Default value is invalid', { @@ -38,7 +38,7 @@ const tableColumnDefaults = [ }, ]; -const tableColumnTypes = [ +const tableColumnTypesNotif = [ 'Error creating table!', 'Column type is invalid', { @@ -48,9 +48,9 @@ const tableColumnTypes = [ export { tableNameNullNotif, - tableEnufColumns, - tableColumnNoDups, - tableMinPrimaryKey, - tableColumnDefaults, - tableColumnTypes, + tableEnufColumnsNotif, + tableColumnNoDupsNotif, + tableMinPrimaryKeyNotif, + tableColumnDefaultsNotif, + tableColumnTypesNotif, }; diff --git a/console/src/components/Services/Data/Add/utils.js b/console/src/components/Services/Data/Add/utils.js index 927a0c6dcf0..e69de29bb2d 100644 --- a/console/src/components/Services/Data/Add/utils.js +++ b/console/src/components/Services/Data/Add/utils.js @@ -1,66 +0,0 @@ -export const frequentlyUsedColumns = [ - { - name: 'id', - type: 'serial', - typeText: 'integer (auto-increment)', - primary: true, - }, - { - name: 'id', - type: 'uuid', - typeText: 'UUID', - primary: true, - default: 'gen_random_uuid()', - }, - { - name: 'created_at', - type: 'timestamptz', - typeText: 'timestamp', - default: 'now()', - }, - { - name: 'updated_at', - type: 'timestamptz', - typeText: 'timestamp', - default: 'now()', - defaultText: 'now() + trigger to set value on update', - dependentSQLGenerator: (schemaName, tableName, columnName) => { - return ` -CREATE OR REPLACE FUNCTION "${schemaName}"."set_current_timestamp_${columnName}"() -RETURNS TRIGGER AS $$ -DECLARE - _new record; -BEGIN - _new := NEW; - _new."${columnName}" = NOW(); - RETURN _new; -END; -$$ LANGUAGE plpgsql; -CREATE TRIGGER "set_${schemaName}_${tableName}_${columnName}" -BEFORE UPDATE ON "${schemaName}"."${tableName}" -FOR EACH ROW -EXECUTE PROCEDURE "${schemaName}"."set_current_timestamp_${columnName}"(); -COMMENT ON TRIGGER "set_${schemaName}_${tableName}_${columnName}" ON "${schemaName}"."${tableName}" -IS 'trigger to set value of column "${columnName}" to current timestamp on row update'; -`; - }, - }, -]; - -export const getFreqUsedColDisplayInfo = c => { - const title = c.name; - - const typeText = c.typeText + '; '; - const defaultText = - c.defaultText || c.default - ? `default: ${c.defaultText || c.default}; ` - : ''; - const pkText = c.primary ? 'primary key; ' : ''; - - const subTitle = typeText + defaultText + pkText; - - return { - title, - subTitle, - }; -}; diff --git a/console/src/components/Services/Data/Common/ReusableComponents/FrequentlyUsedColumnSelector.js b/console/src/components/Services/Data/Common/ReusableComponents/FrequentlyUsedColumnSelector.js new file mode 100644 index 00000000000..a84875835d4 --- /dev/null +++ b/console/src/components/Services/Data/Common/ReusableComponents/FrequentlyUsedColumnSelector.js @@ -0,0 +1,122 @@ +import React from 'react'; +import Dropdown from '../../../../Common/Dropdown/Dropdown'; +import Button from '../../../../Common/Button/Button'; + +const frequentlyUsedColumns = [ + { + name: 'id', + validFor: ['add'], + type: 'serial', + typeText: 'integer (auto-increment)', + primary: true, + }, + { + name: 'id', + validFor: ['add'], + type: 'uuid', + typeText: 'UUID', + primary: true, + default: 'gen_random_uuid()', + }, + { + name: 'created_at', + validFor: ['add', 'modify'], + type: 'timestamptz', + typeText: 'timestamp', + default: 'now()', + }, + { + name: 'updated_at', + validFor: ['add', 'modify'], + type: 'timestamptz', + typeText: 'timestamp', + default: 'now()', + defaultText: 'now() + trigger to set value on update', + dependentSQLGenerator: (schemaName, tableName, columnName) => { + const upSql = ` +CREATE OR REPLACE FUNCTION "${schemaName}"."set_current_timestamp_${columnName}"() +RETURNS TRIGGER AS $$ +DECLARE + _new record; +BEGIN + _new := NEW; + _new."${columnName}" = NOW(); + RETURN _new; +END; +$$ LANGUAGE plpgsql; +CREATE TRIGGER "set_${schemaName}_${tableName}_${columnName}" +BEFORE UPDATE ON "${schemaName}"."${tableName}" +FOR EACH ROW +EXECUTE PROCEDURE "${schemaName}"."set_current_timestamp_${columnName}"(); +COMMENT ON TRIGGER "set_${schemaName}_${tableName}_${columnName}" ON "${schemaName}"."${tableName}" +IS 'trigger to set value of column "${columnName}" to current timestamp on row update'; +`; + + const downSql = `DROP TRIGGER IF EXISTS "set_${schemaName}_${tableName}_${columnName}" ON "${schemaName}"."${tableName}";`; + + return { + upSql, + downSql, + }; + }, + }, +]; + +const getFreqUsedColDisplayInfo = c => { + const title = c.name; + + const typeText = c.typeText + '; '; + const defaultText = + c.defaultText || c.default + ? `default: ${c.defaultText || c.default}; ` + : ''; + const pkText = c.primary ? 'primary key; ' : ''; + + const subTitle = typeText + defaultText + pkText; + + return { + title, + subTitle, + }; +}; + +const FrequentlyUsedColumnSelector = ({ + onSelect, + action = null, + dispatch = null, +}) => { + const frequentlyUsedColumnsOptions = () => { + return frequentlyUsedColumns + .filter(fuc => !action || fuc.validFor.includes(action)) + .map(fuc => { + const { title, subTitle } = getFreqUsedColDisplayInfo(fuc); + return { + content: ( +
    +
    + {title} +
    +
    {subTitle}
    +
    + ), + onClick: () => (dispatch ? dispatch(onSelect(fuc)) : onSelect(fuc)), + }; + }); + }; + + return ( + + + + ); +}; + +export default FrequentlyUsedColumnSelector; diff --git a/console/src/components/Services/Data/TableModify/ColumnCreator.js b/console/src/components/Services/Data/TableModify/ColumnCreator.js index 138f2980004..fc57e7af5e2 100644 --- a/console/src/components/Services/Data/TableModify/ColumnCreator.js +++ b/console/src/components/Services/Data/TableModify/ColumnCreator.js @@ -16,6 +16,7 @@ import Button from '../../../Common/Button/Button'; import { addColSql } from '../TableModify/ModifyActions'; import styles from './ModifyTable.scss'; +import FrequentlyUsedColumnSelector from '../Common/ReusableComponents/FrequentlyUsedColumnSelector'; const useColumnEditor = (dispatch, tableName) => { const initialState = { @@ -24,10 +25,18 @@ const useColumnEditor = (dispatch, tableName) => { colNull: true, colUnique: false, colDefault: '', + colDependentSQLGenerator: null, }; const [columnState, setColumnState] = useState(initialState); - const { colName, colType, colNull, colUnique, colDefault } = columnState; + const { + colName, + colType, + colNull, + colUnique, + colDefault, + colDependentSQLGenerator, + } = columnState; const onSubmit = e => { e.preventDefault(); @@ -57,6 +66,7 @@ const useColumnEditor = (dispatch, tableName) => { colNull, colUnique, colDefault, + colDependentSQLGenerator, () => setColumnState(initialState) ) ); @@ -95,6 +105,17 @@ const useColumnEditor = (dispatch, tableName) => { setColumnState({ ...columnState, colDefault: newValue }); }, }, + frequentlyUsedColumn: { + onSelect: fuc => { + setColumnState({ + ...initialState, + colName: fuc.name, + colType: fuc.type, + colDefault: fuc.default, + colDependentSQLGenerator: fuc.dependentSQLGenerator, + }); + }, + }, onSubmit, }; }; @@ -112,26 +133,107 @@ const ColumnCreator = ({ colNull, colUnique, colDefault, + frequentlyUsedColumn, onSubmit, } = useColumnEditor(dispatch, tableName); - let defaultOptions = []; + const getColumnNameInput = () => { + return ( + + ); + }; - const getInferredDefaultValues = () => - inferDefaultValues(columnDefaultFunctions, validTypeCasts)(colType.value); + const getColumnTypeInput = () => { + const { columnDataTypes, columnTypeValueMap } = getDataOptions( + commonDataTypes, + restTypes, + 0 + ); - const colDefaultFunctions = - colType.value in columnDefaultFunctions - ? columnDefaultFunctions[colType.value] - : getInferredDefaultValues(); + const customSelectBoxStyles = { + container: { + width: '186px', + }, + dropdownIndicator: { + padding: '5px', + }, + placeholder: { + top: '44%', + fontSize: '12px', + }, + singleValue: { + fontSize: '12px', + top: '44%', + color: '#555555', + }, + }; - if (colDefaultFunctions && colDefaultFunctions.length > 0) { - defaultOptions = getDefaultFunctionsOptions(colDefaultFunctions, 0); - } + return ( + + + + ); + }; - const getDefaultInput = () => { + const getColumnNullableInput = () => { + return ( + + + + + ); + }; + + const getColumnUniqueInput = () => { + return ( + + + + + ); + }; + + const getColumnDefaultInput = () => { const theme = require('../../../Common/CustomInputAutoSuggest/CustomThemes/AddColumnDefault.scss'); + let defaultOptions = []; + + const getInferredDefaultValues = () => + inferDefaultValues(columnDefaultFunctions, validTypeCasts)(colType.value); + + const colDefaultFunctions = + colType.value in columnDefaultFunctions + ? columnDefaultFunctions[colType.value] + : getInferredDefaultValues(); + + if (colDefaultFunctions && colDefaultFunctions.length > 0) { + defaultOptions = getDefaultFunctionsOptions(colDefaultFunctions, 0); + } + return ( { + return ( + + ); + }; - const customSelectBoxStyles = { - container: { - width: '186px', - }, - dropdownIndicator: { - padding: '5px', - }, - placeholder: { - top: '44%', - fontSize: '12px', - }, - singleValue: { - fontSize: '12px', - top: '44%', - color: '#555555', - }, + const getFrequentlyUsedColumnSelector = () => { + return ( + + ); }; return ( @@ -176,61 +276,17 @@ const ColumnCreator = ({ className={`form-inline ${styles.display_flex}`} onSubmit={onSubmit} > - - - - - - + {getColumnNameInput()} + {getColumnTypeInput()} + {getColumnNullableInput()} + {getColumnUniqueInput()} + {getColumnDefaultInput()} - - - {getDefaultInput()} - {/* - - */} - - + {getSubmitButton()} +
    + {getFrequentlyUsedColumnSelector()} +

    ); }; diff --git a/console/src/components/Services/Data/TableModify/ModifyActions.js b/console/src/components/Services/Data/TableModify/ModifyActions.js index f34331de0b6..6096f4cd7ef 100644 --- a/console/src/components/Services/Data/TableModify/ModifyActions.js +++ b/console/src/components/Services/Data/TableModify/ModifyActions.js @@ -318,14 +318,14 @@ const saveForeignKeys = (index, tableSchema, columns) => { alter table "${schemaName}"."${tableName}" drop constraint "${generatedConstraintName}", add constraint "${constraintName}" foreign key (${Object.keys(oldConstraint.column_mapping) - .map(lc => `"${lc}"`) - .join(', ')}) + .map(lc => `"${lc}"`) + .join(', ')}) references "${oldConstraint.ref_table_table_schema}"."${ - oldConstraint.ref_table -}" + oldConstraint.ref_table + }" (${Object.values(oldConstraint.column_mapping) - .map(rc => `"${rc}"`) - .join(', ')}) + .map(rc => `"${rc}"`) + .join(', ')}) on update ${pgConfTypes[oldConstraint.on_update]} on delete ${pgConfTypes[oldConstraint.on_delete]}; `; @@ -583,8 +583,8 @@ const deleteTrigger = (trigger, table) => { downMigrationSql += `CREATE TRIGGER "${triggerName}" ${trigger.action_timing} ${ - trigger.event_manipulation -} ON "${tableSchema}"."${tableName}" + trigger.event_manipulation + } ON "${tableSchema}"."${tableName}" FOR EACH ${trigger.action_orientation} ${trigger.action_statement};`; if (trigger.comment) { @@ -1072,6 +1072,7 @@ const addColSql = ( colNull, colUnique, colDefault, + colDependentSQLGenerator, callback ) => { let defWithQuotes = "''"; @@ -1100,6 +1101,7 @@ const addColSql = ( '"' + ' ' + colType; + // check if nullable if (colNull) { // nullable @@ -1108,15 +1110,30 @@ const addColSql = ( // not nullable runSqlQueryUp += ' NOT NULL'; } + // check if unique if (colUnique) { runSqlQueryUp += ' UNIQUE'; } + // check if default value if (colDefault !== '') { runSqlQueryUp += ' DEFAULT ' + defWithQuotes; } + + runSqlQueryUp += ';'; + + const colDependentSQL = colDependentSQLGenerator + ? colDependentSQLGenerator(currentSchema, tableName, colName) + : null; + + if (colDependentSQL) { + runSqlQueryUp += '\n'; + runSqlQueryUp += colDependentSQL.upSql; + } + const schemaChangesUp = []; + if (colType === 'uuid' && colDefault !== '') { schemaChangesUp.push({ type: 'run_sql', @@ -1125,13 +1142,22 @@ const addColSql = ( }, }); } + schemaChangesUp.push({ type: 'run_sql', args: { sql: runSqlQueryUp, }, }); - const runSqlQueryDown = + + let runSqlQueryDown = ''; + + if (colDependentSQL) { + runSqlQueryDown += colDependentSQL.downSql; + runSqlQueryDown += '\n'; + } + + runSqlQueryDown += 'ALTER TABLE ' + '"' + currentSchema + @@ -1143,7 +1169,8 @@ const addColSql = ( ' DROP COLUMN ' + '"' + colName + - '"'; + '";'; + const schemaChangesDown = [ { type: 'run_sql', @@ -1420,24 +1447,24 @@ const saveColumnChangesSql = (colName, column, onSuccess) => { const schemaChangesUp = originalColType !== colType ? [ - { - type: 'run_sql', - args: { - sql: columnChangesUpQuery, + { + type: 'run_sql', + args: { + sql: columnChangesUpQuery, + }, }, - }, - ] + ] : []; const schemaChangesDown = originalColType !== colType ? [ - { - type: 'run_sql', - args: { - sql: columnChangesDownQuery, + { + type: 'run_sql', + args: { + sql: columnChangesDownQuery, + }, }, - }, - ] + ] : []; /* column default up/down migration */ From 19069c2c2bb64039192975fe9235ba89c8be4faf Mon Sep 17 00:00:00 2001 From: Rikin Kachhia Date: Fri, 2 Aug 2019 18:13:10 +0530 Subject: [PATCH 24/27] show proper console notifications for errors in db schema load & metadata reload --- console/src/components/Services/Data/DataActions.js | 5 ++++- .../Services/Metadata/MetadataOptions/ReloadMetadata.js | 6 ++++-- .../Services/Metadata/MetadataStatus/MetadataStatus.js | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/console/src/components/Services/Data/DataActions.js b/console/src/components/Services/Data/DataActions.js index e4cd7403bc0..9635b79e2c3 100644 --- a/console/src/components/Services/Data/DataActions.js +++ b/console/src/components/Services/Data/DataActions.js @@ -304,7 +304,10 @@ const loadSchema = configOptions => { dispatch(loadInconsistentObjects()); }, error => { - console.error('Failed to load schema ' + JSON.stringify(error)); + console.error('loadSchema error: ' + JSON.stringify(error)); + dispatch( + showErrorNotification('DB schema loading failed', null, error) + ); } ); }; diff --git a/console/src/components/Services/Metadata/MetadataOptions/ReloadMetadata.js b/console/src/components/Services/Metadata/MetadataOptions/ReloadMetadata.js index 0aa38a48298..3ec2acc32c7 100644 --- a/console/src/components/Services/Metadata/MetadataOptions/ReloadMetadata.js +++ b/console/src/components/Services/Metadata/MetadataOptions/ReloadMetadata.js @@ -26,8 +26,10 @@ class ReloadMetadata extends Component { dispatch(showSuccessNotification('Metadata reloaded')); this.setState({ isReloading: false }); }, - () => { - dispatch(showErrorNotification('Error reloading metadata')); + err => { + dispatch( + showErrorNotification('Error reloading metadata', null, err) + ); this.setState({ isReloading: false }); } ) diff --git a/console/src/components/Services/Metadata/MetadataStatus/MetadataStatus.js b/console/src/components/Services/Metadata/MetadataStatus/MetadataStatus.js index 694d2c46953..e66f65402c9 100644 --- a/console/src/components/Services/Metadata/MetadataStatus/MetadataStatus.js +++ b/console/src/components/Services/Metadata/MetadataStatus/MetadataStatus.js @@ -99,8 +99,8 @@ const MetadataStatus = ({ dispatch, metadata }) => { }) .catch(e => { // todo error handling - console.error(e); - dispatch(showErrorNotification('Error reloading metadata')); + console.error('reloadMetadata error: ', e); + dispatch(showErrorNotification('Error reloading metadata', null, e)); }); }; From d19491ce542a933ded31db64d8f7213ccdc230b5 Mon Sep 17 00:00:00 2001 From: Josha Inglis Date: Mon, 5 Aug 2019 18:05:37 +1000 Subject: [PATCH 25/27] improve console logic for view updatability check (fix #2667) (#2668) --- .../Data/TablePermissions/Permissions.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/console/src/components/Services/Data/TablePermissions/Permissions.js b/console/src/components/Services/Data/TablePermissions/Permissions.js index 7d619076724..893ad50d209 100644 --- a/console/src/components/Services/Data/TablePermissions/Permissions.js +++ b/console/src/components/Services/Data/TablePermissions/Permissions.js @@ -239,8 +239,10 @@ class Permissions extends Component { tableType === 'view' && !( tableSchema.view_info && - tableSchema.view_info.is_insertable_into === 'YES' && - tableSchema.view_info.is_updatable === 'YES' + (tableSchema.view_info.is_insertable_into === 'YES' || + tableSchema.view_info.is_trigger_insertable_into === 'YES') && + (tableSchema.view_info.is_updatable === 'YES' || + tableSchema.view_info.is_trigger_updatable === 'YES') ) ) { hasPermissions = false; @@ -1770,7 +1772,10 @@ class Permissions extends Component { // Add insert/update permission if it is insertable/updatable as returned by pg if (tSchema.view_info) { - if (tSchema.view_info.is_insertable_into === 'YES') { + if ( + tSchema.view_info.is_insertable_into === 'YES' || + tSchema.view_info.is_trigger_insertable_into === 'YES' + ) { qTypes.push('insert'); } @@ -1779,6 +1784,14 @@ class Permissions extends Component { if (tSchema.view_info.is_updatable === 'YES') { qTypes.push('update'); qTypes.push('delete'); + } else { + if (tSchema.view_info.is_trigger_updatable === 'YES') { + qTypes.push('update'); + } + + if (tSchema.view_info.is_trigger_deletable === 'YES') { + qTypes.push('delete'); + } } } else { qTypes.push('select'); From 242ecf5a47fb42d2d793d2d081340cbc503d6ac0 Mon Sep 17 00:00:00 2001 From: Raja Jain Date: Tue, 6 Aug 2019 09:33:11 +0530 Subject: [PATCH 26/27] community: learn: add flutter-graphql tutorial (#2554) --- .../manifests/caddy-config.yaml | 10 + .../manifests/flutter-graphql.yaml | 50 ++ .../remote-hasura.yaml.sample | 5 + .../app-boilerplate/.gitignore | 73 +++ .../flutter-graphql/app-boilerplate/.metadata | 10 + .../flutter-graphql/app-boilerplate/README.md | 16 + .../app-boilerplate/android/app/build.gradle | 61 ++ .../android/app/proguard-rules.pro | 7 + .../android/app/src/debug/AndroidManifest.xml | 7 + .../android/app/src/main/AndroidManifest.xml | 34 ++ .../example/app_boilerplate/MainActivity.java | 13 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../app/src/main/res/values/styles.xml | 8 + .../app/src/profile/AndroidManifest.xml | 7 + .../app-boilerplate/android/build.gradle | 29 + .../app-boilerplate/android/gradle.properties | 4 + .../gradle/wrapper/gradle-wrapper.properties | 6 + .../app-boilerplate/android/settings.gradle | 15 + .../ios/Flutter/AppFrameworkInfo.plist | 26 + .../ios/Flutter/Debug.xcconfig | 2 + .../ios/Flutter/Release.xcconfig | 2 + .../app-boilerplate/ios/Podfile | 72 +++ .../app-boilerplate/ios/Podfile.lock | 22 + .../ios/Runner.xcodeproj/project.pbxproj | 571 +++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/Runner.xcscheme | 93 +++ .../contents.xcworkspacedata | 10 + .../app-boilerplate/ios/Runner/AppDelegate.h | 6 + .../app-boilerplate/ios/Runner/AppDelegate.m | 13 + .../AppIcon.appiconset/Contents.json | 122 ++++ .../Icon-App-1024x1024@1x.png | Bin 0 -> 11112 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 564 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 1588 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 1025 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 1716 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 1920 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 1895 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 3831 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 1888 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 3294 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 3612 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + .../Runner/Base.lproj/LaunchScreen.storyboard | 37 ++ .../ios/Runner/Base.lproj/Main.storyboard | 26 + .../app-boilerplate/ios/Runner/Info.plist | 45 ++ .../app-boilerplate/ios/Runner/main.m | 9 + .../lib/components/add_task.dart | 46 ++ .../lib/components/custom_button.dart | 34 ++ .../lib/components/feed_tile.dart | 22 + .../lib/components/todo_item_tile.dart | 52 ++ .../app-boilerplate/lib/components/utils.dart | 9 + .../app-boilerplate/lib/data/feed_list.dart | 19 + .../app-boilerplate/lib/data/online_list.dart | 5 + .../app-boilerplate/lib/data/todo_list.dart | 32 + .../app-boilerplate/lib/main.dart | 24 + .../app-boilerplate/lib/model/feed_item.dart | 11 + .../app-boilerplate/lib/model/todo_item.dart | 19 + .../lib/screens/dashboard.dart | 63 ++ .../app-boilerplate/lib/screens/login.dart | 127 ++++ .../app-boilerplate/lib/screens/signup.dart | 106 ++++ .../app-boilerplate/lib/screens/splash.dart | 28 + .../lib/screens/tabs/dashboard/feeds.dart | 80 +++ .../lib/screens/tabs/dashboard/online.dart | 33 + .../lib/screens/tabs/dashboard/todos.dart | 43 ++ .../lib/screens/tabs/todos/active.dart | 46 ++ .../lib/screens/tabs/todos/all.dart | 52 ++ .../lib/screens/tabs/todos/completed.dart | 46 ++ .../app-boilerplate/lib/services/auth.dart | 50 ++ .../services/shared_preferences_service.dart | 25 + .../app-boilerplate/pubspec.lock | 175 ++++++ .../app-boilerplate/pubspec.yaml | 76 +++ .../app-boilerplate/test/widget_test.dart | 30 + .../flutter-graphql/app-final/.gitignore | 72 +++ .../flutter-graphql/app-final/.metadata | 10 + .../flutter-graphql/app-final/README.md | 16 + .../app-final/android/app/build.gradle | 61 ++ .../android/app/src/debug/AndroidManifest.xml | 7 + .../android/app/src/main/AndroidManifest.xml | 34 ++ .../com/example/app_final/MainActivity.java | 13 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../app/src/main/res/values/styles.xml | 8 + .../app/src/profile/AndroidManifest.xml | 7 + .../app-final/android/build.gradle | 29 + .../app-final/android/gradle.properties | 2 + .../gradle/wrapper/gradle-wrapper.properties | 6 + .../app-final/android/settings.gradle | 15 + .../ios/Flutter/AppFrameworkInfo.plist | 26 + .../app-final/ios/Flutter/Debug.xcconfig | 2 + .../app-final/ios/Flutter/Release.xcconfig | 2 + .../flutter-graphql/app-final/ios/Podfile | 72 +++ .../app-final/ios/Podfile.lock | 28 + .../ios/Runner.xcodeproj/project.pbxproj | 577 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/Runner.xcscheme | 91 +++ .../contents.xcworkspacedata | 10 + .../app-final/ios/Runner/AppDelegate.h | 6 + .../app-final/ios/Runner/AppDelegate.m | 13 + .../AppIcon.appiconset/Contents.json | 122 ++++ .../Icon-App-1024x1024@1x.png | Bin 0 -> 11112 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 564 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 1588 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 1025 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 1716 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 1920 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 1895 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 3831 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 1888 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 3294 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 3612 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + .../Runner/Base.lproj/LaunchScreen.storyboard | 37 ++ .../ios/Runner/Base.lproj/Main.storyboard | 26 + .../app-final/ios/Runner/Info.plist | 45 ++ .../app-final/ios/Runner/main.m | 9 + .../app-final/lib/components/add_task.dart | 46 ++ .../lib/components/custom_button.dart | 34 ++ .../app-final/lib/components/feed_tile.dart | 22 + .../lib/components/todo_item_tile.dart | 112 ++++ .../app-final/lib/components/utils.dart | 9 + .../app-final/lib/config/client.dart | 32 + .../app-final/lib/data/feed_fetch.dart | 41 ++ .../app-final/lib/data/feed_list.dart | 20 + .../app-final/lib/data/online_fetch.dart | 17 + .../app-final/lib/data/online_list.dart | 5 + .../app-final/lib/data/todo_fetch.dart | 51 ++ .../app-final/lib/data/todo_list.dart | 32 + .../flutter-graphql/app-final/lib/main.dart | 25 + .../app-final/lib/model/feed_item.dart | 11 + .../app-final/lib/model/todo_item.dart | 19 + .../app-final/lib/screens/dashboard.dart | 70 +++ .../app-final/lib/screens/login.dart | 129 ++++ .../app-final/lib/screens/signup.dart | 106 ++++ .../app-final/lib/screens/splash.dart | 28 + .../lib/screens/tabs/dashboard/feeds.dart | 180 ++++++ .../lib/screens/tabs/dashboard/online.dart | 50 ++ .../lib/screens/tabs/dashboard/todos.dart | 43 ++ .../lib/screens/tabs/todos/active.dart | 84 +++ .../app-final/lib/screens/tabs/todos/all.dart | 106 ++++ .../lib/screens/tabs/todos/completed.dart | 81 +++ .../app-final/lib/services/auth.dart | 51 ++ .../services/shared_preferences_service.dart | 25 + .../flutter-graphql/app-final/pubspec.lock | 238 ++++++++ .../flutter-graphql/app-final/pubspec.yaml | 76 +++ .../app-final/test/widget_test.dart | 30 + .../flutter-graphql/tutorial-site/Dockerfile | 30 + .../tutorial-site/Dockerfile.localdev | 27 + .../flutter-graphql/tutorial-site/README.md | 18 + .../flutter-graphql/tutorial-site/config.js | 55 ++ .../tutorial-site/content/graphql-client.md | 76 +++ .../tutorial-site/content/index.mdx | 26 + .../tutorial-site/content/intro-to-graphql.md | 87 +++ .../intro-to-graphql/1-architecture.md | 62 ++ .../2-fetching-data-queries.md | 206 +++++++ .../3-writing-data-mutations.md | 122 ++++ .../4-watching-data-subscriptions.md | 48 ++ .../tutorial-site/content/introduction.md | 57 ++ .../tutorial-site/content/logout.md | 5 + .../tutorial-site/content/mutations.md | 16 + .../content/mutations/1-create-todo.md | 27 + .../content/mutations/2-create-mutation.md | 60 ++ .../tutorial-site/content/queries.md | 14 + .../content/queries/1-fetch-todos-query.md | 28 + .../content/queries/2-create-query.md | 144 +++++ .../content/queries/3-handle-errors.md | 62 ++ .../tutorial-site/content/realtime-feed.md | 7 + .../realtime-feed/1-subscribe-to-new-todos.md | 62 ++ .../realtime-feed/2-run-subscription.md | 84 +++ .../content/realtime-feed/3-sync-todos.md | 158 +++++ .../tutorial-site/content/setup.md | 30 + .../tutorial-site/content/subscriptions.md | 72 +++ .../content/subscriptions/1-subscription.md | 7 + .../subscriptions/2-apollo-subscription.md | 7 + .../subscriptions/3-create-subscription.md | 63 ++ .../tutorial-site/content/twitter-share.js | 11 + .../content/update-delete-mutations.md | 13 + .../update-delete-mutations/1-update-todos.md | 25 + .../2-mutation-cache.md | 97 +++ .../update-delete-mutations/3-remove-todos.md | 23 + .../4-remove-todos-integration.md | 52 ++ .../tutorial-site/content/what-next.md | 27 + 206 files changed, 7785 insertions(+) create mode 100644 community/learn/graphql-tutorials/manifests/flutter-graphql.yaml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/.gitignore create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/.metadata create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/README.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/build.gradle create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/proguard-rules.pro create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/debug/AndroidManifest.xml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/AndroidManifest.xml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/java/com/example/app_boilerplate/MainActivity.java create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/drawable/launch_background.xml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/values/styles.xml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/profile/AndroidManifest.xml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/build.gradle create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/gradle.properties create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/settings.gradle create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/AppFrameworkInfo.plist create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/Debug.xcconfig create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/Release.xcconfig create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Podfile create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Podfile.lock create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/project.pbxproj create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/AppDelegate.h create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/AppDelegate.m create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Base.lproj/Main.storyboard create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Info.plist create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/main.m create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/add_task.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/custom_button.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/feed_tile.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/todo_item_tile.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/utils.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/feed_list.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/online_list.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/todo_list.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/main.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/model/feed_item.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/model/todo_item.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/dashboard.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/login.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/signup.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/splash.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/feeds.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/online.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/todos.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/active.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/all.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/completed.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/services/auth.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/services/shared_preferences_service.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/pubspec.lock create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/pubspec.yaml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/test/widget_test.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/.gitignore create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/.metadata create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/README.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/build.gradle create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/debug/AndroidManifest.xml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/AndroidManifest.xml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/java/com/example/app_final/MainActivity.java create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/drawable/launch_background.xml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/values/styles.xml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/profile/AndroidManifest.xml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/build.gradle create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/gradle.properties create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/settings.gradle create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/AppFrameworkInfo.plist create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/Debug.xcconfig create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/Release.xcconfig create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Podfile create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Podfile.lock create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/project.pbxproj create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/AppDelegate.h create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/AppDelegate.m create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Base.lproj/Main.storyboard create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Info.plist create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/main.m create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/add_task.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/custom_button.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/feed_tile.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/todo_item_tile.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/utils.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/config/client.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/feed_fetch.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/feed_list.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/online_fetch.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/online_list.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/todo_fetch.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/todo_list.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/main.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/model/feed_item.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/model/todo_item.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/dashboard.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/login.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/signup.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/splash.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/feeds.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/online.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/todos.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/active.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/all.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/completed.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/services/auth.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/services/shared_preferences_service.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/pubspec.lock create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/pubspec.yaml create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/test/widget_test.dart create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/Dockerfile create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/Dockerfile.localdev create mode 100755 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/README.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/config.js create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/graphql-client.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/index.mdx create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/1-architecture.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/2-fetching-data-queries.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/3-writing-data-mutations.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/4-watching-data-subscriptions.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/introduction.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/logout.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations/1-create-todo.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations/2-create-mutation.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/1-fetch-todos-query.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/2-create-query.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/3-handle-errors.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/1-subscribe-to-new-todos.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/2-run-subscription.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/3-sync-todos.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/setup.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/1-subscription.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/2-apollo-subscription.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/3-create-subscription.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/twitter-share.js create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/1-update-todos.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/2-mutation-cache.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/3-remove-todos.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/4-remove-todos-integration.md create mode 100644 community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/what-next.md diff --git a/community/learn/graphql-tutorials/manifests/caddy-config.yaml b/community/learn/graphql-tutorials/manifests/caddy-config.yaml index 055116d551b..6f34342cb92 100644 --- a/community/learn/graphql-tutorials/manifests/caddy-config.yaml +++ b/community/learn/graphql-tutorials/manifests/caddy-config.yaml @@ -37,6 +37,14 @@ data: /graphql/reason-react-apollo/boilerplate.zip https://graphql-engine-cdn.hasura.io/learn-hasura/boilerplates/reason-react-apollo/boilerplate.zip } + redir 301 { + /graphql/flutter-graphql/boilerplate.zip https://graphql-engine-cdn.hasura.io/learn-hasura/boilerplates/flutter-graphql/boilerplate.zip + } + + redir 301 { + /graphql/flutter-graphql/ /graphql/flutter-graphql/introduction + } + redir 301 { /graphql/reason-react-apollo/ /graphql/reason-react-apollo/introduction } @@ -121,6 +129,8 @@ data: proxy /graphql/reason-react-apollo reason-react-apollo + proxy /graphql/flutter-graphql flutter-graphql + proxy /graphql hasura/v1/graphql { without /graphql websocket diff --git a/community/learn/graphql-tutorials/manifests/flutter-graphql.yaml b/community/learn/graphql-tutorials/manifests/flutter-graphql.yaml new file mode 100644 index 00000000000..3b60dbfb87c --- /dev/null +++ b/community/learn/graphql-tutorials/manifests/flutter-graphql.yaml @@ -0,0 +1,50 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: flutter-graphql + name: flutter-graphql + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: flutter-graphql + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 100% + template: + metadata: + labels: + app: flutter-graphql + spec: + containers: + - image: hasura/base-git-image:0.7 + imagePullPolicy: IfNotPresent + name: flutter-graphql + ports: + - containerPort: 8080 + protocol: TCP + readinessProbe: + httpGet: + path: /graphql/flutter-graphql/introduction + port: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: flutter-graphql + name: flutter-graphql + namespace: default +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 8080 + selector: + app: flutter-graphql + type: ClusterIP diff --git a/community/learn/graphql-tutorials/remote-hasura.yaml.sample b/community/learn/graphql-tutorials/remote-hasura.yaml.sample index 394fe1c860d..414580e62dd 100644 --- a/community/learn/graphql-tutorials/remote-hasura.yaml.sample +++ b/community/learn/graphql-tutorials/remote-hasura.yaml.sample @@ -69,6 +69,11 @@ spec: name: reason-react-apollo path: ./community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site name: reason-react-apollo + - containers: + - dockerfile: ./community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/Dockerfile + name: flutter-graphql + path: ./community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site + name: flutter-graphql manifests: helm: {} path: ./community/learn/graphql-tutorials/manifests diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/.gitignore b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/.gitignore new file mode 100644 index 00000000000..de8046ada4f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/.gitignore @@ -0,0 +1,73 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/.metadata b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/.metadata new file mode 100644 index 00000000000..30f681a2d44 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 362b999b90d53859aa7b926a59c970f3ea31abf4 + channel: dev + +project_type: app diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/README.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/README.md new file mode 100644 index 00000000000..252e73e2977 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/README.md @@ -0,0 +1,16 @@ +# app_boilerplate + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/build.gradle b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/build.gradle new file mode 100644 index 00000000000..ce8b4d75296 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.app_boilerplate" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/proguard-rules.pro b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/proguard-rules.pro new file mode 100644 index 00000000000..70885bd0918 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/proguard-rules.pro @@ -0,0 +1,7 @@ +## Flutter wrapper +-keep class io.flutter.app.** { *; } +-keep class io.flutter.plugin.** { *; } +-keep class io.flutter.util.** { *; } +-keep class io.flutter.view.** { *; } +-keep class io.flutter.** { *; } +-keep class io.flutter.plugins.** { *; } \ No newline at end of file diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/debug/AndroidManifest.xml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000000..87dc2edcbae --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/AndroidManifest.xml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..a6a0c8459a9 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/java/com/example/app_boilerplate/MainActivity.java b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/java/com/example/app_boilerplate/MainActivity.java new file mode 100644 index 00000000000..93e61b07b82 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/java/com/example/app_boilerplate/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.app_boilerplate; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/drawable/launch_background.xml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000000..304732f8842 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/values/styles.xml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000000..00fa4417cfb --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/profile/AndroidManifest.xml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000000..87dc2edcbae --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/build.gradle b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/build.gradle new file mode 100644 index 00000000000..541636cc492 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.3.0' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/gradle.properties b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/gradle.properties new file mode 100644 index 00000000000..8ce44f61a0d --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableJetifier=true +android.useAndroidX=true + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/gradle/wrapper/gradle-wrapper.properties b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..2819f022f1f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/settings.gradle b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/settings.gradle new file mode 100644 index 00000000000..5a2f14fb18f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/AppFrameworkInfo.plist b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000000..9367d483e44 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/Debug.xcconfig b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000000..e8efba11468 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/Release.xcconfig b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000000..399e9340e6f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Podfile b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Podfile new file mode 100644 index 00000000000..64ba7492ea9 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Podfile @@ -0,0 +1,72 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + end + pods_ary = [] + skip_line_start_symbols = ["#", "/"] + File.foreach(file_abs_path) { |line| + next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } + plugin = line.split(pattern=separator) + if plugin.length == 2 + podname = plugin[0].strip() + path = plugin[1].strip() + podpath = File.expand_path("#{path}", file_abs_path) + pods_ary.push({:name => podname, :path => podpath}); + else + puts "Invalid plugin specification: #{line}" + end + } + return pods_ary +end + +target 'Runner' do + # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock + # referring to absolute paths on developers' machines. + system('rm -rf .symlinks') + system('mkdir -p .symlinks/plugins') + + # Flutter Pods + generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') + if generated_xcode_build_settings.empty? + puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first." + end + generated_xcode_build_settings.map { |p| + if p[:name] == 'FLUTTER_FRAMEWORK_DIR' + symlink = File.join('.symlinks', 'flutter') + File.symlink(File.dirname(p[:path]), symlink) + pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) + end + } + + # Plugin Pods + plugin_pods = parse_KV_file('../.flutter-plugins') + plugin_pods.map { |p| + symlink = File.join('.symlinks', 'plugins', p[:name]) + File.symlink(p[:path], symlink) + pod p[:name], :path => File.join(symlink, 'ios') + } +end + +# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. +install! 'cocoapods', :disable_input_output_paths => true + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end +end diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Podfile.lock b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Podfile.lock new file mode 100644 index 00000000000..78e30adae6a --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Podfile.lock @@ -0,0 +1,22 @@ +PODS: + - Flutter (1.0.0) + - shared_preferences (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `.symlinks/flutter/ios`) + - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) + +EXTERNAL SOURCES: + Flutter: + :path: ".symlinks/flutter/ios" + shared_preferences: + :path: ".symlinks/plugins/shared_preferences/ios" + +SPEC CHECKSUMS: + Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a + shared_preferences: 1feebfa37bb57264736e16865e7ffae7fc99b523 + +PODFILE CHECKSUM: 7fb83752f59ead6285236625b82473f90b1cb932 + +COCOAPODS: 1.7.3 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/project.pbxproj b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..61ed9ad781f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,571 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + B2A1B942C7567EA1E192F576 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69F5F66A71A9272B941370B7 /* libPods-Runner.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 009B69F0F11A836865C26587 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 69F5F66A71A9272B941370B7 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7243B9F2463C76C8A9F67B79 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D49B8277A02C5FB9D47F6C60 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + B2A1B942C7567EA1E192F576 /* libPods-Runner.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2E89F3FDCF7059D26DB27B4E /* Frameworks */ = { + isa = PBXGroup; + children = ( + 69F5F66A71A9272B941370B7 /* libPods-Runner.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 34912711BAAE182FA08750E7 /* Pods */ = { + isa = PBXGroup; + children = ( + 7243B9F2463C76C8A9F67B79 /* Pods-Runner.debug.xcconfig */, + 009B69F0F11A836865C26587 /* Pods-Runner.release.xcconfig */, + D49B8277A02C5FB9D47F6C60 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 34912711BAAE182FA08750E7 /* Pods */, + 2E89F3FDCF7059D26DB27B4E /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 885AE27C3CC997A8D697998C /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + D916C489DDDC3AE07EB82305 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 885AE27C3CC997A8D697998C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + D916C489DDDC3AE07EB82305 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.appBoilerplate; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.appBoilerplate; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.appBoilerplate; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000..1d526a16ed0 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000000..786d6aad545 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcworkspace/contents.xcworkspacedata b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000..21a3cc14c74 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/AppDelegate.h b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/AppDelegate.h new file mode 100644 index 00000000000..36e21bbf9cf --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/AppDelegate.m b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/AppDelegate.m new file mode 100644 index 00000000000..59a72e90be1 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000000..d36b1fab2d9 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d43d11e66f4de3da27ed045ca4fe38ad8b48094 GIT binary patch literal 11112 zcmeHN3sh5A)((b(k1DoWZSj%R+R=^`Y(b;ElB$1^R>iT7q6h&WAVr806i~>Gqn6rM z>3}bMG&oq%DIriqR35=rtEdos5L6z)YC*Xq0U-$_+Il@RaU zXYX%+``hR28`(B*uJ6G9&iz>|)PS%!)9N`7=LcmcxH}k69HPyT-%S zH7+jBCC<%76cg_H-n41cTqnKn`u_V9p~XaTLUe3s{KRPSTeK6apP4Jg%VQ$e#72ms zxyWzmGSRwN?=fRgpx!?W&ZsrLfuhAsRxm%;_|P@3@3~BJwY4ZVBJ3f&$5x>`^fD?d zI+z!v#$!gz%FtL*%mR^Uwa*8LJFZ_;X!y$cD??W#c)31l@ervOa_Qk86R{HJiZb$f z&&&0xYmB{@D@yl~^l5IXtB_ou{xFiYP(Jr<9Ce{jCN z<3Rf2TD%}_N?y>bgWq|{`RKd}n>P4e8Z-D+(fn^4)+|pv$DcR&i+RHNhv$71F*McT zl`phYBlb;wO`b7)*10XF6UXhY9`@UR*6-#(Zp`vyU(__*te6xYtV&N0(zjMtev{tZ zapmGin===teMXjsS0>CYxUy<2izOKOPai0}!B9+6q$s3CF8W{xUwz?A0ADO5&BsiB z{SFt|KehNd-S#eiDq!y&+mW9N_!wH-i~q|oNm=mEzkx}B?Ehe%q$tK8f=QY#*6rH9 zNHHaG(9WBqzP!!TMEktSVuh$i$4A^b25LK}&1*4W?ul*5pZYjL1OZ@X9?3W7Y|T6} z1SXx0Wn-|!A;fZGGlYn9a1Jz5^8)~v#mXhmm>um{QiGG459N}L<&qyD+sy_ixD@AP zW0XV6w#3(JW>TEV}MD=O0O>k5H>p#&|O zD2mGf0Cz7+>l7`NuzGobt;(o@vb9YiOpHN8QJ9Uva|i7R?7nnq;L_iq+ZqPv*oGu! zN@GuJ9fm;yrEFga63m?1qy|5&fd32<%$yP$llh}Udrp>~fb>M>R55I@BsGYhCj8m1 zC=ziFh4@hoytpfrJlr}FsV|C(aV4PZ^8^`G29(+!Bk8APa#PemJqkF zE{IzwPaE)I&r`OxGk*vPErm6sGKaQJ&6FODW$;gAl_4b_j!oH4yE@ zP~Cl4?kp>Ccc~Nm+0kjIb`U0N7}zrQEN5!Ju|}t}LeXi!baZOyhlWha5lq{Ld2rdo zGz7hAJQt<6^cxXTe0xZjmADL85cC&H+~Lt2siIIh{$~+U#&#^{Ub22IA|ea6 z5j12XLc`~dh$$1>3o0Cgvo*ybi$c*z>n=5L&X|>Wy1~eagk;lcEnf^2^2xB=e58Z` z@Rw{1ssK)NRV+2O6c<8qFl%efHE;uy!mq(Xi1P*H2}LMi z3EqWN2U?eW{J$lSFxDJg-=&RH!=6P9!y|S~gmjg)gPKGMxq6r9cNIhW` zS})-obO}Ao_`;=>@fAwU&=|5$J;?~!s4LN2&XiMXEl>zk9M}tVEg#kkIkbKp%Ig2QJ2aCILCM1E=aN*iuz>;q#T_I7aVM=E4$m_#OWLnXQnFUnu?~(X>$@NP zBJ@Zw>@bmErSuW7SR2=6535wh-R`WZ+5dLqwTvw}Ks8~4F#hh0$Qn^l-z=;>D~St( z-1yEjCCgd*z5qXa*bJ7H2Tk54KiX&=Vd}z?%dcc z`N8oeYUKe17&|B5A-++RHh8WQ%;gN{vf%05@jZF%wn1Z_yk#M~Cn(i@MB_mpcbLj5 zR#QAtC`k=tZ*h|){Mjz`7bNL zGWOW=bjQhX@`Vw^xn#cVwn28c2D9vOb0TLLy~-?-%gOyHSeJ9a>P}5OF5$n}k-pvUa*pvLw)KvG~>QjNWS3LY1f*OkFwPZ5qC@+3^Bt=HZbf`alKY#{pn zdY}NEIgo1sd)^TPxVzO{uvU$|Z-jkK0p1x##LexgQ$zx1^bNPOG*u2RmZkIM!zFVz zz|IsP3I?qrlmjGS2w_(azCvGTnf~flqogV@Q%mH{76uLU(>UB zQZ?*ys3BO&TV{Pj_qEa-hkH7mOMe_Bnu3%CXCgu90XNKf$N)PUc3Ei-&~@tT zI^49Lm^+=TrI=h4h=W@jW{GjWd{_kVuSzAL6Pi@HKYYnnNbtcYdIRww+jY$(30=#p8*if(mzbvau z00#}4Qf+gH&ce_&8y3Z@CZV>b%&Zr7xuPSSqOmoaP@arwPrMx^jQBQQi>YvBUdpBn zI``MZ3I3HLqp)@vk^E|~)zw$0$VI_RPsL9u(kqulmS`tnb%4U)hm{)h@bG*jw@Y*#MX;Th1wu3TrO}Srn_+YWYesEgkO1 zv?P8uWB)is;#&=xBBLf+y5e4?%y>_8$1KwkAJ8UcW|0CIz89{LydfJKr^RF=JFPi}MAv|ecbuZ!YcTSxsD$(Pr#W*oytl?@+2 zXBFb32Kf_G3~EgOS7C`8w!tx}DcCT%+#qa76VSbnHo;4(oJ7)}mm?b5V65ir`7Z}s zR2)m15b#E}z_2@rf34wo!M^CnVoi# ze+S(IK({C6u=Sm{1>F~?)8t&fZpOOPcby;I3jO;7^xmLKM(<%i-nyj9mgw9F1Lq4|DZUHZ4)V9&6fQM(ZxbG{h+}(koiTu`SQw6#6q2Yg z-d+1+MRp$zYT2neIR2cKij2!R;C~ooQ3<;^8)_Gch&ZyEtiQwmF0Mb_)6)4lVEBF< zklXS7hvtu30uJR`3OzcqUNOdYsfrKSGkIQAk|4=&#ggxdU4^Y(;)$8}fQ>lTgQdJ{ zzie8+1$3@E;|a`kzuFh9Se}%RHTmBg)h$eH;gttjL_)pO^10?!bNev6{mLMaQpY<< z7M^ZXrg>tw;vU@9H=khbff?@nu)Yw4G% zGxobPTUR2p_ed7Lvx?dkrN^>Cv$Axuwk;Wj{5Z@#$sK@f4{7SHg%2bpcS{(~s;L(mz@9r$cK@m~ef&vf%1@ z@8&@LLO2lQso|bJD6}+_L1*D^}>oqg~$NipL>QlP3 zM#ATSy@ycMkKs5-0X8nFAtMhO_=$DlWR+@EaZ}`YduRD4A2@!at3NYRHmlENea9IF zN*s>mi?zy*Vv+F+&4-o`Wj}P3mLGM*&M(z|;?d82>hQkkY?e-hJ47mWOLCPL*MO04 z3lE(n2RM=IIo;Z?I=sKJ_h=iJHbQ2<}WW0b@I6Qf-{T=Qn#@N0yG5xH&ofEy^mZMPzd22nR`t!Q)VkNgf*VOxE z$XhOunG3ZN#`Ks$Hp~}`OX5vmHP={GYUJ+-g0%PS$*Qi5+-40M47zJ24vK1#? zb$s^%r?+>#lw$mpZaMa1aO%wlPm3~cno_(S%U&-R;6eK(@`CjswAW2)HfZ>ptItaZ|XqQ z&sHVVL>WCe|E4iPb2~gS5ITs6xfg(kmt&3$YcI=zTuqj37t|+9ojCr(G^ul#p{>k) zM94pI>~5VZ$!*Qurq<@RIXgP3sx-2kL$1Q~da%rnNIh?)&+c~*&e~CYPDhPYjb+Xu zKg5w^XB3(_9{Waa4E(-J-Kq_u6t_k?a8kEHqai-N-4#`SRerO!h}!cS%SMC<)tGix zOzVP^_t!HN&HIPL-ZpcgWitHM&yFRC7!k4zSI+-<_uQ}|tX)n{Ib;X>Xx>i_d*KkH zCzogKQFpP1408_2!ofU|iBq2R8hW6G zuqJs9Tyw{u%-uWczPLkM!MfKfflt+NK9Vk8E!C>AsJwNDRoe2~cL+UvqNP|5J8t)( z0$iMa!jhudJ+fqFn+um&@Oj6qXJd_3-l`S^I1#0fnt!z3?D*hAHr*u(*wR@`4O z#avrtg%s`Fh{?$FtBFM^$@@hW!8ZfF4;=n0<8In&X}-Rp=cd0TqT_ne46$j^r}FzE z26vX^!PzScuQfFfl1HEZ{zL?G88mcc76zHGizWiykBf4m83Z${So-+dZ~YGhm*RO7 zB1gdIdqnFi?qw+lPRFW5?}CQ3Me3G^muvll&4iN+*5#_mmIu;loULMwb4lu9U*dFM z-Sr**(0Ei~u=$3<6>C-G6z4_LNCx||6YtjS)<;hf)YJTPKXW+w%hhCTUAInIse9>r zl2YU6nRb$u-FJlWN*{{%sm_gi_UP5{=?5}5^D2vPzM=oPfNw~azZQ#P zl5z8RtSSiTIpEohC15i-Q1Bk{3&ElsD0uGAOxvbk29VUDmmA0w;^v`W#0`};O3DVE z&+-ca*`YcN%z*#VXWK9Qa-OEME#fykF%|7o=1Y+eF;Rtv0W4~kKRDx9YBHOWhC%^I z$Jec0cC7o37}Xt}cu)NH5R}NT+=2Nap*`^%O)vz?+{PV<2~qX%TzdJOGeKj5_QjqR&a3*K@= P-1+_A+?hGkL;m(J7kc&K literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..28c6bf03016f6c994b70f38d1b7346e5831b531f GIT binary patch literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f091b6b0bca859a3f474b03065bef75ba58a9e4c GIT binary patch literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ef06e7edb86cdfe0d15b4b0d98334a86163658 GIT binary patch literal 1716 zcmds$`#;kQ7{|XelZftyR5~xW7?MLxS4^|Hw3&P7^y)@A9Fj{Xm1~_CIV^XZ%SLBn zA;!r`GqGHg=7>xrB{?psZQs88ZaedDoagm^KF{a*>G|dJWRSe^I$DNW008I^+;Kjt z>9p3GNR^I;v>5_`+91i(*G;u5|L+Bu6M=(afLjtkya#yZ175|z$pU~>2#^Z_pCZ7o z1c6UNcv2B3?; zX%qdxCXQpdKRz=#b*q0P%b&o)5ZrNZt7$fiETSK_VaY=mb4GK`#~0K#~9^ zcY!`#Af+4h?UMR-gMKOmpuYeN5P*RKF!(tb`)oe0j2BH1l?=>y#S5pMqkx6i{*=V9JF%>N8`ewGhRE(|WohnD59R^$_36{4>S zDFlPC5|k?;SPsDo87!B{6*7eqmMdU|QZ84>6)Kd9wNfh90=y=TFQay-0__>=<4pk& zYDjgIhL-jQ9o>z32K)BgAH+HxamL{ZL~ozu)Qqe@a`FpH=oQRA8=L-m-1dam(Ix2V z?du;LdMO+ooBelr^_y4{|44tmgH^2hSzPFd;U^!1p>6d|o)(-01z{i&Kj@)z-yfWQ)V#3Uo!_U}q3u`(fOs`_f^ueFii1xBNUB z6MecwJN$CqV&vhc+)b(p4NzGGEgwWNs z@*lUV6LaduZH)4_g!cE<2G6#+hJrWd5(|p1Z;YJ7ifVHv+n49btR}dq?HHDjl{m$T z!jLZcGkb&XS2OG~u%&R$(X+Z`CWec%QKt>NGYvd5g20)PU(dOn^7%@6kQb}C(%=vr z{?RP(z~C9DPnL{q^@pVw@|Vx~@3v!9dCaBtbh2EdtoNHm4kGxp>i#ct)7p|$QJs+U z-a3qtcPvhihub?wnJqEt>zC@)2suY?%-96cYCm$Q8R%-8$PZYsx3~QOLMDf(piXMm zB=<63yQk1AdOz#-qsEDX>>c)EES%$owHKue;?B3)8aRd}m~_)>SL3h2(9X;|+2#7X z+#2)NpD%qJvCQ0a-uzZLmz*ms+l*N}w)3LRQ*6>|Ub-fyptY(keUxw+)jfwF5K{L9 z|Cl_w=`!l_o><384d&?)$6Nh(GAm=4p_;{qVn#hI8lqewW7~wUlyBM-4Z|)cZr?Rh z=xZ&Ol>4(CU85ea(CZ^aO@2N18K>ftl8>2MqetAR53_JA>Fal`^)1Y--Am~UDa4th zKfCYpcXky$XSFDWBMIl(q=Mxj$iMBX=|j9P)^fDmF(5(5$|?Cx}DKEJa&XZP%OyE`*GvvYQ4PV&!g2|L^Q z?YG}tx;sY@GzMmsY`7r$P+F_YLz)(e}% zyakqFB<6|x9R#TdoP{R$>o7y(-`$$p0NxJ6?2B8tH)4^yF(WhqGZlM3=9Ibs$%U1w zWzcss*_c0=v_+^bfb`kBFsI`d;ElwiU%frgRB%qBjn@!0U2zZehBn|{%uNIKBA7n= zzE`nnwTP85{g;8AkYxA68>#muXa!G>xH22D1I*SiD~7C?7Za+9y7j1SHiuSkKK*^O zsZ==KO(Ua#?YUpXl{ViynyT#Hzk=}5X$e04O@fsMQjb}EMuPWFO0e&8(2N(29$@Vd zn1h8Yd>6z(*p^E{c(L0Lg=wVdupg!z@WG;E0k|4a%s7Up5C0c)55XVK*|x9RQeZ1J@1v9MX;>n34(i>=YE@Iur`0Vah(inE3VUFZNqf~tSz{1fz3Fsn_x4F>o(Yo;kpqvBe-sbwH(*Y zu$JOl0b83zu$JMvy<#oH^Wl>aWL*?aDwnS0iEAwC?DK@aT)GHRLhnz2WCvf3Ba;o=aY7 z2{Asu5MEjGOY4O#Ggz@@J;q*0`kd2n8I3BeNuMmYZf{}pg=jTdTCrIIYuW~luKecn z+E-pHY%ohj@uS0%^ z&(OxwPFPD$+#~`H?fMvi9geVLci(`K?Kj|w{rZ9JgthFHV+=6vMbK~0)Ea<&WY-NC zy-PnZft_k2tfeQ*SuC=nUj4H%SQ&Y$gbH4#2sT0cU0SdFs=*W*4hKGpuR1{)mV;Qf5pw4? zfiQgy0w3fC*w&Bj#{&=7033qFR*<*61B4f9K%CQvxEn&bsWJ{&winp;FP!KBj=(P6 z4Z_n4L7cS;ao2)ax?Tm|I1pH|uLpDSRVghkA_UtFFuZ0b2#>!8;>-_0ELjQSD-DRd z4im;599VHDZYtnWZGAB25W-e(2VrzEh|etsv2YoP#VbIZ{aFkwPrzJ#JvCvA*mXS& z`}Q^v9(W4GiSs}#s7BaN!WA2bniM$0J(#;MR>uIJ^uvgD3GS^%*ikdW6-!VFUU?JV zZc2)4cMsX@j z5HQ^e3BUzOdm}yC-xA%SY``k$rbfk z;CHqifhU*jfGM@DkYCecD9vl*qr58l6x<8URB=&%{!Cu3RO*MrKZ4VO}V6R0a zZw3Eg^0iKWM1dcTYZ0>N899=r6?+adUiBKPciJw}L$=1f4cs^bio&cr9baLF>6#BM z(F}EXe-`F=f_@`A7+Q&|QaZ??Txp_dB#lg!NH=t3$G8&06MFhwR=Iu*Im0s_b2B@| znW>X}sy~m#EW)&6E&!*0%}8UAS)wjt+A(io#wGI@Z2S+Ms1Cxl%YVE800007ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f9ed8f5cee1c98386d13b17e89f719e83555b2 GIT binary patch literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..75b2d164a5a98e212cca15ea7bf2ab5de5108680 GIT binary patch literal 3831 zcmVjJBgitF5mAp-i>4+KS_oR{|13AP->1TD4=w)g|)JHOx|a2Wk1Va z!k)vP$UcQ#mdj%wNQoaJ!w>jv_6&JPyutpQps?s5dmDQ>`%?Bvj>o<%kYG!YW6H-z zu`g$@mp`;qDR!51QaS}|ZToSuAGcJ7$2HF0z`ln4t!#Yg46>;vGG9N9{V@9z#}6v* zfP?}r6b{*-C*)(S>NECI_E~{QYzN5SXRmVnP<=gzP+_Sp(Aza_hKlZ{C1D&l*(7IKXxQC1Z9#6wx}YrGcn~g%;icdw>T0Rf^w0{ z$_wn1J+C0@!jCV<%Go5LA45e{5gY9PvZp8uM$=1}XDI+9m7!A95L>q>>oe0$nC->i zeexUIvq%Uk<-$>DiDb?!In)lAmtuMWxvWlk`2>4lNuhSsjAf2*2tjT`y;@d}($o)S zn(+W&hJ1p0xy@oxP%AM15->wPLp{H!k)BdBD$toBpJh+crWdsNV)qsHaqLg2_s|Ih z`8E9z{E3sA!}5aKu?T!#enD(wLw?IT?k-yWVHZ8Akz4k5(TZJN^zZgm&zM28sfTD2BYJ|Fde3Xzh;;S` z=GXTnY4Xc)8nYoz6&vF;P7{xRF-{|2Xs5>a5)@BrnQ}I(_x7Cgpx#5&Td^4Q9_FnQ zX5so*;#8-J8#c$OlA&JyPp$LKUhC~-e~Ij!L%uSMu!-VZG7Hx-L{m2DVR2i=GR(_% zCVD!4N`I)&Q5S`?P&fQZ=4#Dgt_v2-DzkT}K(9gF0L(owe-Id$Rc2qZVLqI_M_DyO z9@LC#U28_LU{;wGZ&))}0R2P4MhajKCd^K#D+JJ&JIXZ_p#@+7J9A&P<0kdRujtQ_ zOy>3=C$kgi6$0pW06KaLz!21oOryKM3ZUOWqppndxfH}QpgjEJ`j7Tzn5bk6K&@RA?vl##y z$?V~1E(!wB5rH`>3nc&@)|#<1dN2cMzzm=PGhQ|Yppne(C-Vlt450IXc`J4R0W@I7 zd1e5uW6juvO%ni(WX7BsKx3MLngO7rHO;^R5I~0^nE^9^E_eYLgiR9&KnJ)pBbfno zSVnW$0R+&6jOOsZ82}nJ126+c|%svPo;TeUku<2G7%?$oft zyaO;tVo}(W)VsTUhq^XmFi#2z%-W9a{7mXn{uzivYQ_d6b7VJG{77naW(vHt-uhnY zVN#d!JTqVh(7r-lhtXVU6o})aZbDt_;&wJVGl2FKYFBFpU-#9U)z#(A%=IVnqytR$SY-sO( z($oNE09{D^@OuYPz&w~?9>Fl5`g9u&ecFGhqX=^#fmR=we0CJw+5xna*@oHnkahk+ z9aWeE3v|An+O5%?4fA&$Fgu~H_YmqR!yIU!bFCk4!#pAj%(lI(A5n)n@Id#M)O9Yx zJU9oKy{sRAIV3=5>(s8n{8ryJ!;ho}%pn6hZKTKbqk=&m=f*UnK$zW3YQP*)pw$O* zIfLA^!-bmBl6%d_n$#tP8Zd_(XdA*z*WH|E_yILwjtI~;jK#v-6jMl^?<%Y%`gvpwv&cFb$||^v4D&V=aNy?NGo620jL3VZnA%s zH~I|qPzB~e(;p;b^gJr7Ure#7?8%F0m4vzzPy^^(q4q1OdthF}Fi*RmVZN1OwTsAP zn9CZP`FazX3^kG(KodIZ=Kty8DLTy--UKfa1$6XugS zk%6v$Kmxt6U!YMx0JQ)0qX*{CXwZZk$vEROidEc7=J-1;peNat!vS<3P-FT5po>iE z!l3R+<`#x|+_hw!HjQGV=8!q|76y8L7N8gP3$%0kfush|u0uU^?dKBaeRSBUpOZ0c z62;D&Mdn2}N}xHRFTRI?zRv=>=AjHgH}`2k4WK=#AHB)UFrR-J87GgX*x5fL^W2#d z=(%K8-oZfMO=i{aWRDg=FX}UubM4eotRDcn;OR#{3q=*?3mE3_oJ-~prjhxh%PgQT zyn)Qozaq0@o&|LEgS{Ind4Swsr;b`u185hZPOBLL<`d2%^Yp1?oL)=jnLi;Zo0ZDliTtQ^b5SmfIMe{T==zZkbvn$KTQGlbG8w}s@M3TZnde;1Am46P3juKb zl9GU&3F=q`>j!`?SyH#r@O59%@aMX^rx}Nxe<>NqpUp5=lX1ojGDIR*-D^SDuvCKF z?3$xG(gVUsBERef_YjPFl^rU9EtD{pt z0CXwpN7BN3!8>hajGaTVk-wl=9rxmfWtIhC{mheHgStLi^+Nz12a?4r(fz)?3A%at zMlvQmL<2-R)-@G1wJ0^zQK%mR=r4d{Y3fHp){nWXUL#|CqXl(+v+qDh>FkF9`eWrW zfr^D%LNfOcTNvtx0JXR35J0~Jpi2#P3Q&80w+nqNfc}&G0A~*)lGHKv=^FE+b(37|)zL;KLF>oiGfb(?&1 zV3XRu!Sw>@quKiab%g6jun#oZ%!>V#A%+lNc?q>6+VvyAn=kf_6z^(TZUa4Eelh{{ zqFX-#dY(EV@7l$NE&kv9u9BR8&Ojd#ZGJ6l8_BW}^r?DIS_rU2(XaGOK z225E@kH5Opf+CgD^{y29jD4gHbGf{1MD6ggQ&%>UG4WyPh5q_tb`{@_34B?xfSO*| zZv8!)q;^o-bz`MuxXk*G^}(6)ACb@=Lfs`Hxoh>`Y0NE8QRQ!*p|SH@{r8=%RKd4p z+#Ty^-0kb=-H-O`nAA3_6>2z(D=~Tbs(n8LHxD0`R0_ATFqp-SdY3(bZ3;VUM?J=O zKCNsxsgt@|&nKMC=*+ZqmLHhX1KHbAJs{nGVMs6~TiF%Q)P@>!koa$%oS zjXa=!5>P`vC-a}ln!uH1ooeI&v?=?v7?1n~P(wZ~0>xWxd_Aw;+}9#eULM7M8&E?Y zC-ZLhi3RoM92SXUb-5i-Lmt5_rfjE{6y^+24`y$1lywLyHO!)Boa7438K4#iLe?rh z2O~YGSgFUBH?og*6=r9rme=peP~ah`(8Zt7V)j5!V0KPFf_mebo3z95U8(up$-+EA^9dTRLq>Yl)YMBuch9%=e5B`Vnb>o zt03=kq;k2TgGe4|lGne&zJa~h(UGutjP_zr?a7~#b)@15XNA>Dj(m=gg2Q5V4-$)D|Q9}R#002ovPDHLkV1o7DH3k3x literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c4df70d39da7941ef3f6dcb7f06a192d8dcb308d GIT binary patch literal 1888 zcmV-m2cP(fP)x~L`~4d)Rspd&<9kFh{hn*KP1LP0~$;u(LfAu zp%fx&qLBcRHx$G|3q(bv@+b;o0*D|jwD-Q9uQR(l*ST}s+uPgQ-MeFwZ#GS?b332? z&Tk$&_miXn3IGq)AmQ)3sisq{raD4(k*bHvpCe-TdWq^NRTEVM)i9xbgQ&ccnUVx* zEY%vS%gDcSg=!tuIK8$Th2_((_h^+7;R|G{n06&O2#6%LK`a}n?h_fL18btz<@lFG za}xS}u?#DBMB> zw^b($1Z)`9G?eP95EKi&$eOy@K%h;ryrR3la%;>|o*>CgB(s>dDcNOXg}CK9SPmD? zmr-s{0wRmxUnbDrYfRvnZ@d z6johZ2sMX{YkGSKWd}m|@V7`Degt-43=2M?+jR%8{(H$&MLLmS;-|JxnX2pnz;el1jsvqQz}pGSF<`mqEXRQ5sC4#BbwnB_4` zc5bFE-Gb#JV3tox9fp-vVEN{(tOCpRse`S+@)?%pz+zVJXSooTrNCUg`R6`hxwb{) zC@{O6MKY8tfZ5@!yy=p5Y|#+myRL=^{tc(6YgAnkg3I(Cd!r5l;|;l-MQ8B`;*SCE z{u)uP^C$lOPM z5d~UhKhRRmvv{LIa^|oavk1$QiEApSrP@~Jjbg`<*dW4TO?4qG%a%sTPUFz(QtW5( zM)lA+5)0TvH~aBaOAs|}?u2FO;yc-CZ1gNM1dAxJ?%m?YsGR`}-xk2*dxC}r5j$d* zE!#Vtbo69h>V4V`BL%_&$} z+oJAo@jQ^Tk`;%xw-4G>hhb&)B?##U+(6Fi7nno`C<|#PVA%$Y{}N-?(Gc$1%tr4Pc}}hm~yY#fTOe!@v9s-ik$dX~|ygArPhByaXn8 zpI^FUjNWMsTFKTP3X7m?UK)3m zp6rI^_zxRYrx6_QmhoWoDR`fp4R7gu6;gdO)!KexaoO2D88F9x#TM1(9Bn7g;|?|o z)~$n&Lh#hCP6_LOPD>a)NmhW})LADx2kq=X7}7wYRj-0?dXr&bHaRWCfSqvzFa=sn z-8^gSyn-RmH=BZ{AJZ~!8n5621GbUJV7Qvs%JNv&$%Q17s_X%s-41vAPfIR>;x0Wlqr5?09S>x#%Qkt>?(&XjFRY}*L6BeQ3 z<6XEBh^S7>AbwGm@XP{RkeEKj6@_o%oV?hDuUpUJ+r#JZO?!IUc;r0R?>mi)*ZpQ) z#((dn=A#i_&EQn|hd)N$#A*fjBFuiHcYvo?@y1 z5|fV=a^a~d!c-%ZbMNqkMKiSzM{Yq=7_c&1H!mXk60Uv32dV;vMg&-kQ)Q{+PFtwc zj|-uQ;b^gts??J*9VxxOro}W~Q9j4Em|zSRv)(WSO9$F$s=Ydu%Q+5DOid~lwk&we zY%W(Z@ofdwPHncEZzZgmqS|!gTj3wQq9rxQy+^eNYKr1mj&?tm@wkO*9@UtnRMG>c aR{jt9+;fr}hV%pg00001^@s67{VYS000c7NklQEG_j zup^)eW&WUIApqy$=APz8jE@awGp)!bsTjDbrJO`$x^ZR^dr;>)LW>{ zs70vpsD38v)19rI=GNk1b(0?Js9~rjsQsu*K;@SD40RB-3^gKU-MYC7G!Bw{fZsqp zih4iIi;Hr_xZ033Iu{sQxLS=}yBXgLMn40d++>aQ0#%8D1EbGZp7+ z5=mK?t31BkVYbGOxE9`i748x`YgCMwL$qMsChbSGSE1`p{nSmadR zcQ#R)(?!~dmtD0+D2!K zR9%!Xp1oOJzm(vbLvT^$IKp@+W2=-}qTzTgVtQ!#Y7Gxz}stUIm<1;oBQ^Sh2X{F4ibaOOx;5ZGSNK z0maF^@(UtV$=p6DXLgRURwF95C=|U8?osGhgOED*b z7woJ_PWXBD>V-NjQAm{~T%sjyJ{5tn2f{G%?J!KRSrrGvQ1(^`YLA5B!~eycY(e5_ z*%aa{at13SxC(=7JT7$IQF~R3sy`Nn%EMv!$-8ZEAryB*yB1k&stni)=)8-ODo41g zkJu~roIgAih94tb=YsL%iH5@^b~kU9M-=aqgXIrbtxMpFy5mekFm#edF9z7RQ6V}R zBIhbXs~pMzt0VWy1Fi$^fh+1xxLDoK09&5&MJl(q#THjPm(0=z2H2Yfm^a&E)V+a5 zbi>08u;bJsDRUKR9(INSc7XyuWv(JsD+BB*0hS)FO&l&7MdViuur@-<-EHw>kHRGY zqoT}3fDv2-m{NhBG8X}+rgOEZ;amh*DqN?jEfQdqxdj08`Sr=C-KmT)qU1 z+9Cl)a1mgXxhQiHVB}l`m;-RpmKy?0*|yl?FXvJkFxuu!fKlcmz$kN(a}i*saM3nr z0!;a~_%Xqy24IxA2rz<+08=B-Q|2PT)O4;EaxP^6qixOv7-cRh?*T?zZU`{nIM-at zTKYWr9rJ=tppQ9I#Z#mLgINVB!pO-^FOcvFw6NhV0gztuO?g ztoA*C-52Q-Z-P#xB4HAY3KQVd%dz1S4PA3vHp0aa=zAO?FCt zC_GaTyVBg2F!bBr3U@Zy2iJgIAt>1sf$JWA9kh{;L+P*HfUBX1Zy{4MgNbDfBV_ly z!y#+753arsZUt@366jIC0klaC@ckuk!qu=pAyf7&QmiBUT^L1&tOHzsK)4n|pmrVT zs2($4=?s~VejTFHbFdDOwG;_58LkIj1Fh@{glkO#F1>a==ymJS$z;gdedT1zPx4Kj ztjS`y_C}%af-RtpehdQDt3a<=W5C4$)9W@QAse;WUry$WYmr51ml9lkeunUrE`-3e zmq1SgSOPNEE-Mf+AGJ$g0M;3@w!$Ej;hMh=v=I+Lpz^n%Pg^MgwyqOkNyu2c^of)C z1~ALor3}}+RiF*K4+4{(1%1j3pif1>sv0r^mTZ?5Jd-It!tfPfiG_p$AY*Vfak%FG z4z#;wLtw&E&?}w+eKG^=#jF7HQzr8rV0mY<1YAJ_uGz~$E13p?F^fPSzXSn$8UcI$ z8er9{5w5iv0qf8%70zV71T1IBB1N}R5Kp%NO0=5wJalZt8;xYp;b{1K) zHY>2wW-`Sl{=NpR%iu3(u6l&)rc%%cSA#aV7WCowfbFR4wcc{LQZv~o1u_`}EJA3>ki`?9CKYTA!rhO)if*zRdd}Kn zEPfYbhoVE~!FI_2YbC5qAj1kq;xP6%J8+?2PAs?`V3}nyFVD#sV3+uP`pi}{$l9U^ zSz}_M9f7RgnnRhaoIJgT8us!1aB&4!*vYF07Hp&}L zCRlop0oK4DL@ISz{2_BPlezc;xj2|I z23RlDNpi9LgTG_#(w%cMaS)%N`e>~1&a3<{Xy}>?WbF>OOLuO+j&hc^YohQ$4F&ze z+hwnro1puQjnKm;vFG~o>`kCeUIlkA-2tI?WBKCFLMBY=J{hpSsQ=PDtU$=duS_hq zHpymHt^uuV1q@uc4bFb{MdG*|VoW@15Osrqt2@8ll0qO=j*uOXn{M0UJX#SUztui9FN4)K3{9!y8PC-AHHvpVTU;x|-7P+taAtyglk#rjlH2 z5Gq8ik}BPaGiM{#Woyg;*&N9R2{J0V+WGB69cEtH7F?U~Kbi6ksi*`CFXsi931q7Y zGO82?whBhN%w1iDetv%~wM*Y;E^)@Vl?VDj-f*RX>{;o_=$fU!&KAXbuadYZ46Zbg z&6jMF=49$uL^73y;;N5jaHYv)BTyfh&`qVLYn?`o6BCA_z-0niZz=qPG!vonK3MW_ zo$V96zM!+kJRs{P-5-rQVse0VBH*n6A58)4uc&gfHMa{gIhV2fGf{st>E8sKyP-$8zp~wJX^A*@DI&-;8>gANXZj zU)R+Y)PB?=)a|Kj>8NXEu^S_h^7R`~Q&7*Kn!xyvzVv&^>?^iu;S~R2e-2fJx-oUb cX)(b1KSk$MOV07*qoM6N<$f&6$jw%VRuvdN2+38CZWny1cRtlsl+0_KtW)EU14Ei(F!UtWuj4IK+3{sK@>rh zs1Z;=(DD&U6+tlyL?UnHVN^&g6QhFi2#HS+*qz;(>63G(`|jRtW|nz$Pv7qTovP!^ zP_jES{mr@O-02w%!^a?^1ZP!_KmQiz0L~jZ=W@Qt`8wzOoclQsAS<5YdH;a(4bGLE zk8s}1If(PSIgVi!XE!5kA?~z*sobvNyohr;=Q_@h2@$6Flyej3J)D-6YfheRGl`HEcPk|~huT_2-U?PfL=4BPV)f1o!%rQ!NMt_MYw-5bUSwQ9Z&zC>u zOrl~UJglJNa%f50Ok}?WB{on`Ci`p^Y!xBA?m@rcJXLxtrE0FhRF3d*ir>yzO|BD$ z3V}HpFcCh6bTzY}Nt_(W%QYd3NG)jJ4<`F<1Od) zfQblTdC&h2lCz`>y?>|9o2CdvC8qZeIZt%jN;B7Hdn2l*k4M4MFEtq`q_#5?}c$b$pf_3y{Y!cRDafZBEj-*OD|gz#PBDeu3QoueOesLzB+O zxjf2wvf6Wwz>@AiOo2mO4=TkAV+g~%_n&R;)l#!cBxjuoD$aS-`IIJv7cdX%2{WT7 zOm%5rs(wqyPE^k5SIpUZ!&Lq4<~%{*>_Hu$2|~Xa;iX*tz8~G6O3uFOS?+)tWtdi| zV2b#;zRN!m@H&jd=!$7YY6_}|=!IU@=SjvGDFtL;aCtw06U;-v^0%k0FOyESt z1Wv$={b_H&8FiRV?MrzoHWd>%v6KTRU;-v^Miiz+@q`(BoT!+<37CKhoKb)|8!+RG z6BQFU^@fRW;s8!mOf2QViKQGk0TVER6EG1`#;Nm39Do^PoT!+<37AD!%oJe86(=et zZ~|sLzU>V-qYiU6V8$0GmU7_K8|Fd0B?+9Un1BhKAz#V~Fk^`mJtlCX#{^8^M8!me z8Yg;8-~>!e<-iG;h*0B1kBKm}hItVGY6WnjVpgnTTAC$rqQ^v)4KvOtpY|sIj@WYg zyw##ZZ5AC2IKNC;^hwg9BPk0wLStlmBr;E|$5GoAo$&Ui_;S9WY62n3)i49|T%C#i017z3J=$RF|KyZWnci*@lW4 z=AKhNN6+m`Q!V3Ye68|8y@%=am>YD0nG99M)NWc20%)gwO!96j7muR}Fr&54SxKP2 zP30S~lt=a*qDlbu3+Av57=9v&vr<6g0&`!8E2fq>I|EJGKs}t|{h7+KT@)LfIV-3K zK)r_fr2?}FFyn*MYoLC>oV-J~eavL2ho4a4^r{E-8m2hi>~hA?_vIG4a*KT;2eyl1 zh_hUvUJpNCFwBvRq5BI*srSle>c6%n`#VNsyC|MGa{(P&08p=C9+WUw9Hl<1o9T4M zdD=_C0F7#o8A_bRR?sFNmU0R6tW`ElnF8p53IdHo#S9(JoZCz}fHwJ6F<&?qrpVqE zte|m%89JQD+XwaPU#%#lVs-@-OL);|MdfINd6!XwP2h(eyafTUsoRkA%&@fe?9m@jw-v(yTTiV2(*fthQH9}SqmsRPVnwwbV$1E(_lkmo&S zF-truCU914_$jpqjr(>Ha4HkM4YMT>m~NosUu&UZ>zirfHo%N6PPs9^_o$WqPA0#5 z%tG>qFCL+b*0s?sZ;Sht0nE7Kl>OVXy=gjWxxK;OJ3yGd7-pZf7JYNcZo2*1SF`u6 zHJyRRxGw9mDlOiXqVMsNe#WX`fC`vrtjSQ%KmLcl(lC>ZOQzG^%iql2w-f_K@r?OE zwCICifM#L-HJyc7Gm>Ern?+Sk3&|Khmu4(~3qa$(m6Ub^U0E5RHq49za|XklN#?kP zl;EstdW?(_4D>kwjWy2f!LM)y?F94kyU3`W!6+AyId-89v}sXJpuic^NLL7GJItl~ zsiuB98AI-(#Mnm|=A-R6&2fwJ0JVSY#Q>&3$zFh|@;#%0qeF=j5Ajq@4i0tIIW z&}sk$&fGwoJpe&u-JeGLi^r?dO`m=y(QO{@h zQqAC7$rvz&5+mo3IqE?h=a~6m>%r5Quapvzq;{y~p zJpyXOBgD9VrW7@#p6l7O?o3feml(DtSL>D^R) zZUY%T2b0-vBAFN7VB;M88!~HuOXi4KcI6aRQ&h|XQ0A?m%j2=l1f0cGP}h(oVfJ`N zz#PpmFC*ieab)zJK<4?^k=g%OjPnkANzbAbmGZHoVRk*mTfm75s_cWVa`l*f$B@xu z5E*?&@seIo#*Y~1rBm!7sF9~~u6Wrj5oICUOuz}CS)jdNIznfzCA(stJ(7$c^e5wN z?lt>eYgbA!kvAR7zYSD&*r1$b|(@;9dcZ^67R0 zXAXJKa|5Sdmj!g578Nwt6d$sXuc&MWezA0Whd`94$h{{?1IwXP4)Tx4obDK%xoFZ_Z zjjHJ_P@R_e5blG@yEjnaJb`l;s%Lb2&=8$&Ct-fV`E^4CUs)=jTk!I}2d&n!f@)bm z@ z_4Dc86+3l2*p|~;o-Sb~oXb_RuLmoifDU^&Te$*FevycC0*nE3Xws8gsWp|Rj2>SM zns)qcYj?^2sd8?N!_w~4v+f-HCF|a$TNZDoNl$I1Uq87euoNgKb6&r26TNrfkUa@o zfdiFA@p{K&mH3b8i!lcoz)V{n8Q@g(vR4ns4r6w;K z>1~ecQR0-<^J|Ndg5fvVUM9g;lbu-){#ghGw(fg>L zh)T5Ljb%lWE;V9L!;Cqk>AV1(rULYF07ZBJbGb9qbSoLAd;in9{)95YqX$J43-dY7YU*k~vrM25 zxh5_IqO0LYZW%oxQ5HOzmk4x{atE*vipUk}sh88$b2tn?!ujEHn`tQLe&vo}nMb&{ zio`xzZ&GG6&ZyN3jnaQy#iVqXE9VT(3tWY$n-)uWDQ|tc{`?fq2F`oQ{;d3aWPg4Hp-(iE{ry>MIPWL> iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000000..89c2725b70f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Base.lproj/LaunchScreen.storyboard b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000000..f2e259c7c93 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Base.lproj/Main.storyboard b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000000..f3c28516fb3 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Info.plist b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Info.plist new file mode 100644 index 00000000000..6cf663a1898 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + app_boilerplate + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/main.m b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/main.m new file mode 100644 index 00000000000..dff6597e451 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/add_task.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/add_task.dart new file mode 100644 index 00000000000..1680f8a2a35 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/add_task.dart @@ -0,0 +1,46 @@ +import 'package:app_boilerplate/components/custom_button.dart'; + +import 'package:flutter/material.dart'; + +class AddTask extends StatelessWidget { + //final TodoList todoList; + final Function onAdd; + const AddTask({Key key, this.onAdd}) : super(key: key); + + @override + Widget build(BuildContext context) { + TextEditingController _controller = TextEditingController(); + return Container( + child: Padding( + padding: const EdgeInsets.all(18.0), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: TextFormField( + controller: _controller, + decoration: InputDecoration( + labelText: "Add task", + border: OutlineInputBorder(), + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: CustomButton( + width: 90, + height: 50, + onTap: () { + onAdd(_controller.text); + _controller.clear(); + FocusScope.of(context).requestFocus(new FocusNode()); + }, + text: "Add", + ), + ) + ], + ), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/custom_button.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/custom_button.dart new file mode 100644 index 00000000000..47aa2ed02e4 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/custom_button.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +class CustomButton extends StatelessWidget { + final Function onTap; + final String text; + final double height; + final double width; + + CustomButton({ + Key key, + @required this.onTap, + @required this.text, + @required this.height, + @required this.width, + }) : super(key: key); + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + width: width, + height: height, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(23), color: Colors.black), + child: Center( + child: Text( + text, + style: TextStyle(color: Colors.white), + ), + ), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/feed_tile.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/feed_tile.dart new file mode 100644 index 00000000000..7e6fa6a3b16 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/feed_tile.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +class FeedTile extends StatelessWidget { + final String username; + final String feed; + + FeedTile({ + Key key, + @required this.username, + @required this.feed, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Card( + child: ListTile( + title: Text(username), + subtitle: Text(feed), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/todo_item_tile.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/todo_item_tile.dart new file mode 100644 index 00000000000..cc67e14de33 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/todo_item_tile.dart @@ -0,0 +1,52 @@ +import 'package:app_boilerplate/model/todo_item.dart'; +import 'package:flutter/material.dart'; + +class TodoItemTile extends StatelessWidget { + final TodoItem item; + final Function delete; + final Function toggleIsCompleted; + TodoItemTile({ + Key key, + @required this.item, + @required this.delete, + @required this.toggleIsCompleted, + }) : super(key: key); + @override + Widget build(BuildContext context) { + return Container( + child: Card( + child: ListTile( + contentPadding: EdgeInsets.all(0), + title: Text(item.task, + style: TextStyle( + decoration: item.isCompleted + ? TextDecoration.lineThrough + : TextDecoration.none)), + leading: InkWell( + onTap: () { + toggleIsCompleted(); + }, + child: Container( + height: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: Icon(!item.isCompleted + ? Icons.radio_button_unchecked + : Icons.radio_button_checked), + ), + ), + trailing: InkWell( + onTap: () { + delete(); + }, + child: Container( + decoration: BoxDecoration( + border: Border(left: BorderSide(color: Colors.grey))), + width: 60, + height: double.infinity, + child: Icon(Icons.delete)), + ), + ), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/utils.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/utils.dart new file mode 100644 index 00000000000..b74bdda1cbd --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/components/utils.dart @@ -0,0 +1,9 @@ +import 'package:flutter/material.dart'; +import 'package:toast/toast.dart'; + +class UtilFs { + static showToast(String message, BuildContext context) { + Toast.show(message, context, + duration: Toast.LENGTH_LONG, gravity: Toast.BOTTOM); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/feed_list.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/feed_list.dart new file mode 100644 index 00000000000..fea14a66b34 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/feed_list.dart @@ -0,0 +1,19 @@ +import 'package:app_boilerplate/model/feed_item.dart'; + +class FeedList { + List list = [ + FeedItem.fromElements("", "user1", "I'm user1"), + FeedItem.fromElements("", "user2", "I'm user2"), + FeedItem.fromElements("", "user3", "I'm user3"), + FeedItem.fromElements("", "user4", "I'm user4"), + FeedItem.fromElements("", "user5", "I'm user5"), + ]; + + addFeed(String id, String username, String feed) { + list.add( + FeedItem.fromElements(id, username, feed), + ); + } +} + +FeedList feedList = new FeedList(); diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/online_list.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/online_list.dart new file mode 100644 index 00000000000..a5ba564851b --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/online_list.dart @@ -0,0 +1,5 @@ +class OnlineList { + List list = ["User1", "User3", "User5"]; +} + +OnlineList onlineList = new OnlineList(); diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/todo_list.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/todo_list.dart new file mode 100644 index 00000000000..b41b8cb2059 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/data/todo_list.dart @@ -0,0 +1,32 @@ +import 'package:app_boilerplate/model/todo_item.dart'; + +class TodoList { + List list = []; + int id = 0; + addTodo(String task) { + id++; + list.add( + TodoItem.fromElements( + id, + task, + false, + ), + ); + } + + removeTodo(int id) { + list.removeWhere((item) => item.id == id); + } + + toggleList(int id) { + int index = list.indexWhere((item) => item.id == id); + list[index].isCompleted = !list[index].isCompleted; + } + + List get activeList => + list.where((item) => item.isCompleted == false).toList(); + List get completeList => + list.where((item) => item.isCompleted == true).toList(); +} + +TodoList todoList = new TodoList(); diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/main.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/main.dart new file mode 100644 index 00000000000..5bbf6e917cd --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/main.dart @@ -0,0 +1,24 @@ +import 'package:app_boilerplate/screens/dashboard.dart'; +import 'package:app_boilerplate/screens/login.dart'; +import 'package:app_boilerplate/screens/signup.dart'; +import 'package:app_boilerplate/screens/splash.dart'; +import 'package:flutter/material.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + final routes = { + "/login": (BuildContext context) => Login(), + "/dashboard": (BuildContext context) => Dashboard(), + "/signup": (BuildContext context) => Signup(), + }; + return MaterialApp( + title: 'Hasura GraphQL Demo', + theme: ThemeData(primaryColor: Colors.black), + routes: routes, + home: Splash(), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/model/feed_item.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/model/feed_item.dart new file mode 100644 index 00000000000..c1b3fd6a5ea --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/model/feed_item.dart @@ -0,0 +1,11 @@ +class FeedItem { + String id = ""; + String username = ""; + String feed = ""; + + FeedItem.fromElements(String id, String username, String feed) { + this.id = id; + this.username = username; + this.feed = feed; + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/model/todo_item.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/model/todo_item.dart new file mode 100644 index 00000000000..81511cfecdf --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/model/todo_item.dart @@ -0,0 +1,19 @@ +class TodoItem { + int id; + String task = ""; + bool isCompleted = false; + TodoItem.fromElements(int id, String task, bool isCompleted) { + this.id = id; + this.task = task; + this.isCompleted = isCompleted; + } + Map toJson() { + Map jsonData = { + "__typename": "todos", + "id": id, + "title": task, + "is_completed": isCompleted, + }; + return jsonData; + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/dashboard.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/dashboard.dart new file mode 100644 index 00000000000..e1757b51e55 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/dashboard.dart @@ -0,0 +1,63 @@ +import 'package:app_boilerplate/screens/tabs/dashboard/feeds.dart'; +import 'package:app_boilerplate/screens/tabs/dashboard/online.dart'; +import 'package:app_boilerplate/screens/tabs/dashboard/todos.dart'; +import 'package:app_boilerplate/services/shared_preferences_service.dart'; +import 'package:flutter/material.dart'; + +class Dashboard extends StatelessWidget { + const Dashboard({Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return DefaultTabController( + length: 3, + child: Scaffold( + appBar: AppBar( + automaticallyImplyLeading: false, + centerTitle: true, + title: Text( + "ToDo App", + ), + actions: [ + IconButton( + icon: Icon(Icons.exit_to_app), + onPressed: () async { + sharedPreferenceService.clearToken(); + Navigator.pushReplacementNamed(context, "/login"); + }, + ), + ], + ), + bottomNavigationBar: new TabBar( + tabs: [ + Tab( + text: "Todos", + icon: new Icon(Icons.edit), + ), + Tab( + text: "Feeds", + icon: new Icon(Icons.message), + ), + Tab( + text: "Online", + icon: new Icon(Icons.people), + ), + ], + labelColor: Colors.black, + unselectedLabelColor: Colors.grey, + indicatorSize: TabBarIndicatorSize.label, + indicatorPadding: EdgeInsets.all(5.0), + indicatorColor: Colors.blue, + ), + body: TabBarView( + physics: NeverScrollableScrollPhysics(), + children: [ + Todos(), + Feeds(), + Online(), + ], + ), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/login.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/login.dart new file mode 100644 index 00000000000..77f499a8647 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/login.dart @@ -0,0 +1,127 @@ +import 'package:app_boilerplate/components/custom_button.dart'; +import 'package:app_boilerplate/components/utils.dart'; +import 'package:app_boilerplate/services/auth.dart'; +import 'package:app_boilerplate/services/shared_preferences_service.dart'; +import 'package:flutter/material.dart'; + +class Login extends StatefulWidget { + Login({Key key}) : super(key: key); + + _LoginState createState() => _LoginState(); +} + +class _LoginState extends State { + TextEditingController emailController = TextEditingController(); + TextEditingController passwordController = TextEditingController(); + final _formKey = GlobalKey(); + String _token = ""; + bool busyView = false; + + @override + Widget build(BuildContext context) { + if (!busyView) { + return Scaffold( + body: Center( + child: Form( + key: _formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + "ToDo App", + style: TextStyle(fontWeight: FontWeight.w800, fontSize: 38), + ), + Container( + width: MediaQuery.of(context).size.width / 1.3, + child: Column( + children: [ + TextFormField( + controller: emailController, + decoration: InputDecoration(labelText: "Email"), + keyboardType: TextInputType.emailAddress, + validator: (value) { + Pattern pattern = + r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'; + RegExp regex = new RegExp(pattern); + if (!regex.hasMatch(value)) + return 'Enter Valid Email'; + else + return null; + }, + ), + TextFormField( + controller: passwordController, + decoration: InputDecoration(labelText: "Password"), + validator: (value) { + return value.length < 4 + ? "Password must be at least 4 characters long" + : null; + }, + obscureText: true, + ), + ], + ), + ), + Column( + children: [ + CustomButton( + width: 180, + height: 50, + onTap: () async { + if (_formKey.currentState.validate()) { + setState(() { + busyView = true; + }); + _token = await hasuraAuth.login( + emailController.text, + passwordController.text, + ); + if (_token != null) { + UtilFs.showToast("Login Successful", context); + await sharedPreferenceService.setToken(_token); + Navigator.pushReplacementNamed( + context, "/dashboard"); + } else { + setState(() { + busyView = false; + }); + UtilFs.showToast("Login Failed", context); + FocusScope.of(context) + .requestFocus(new FocusNode()); + } + } + }, + text: "Login", + ), + Padding( + padding: const EdgeInsets.all(18.0), + child: GestureDetector( + onTap: () { + Navigator.pushNamed(context, "/signup"); + }, + child: Container( + height: 20, + child: Text( + "New? Sign Up", + style: + TextStyle(decoration: TextDecoration.underline), + ), + ), + ), + ) + ], + ) + ], + ), + ), + ), + ); + } else { + return Scaffold( + body: Center( + child: CircularProgressIndicator(), + ), + ); + } + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/signup.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/signup.dart new file mode 100644 index 00000000000..a2e5be52568 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/signup.dart @@ -0,0 +1,106 @@ +import 'package:app_boilerplate/components/custom_button.dart'; +import 'package:app_boilerplate/components/utils.dart'; +import 'package:app_boilerplate/services/auth.dart'; +import 'package:flutter/material.dart'; + +class Signup extends StatefulWidget { + Signup({Key key}) : super(key: key); + + _SignupState createState() => _SignupState(); +} + +class _SignupState extends State { + TextEditingController emailController = TextEditingController(); + TextEditingController passwordController = TextEditingController(); + final _formKey = GlobalKey(); + bool busyView = false; + + @override + Widget build(BuildContext context) { + if (!busyView) { + return Scaffold( + body: Center( + child: Form( + key: _formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + "ToDo App", + style: TextStyle(fontWeight: FontWeight.w800, fontSize: 38), + ), + Container( + width: MediaQuery.of(context).size.width / 1.3, + child: Column( + children: [ + TextFormField( + controller: emailController, + decoration: InputDecoration(labelText: "Email"), + keyboardType: TextInputType.emailAddress, + validator: (value) { + Pattern pattern = + r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'; + RegExp regex = new RegExp(pattern); + if (!regex.hasMatch(value)) + return 'Enter Valid Email'; + else + return null; + }, + ), + TextFormField( + controller: passwordController, + decoration: InputDecoration(labelText: "Password"), + validator: (value) { + return value.length < 4 + ? "Password must be at least 4 characters long" + : null; + }, + obscureText: true, + ), + ], + ), + ), + Column( + children: [ + CustomButton( + width: 180, + height: 50, + onTap: () async { + if (_formKey.currentState.validate()) { + setState(() { + busyView = true; + }); + if (await hasuraAuth.signup( + emailController.text, + passwordController.text, + )) { + UtilFs.showToast("SignUp Successful", context); + Navigator.pop(context); + } else { + FocusScope.of(context) + .requestFocus(new FocusNode()); + UtilFs.showToast("SignUp Failed", context); + } + setState(() { + busyView = false; + }); + } + }, + text: "SignUp", + ), + ], + ) + ], + ), + ), + ), + ); + } else { + return Scaffold( + body: Center( + child: CircularProgressIndicator(), + ), + ); + } + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/splash.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/splash.dart new file mode 100644 index 00000000000..26ae5b56afd --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/splash.dart @@ -0,0 +1,28 @@ +import 'package:app_boilerplate/services/shared_preferences_service.dart'; +import 'package:flutter/material.dart'; + +class Splash extends StatelessWidget { + const Splash({ + Key key, + }) : super(key: key); + + initMethod(context) async { + await sharedPreferenceService.getSharedPreferencesInstance(); + String _token = await sharedPreferenceService.token; + if (_token == null || _token == "") { + Navigator.of(context).pushReplacementNamed('/login'); + } else + Navigator.of(context).pushReplacementNamed('/dashboard'); + } + + @override + Widget build(BuildContext context) { + WidgetsBinding.instance.addPostFrameCallback((_) => initMethod(context)); + + return Scaffold( + body: Center( + child: new CircularProgressIndicator(), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/feeds.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/feeds.dart new file mode 100644 index 00000000000..70d28a7f542 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/feeds.dart @@ -0,0 +1,80 @@ +import 'package:app_boilerplate/components/custom_button.dart'; +import 'package:app_boilerplate/components/feed_tile.dart'; +import 'package:app_boilerplate/data/feed_list.dart'; +import 'package:flutter/material.dart'; + +class Feeds extends StatefulWidget { + const Feeds({Key key}) : super(key: key); + + @override + _FeedsState createState() => _FeedsState(); +} + +class _FeedsState extends State { + TextEditingController _controller = TextEditingController(); + @override + Widget build(BuildContext context) { + print("All tab"); + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(18.0), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: TextFormField( + controller: _controller, + decoration: InputDecoration( + labelText: "Say something ...", + border: OutlineInputBorder(), + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: CustomButton( + width: 90, + height: 50, + onTap: () { + feedList.addFeed("", "You", _controller.text); + _controller.clear(); + FocusScope.of(context).requestFocus(new FocusNode()); + }, + text: "Post", + ), + ) + ], + ), + ), + CustomButton( + onTap: () { + print("loading"); + }, + height: 50, + text: "New Notification", + width: MediaQuery.of(context).size.width / 2, + ), + Expanded( + child: ListView.builder( + itemCount: feedList.list.length, + itemBuilder: (context, index) { + return FeedTile( + username: + feedList.list[feedList.list.length - index - 1].username, + feed: feedList.list[feedList.list.length - index - 1].feed); + }, + ), + ), + CustomButton( + onTap: () { + print("load more"); + }, + height: 50, + text: "Load More", + width: MediaQuery.of(context).size.width / 3, + ) + ], + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/online.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/online.dart new file mode 100644 index 00000000000..a4cd36305b2 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/online.dart @@ -0,0 +1,33 @@ +import 'package:app_boilerplate/data/online_list.dart'; +import 'package:flutter/material.dart'; + +class Online extends StatelessWidget { + const Online({Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: Text( + "Online Users", + style: TextStyle(fontSize: 28), + ), + ), + Expanded( + child: ListView.builder( + itemCount: onlineList.list.length, + itemBuilder: (context, index) { + return Card( + child: ListTile( + title: Text(onlineList.list[index]), + ), + ); + }, + ), + ), + ], + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/todos.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/todos.dart new file mode 100644 index 00000000000..b6c2c2fbd05 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/dashboard/todos.dart @@ -0,0 +1,43 @@ +import 'package:app_boilerplate/screens/tabs/todos/active.dart'; +import 'package:app_boilerplate/screens/tabs/todos/all.dart'; +import 'package:app_boilerplate/screens/tabs/todos/completed.dart'; +import 'package:flutter/material.dart'; + +class Todos extends StatefulWidget { + Todos({Key key}) : super(key: key); + + _TodosState createState() => _TodosState(); +} + +class _TodosState extends State { + @override + Widget build(BuildContext context) { + return DefaultTabController( + length: 3, + child: Scaffold( + appBar: AppBar( + title: TabBar( + tabs: [ + Tab( + text: "All", + ), + Tab( + text: "Active", + ), + Tab( + text: "Completed", + ), + ], + ), + ), + body: TabBarView( + children: [ + All(), + Active(), + Completed(), + ], + ), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/active.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/active.dart new file mode 100644 index 00000000000..315ff490904 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/active.dart @@ -0,0 +1,46 @@ +import 'package:app_boilerplate/components/add_task.dart'; +import 'package:app_boilerplate/components/todo_item_tile.dart'; +import 'package:app_boilerplate/data/todo_list.dart'; +import 'package:flutter/material.dart'; + +class Active extends StatefulWidget { + const Active({Key key}) : super(key: key); + + @override + _ActiveState createState() => _ActiveState(); +} + +class _ActiveState extends State { + @override + Widget build(BuildContext context) { + return Column( + children: [ + AddTask( + onAdd: (value) { + todoList.addTodo(value); + }, + ), + Expanded( + child: ListView.builder( + itemCount: todoList.activeList.length, + itemBuilder: (context, index) { + return TodoItemTile( + item: todoList.activeList[index], + delete: () { + setState(() { + todoList.removeTodo(todoList.activeList[index].id); + }); + }, + toggleIsCompleted: () { + setState(() { + todoList.toggleList(todoList.activeList[index].id); + }); + }, + ); + }, + ), + ), + ], + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/all.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/all.dart new file mode 100644 index 00000000000..8b8c60b50be --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/all.dart @@ -0,0 +1,52 @@ +import 'package:app_boilerplate/components/add_task.dart'; +import 'package:app_boilerplate/components/todo_item_tile.dart'; +import 'package:app_boilerplate/data/todo_list.dart'; +import 'package:flutter/material.dart'; + +class All extends StatefulWidget { + All({Key key}) : super(key: key); + + @override + _AllState createState() => _AllState(); +} + +class _AllState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + print("All tab"); + return Column( + children: [ + AddTask( + onAdd: (value) { + todoList.addTodo(value); + }, + ), + Expanded( + child: ListView.builder( + itemCount: todoList.list.length, + itemBuilder: (context, index) { + return TodoItemTile( + item: todoList.list[index], + delete: () { + setState(() { + todoList.removeTodo(todoList.list[index].id); + }); + }, + toggleIsCompleted: () { + setState(() { + todoList.toggleList(todoList.list[index].id); + }); + }, + ); + }, + ), + ), + ], + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/completed.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/completed.dart new file mode 100644 index 00000000000..7f70e9ec871 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/screens/tabs/todos/completed.dart @@ -0,0 +1,46 @@ +import 'package:app_boilerplate/components/add_task.dart'; +import 'package:app_boilerplate/components/todo_item_tile.dart'; +import 'package:app_boilerplate/data/todo_list.dart'; +import 'package:flutter/material.dart'; + +class Completed extends StatefulWidget { + const Completed({Key key}) : super(key: key); + + @override + _CompletedState createState() => _CompletedState(); +} + +class _CompletedState extends State { + @override + Widget build(BuildContext context) { + return Column( + children: [ + AddTask( + onAdd: (value) { + todoList.addTodo(value); + }, + ), + Expanded( + child: ListView.builder( + itemCount: todoList.completeList.length, + itemBuilder: (context, index) { + return TodoItemTile( + item: todoList.completeList[index], + delete: () { + setState(() { + todoList.removeTodo(todoList.completeList[index].id); + }); + }, + toggleIsCompleted: () { + setState(() { + todoList.toggleList(todoList.completeList[index].id); + }); + }, + ); + }, + ), + ), + ], + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/services/auth.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/services/auth.dart new file mode 100644 index 00000000000..68c5e34ecb3 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/services/auth.dart @@ -0,0 +1,50 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; + +class HasuraAuth { + Future login(String username, String password) async { + String _token; + Map credentials = { + "username": username, + "password": password, + }; + http.Response response = await http + .post( + "https://learn.hasura.io/auth/login", + headers: {"content-type": "application/json"}, + body: jsonEncode(credentials), + ) + .catchError((onError) { + return null; + }); + if (response == null) { + return null; + } + _token = jsonDecode(response.body)["token"]; + return _token; + } + + Future signup(String username, String password) async { + bool success = false; + Map credentials = { + "username": username, + "password": password, + }; + http.Response response = await http + .post( + "https://learn.hasura.io/auth/signup", + headers: {"content-type": "application/json"}, + body: jsonEncode(credentials), + ) + .catchError((onError) { + return null; + }); + if (response == null) { + return success; + } + success = jsonDecode(response.body)["id"] != null; + return success; + } +} + +HasuraAuth hasuraAuth = new HasuraAuth(); diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/services/shared_preferences_service.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/services/shared_preferences_service.dart new file mode 100644 index 00000000000..386dd155de7 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/lib/services/shared_preferences_service.dart @@ -0,0 +1,25 @@ +import 'package:shared_preferences/shared_preferences.dart'; + +class SharedPreferenceService { + SharedPreferences _prefs; + + Future getSharedPreferencesInstance() async { + _prefs = await SharedPreferences.getInstance().catchError((e) { + print("shared prefrences error : $e"); + return false; + }); + return true; + } + + Future setToken(String token) async { + await _prefs.setString('token', token); + } + + Future clearToken() async { + await _prefs.clear(); + } + + Future get token async => _prefs.getString('token'); +} + +SharedPreferenceService sharedPreferenceService = SharedPreferenceService(); diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/pubspec.lock b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/pubspec.lock new file mode 100644 index 00000000000..21f89959305 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/pubspec.lock @@ -0,0 +1,175 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.11" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.0+2" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.3" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.3+1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.5" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.5" + toast: + dependency: "direct main" + description: + name: toast + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" +sdks: + dart: ">=2.2.2 <3.0.0" + flutter: ">=1.5.0 <2.0.0" diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/pubspec.yaml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/pubspec.yaml new file mode 100644 index 00000000000..1f8bc3e9a0d --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/pubspec.yaml @@ -0,0 +1,76 @@ +name: app_boilerplate +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + http: ^0.12.0+2 + toast: ^0.1.3 + shared_preferences: ^0.5.3+1 + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/test/widget_test.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/test/widget_test.dart new file mode 100644 index 00000000000..351cb38bf92 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-boilerplate/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:app_boilerplate/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/.gitignore b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/.gitignore new file mode 100644 index 00000000000..ac4a90645ca --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/.gitignore @@ -0,0 +1,72 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/.metadata b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/.metadata new file mode 100644 index 00000000000..2408a0ab09a --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 43b03127d469f1f6d9a22f8dae41eea2eed2afd9 + channel: dev + +project_type: app diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/README.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/README.md new file mode 100644 index 00000000000..3976aa1c700 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/README.md @@ -0,0 +1,16 @@ +# app_final + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/build.gradle b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/build.gradle new file mode 100644 index 00000000000..c0ac0af0b88 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.app_final" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/debug/AndroidManifest.xml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000000..ffad1478047 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/AndroidManifest.xml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..212430bd4dc --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/java/com/example/app_final/MainActivity.java b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/java/com/example/app_final/MainActivity.java new file mode 100644 index 00000000000..35d5bca95dc --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/java/com/example/app_final/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.app_final; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/drawable/launch_background.xml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000000..304732f8842 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/values/styles.xml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000000..00fa4417cfb --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/profile/AndroidManifest.xml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000000..ffad1478047 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/build.gradle b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/build.gradle new file mode 100644 index 00000000000..bb8a303898c --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/gradle.properties b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/gradle.properties new file mode 100644 index 00000000000..2bd6f4fda00 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx1536M + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/gradle/wrapper/gradle-wrapper.properties b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..2819f022f1f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/settings.gradle b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/settings.gradle new file mode 100644 index 00000000000..5a2f14fb18f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/AppFrameworkInfo.plist b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000000..6b4c0f78a78 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/Debug.xcconfig b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000000..e8efba11468 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/Release.xcconfig b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000000..399e9340e6f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Podfile b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Podfile new file mode 100644 index 00000000000..64ba7492ea9 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Podfile @@ -0,0 +1,72 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + end + pods_ary = [] + skip_line_start_symbols = ["#", "/"] + File.foreach(file_abs_path) { |line| + next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } + plugin = line.split(pattern=separator) + if plugin.length == 2 + podname = plugin[0].strip() + path = plugin[1].strip() + podpath = File.expand_path("#{path}", file_abs_path) + pods_ary.push({:name => podname, :path => podpath}); + else + puts "Invalid plugin specification: #{line}" + end + } + return pods_ary +end + +target 'Runner' do + # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock + # referring to absolute paths on developers' machines. + system('rm -rf .symlinks') + system('mkdir -p .symlinks/plugins') + + # Flutter Pods + generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') + if generated_xcode_build_settings.empty? + puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first." + end + generated_xcode_build_settings.map { |p| + if p[:name] == 'FLUTTER_FRAMEWORK_DIR' + symlink = File.join('.symlinks', 'flutter') + File.symlink(File.dirname(p[:path]), symlink) + pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) + end + } + + # Plugin Pods + plugin_pods = parse_KV_file('../.flutter-plugins') + plugin_pods.map { |p| + symlink = File.join('.symlinks', 'plugins', p[:name]) + File.symlink(p[:path], symlink) + pod p[:name], :path => File.join(symlink, 'ios') + } +end + +# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. +install! 'cocoapods', :disable_input_output_paths => true + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end +end diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Podfile.lock b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Podfile.lock new file mode 100644 index 00000000000..e64b7ba1388 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Podfile.lock @@ -0,0 +1,28 @@ +PODS: + - Flutter (1.0.0) + - path_provider (0.0.1): + - Flutter + - shared_preferences (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `.symlinks/flutter/ios`) + - path_provider (from `.symlinks/plugins/path_provider/ios`) + - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) + +EXTERNAL SOURCES: + Flutter: + :path: ".symlinks/flutter/ios" + path_provider: + :path: ".symlinks/plugins/path_provider/ios" + shared_preferences: + :path: ".symlinks/plugins/shared_preferences/ios" + +SPEC CHECKSUMS: + Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a + path_provider: f96fff6166a8867510d2c25fdcc346327cc4b259 + shared_preferences: 1feebfa37bb57264736e16865e7ffae7fc99b523 + +PODFILE CHECKSUM: 7fb83752f59ead6285236625b82473f90b1cb932 + +COCOAPODS: 1.7.3 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/project.pbxproj b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..aa73228b9bb --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,577 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 3BB7AE73B5458ADDAF753CA4 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CCAD7FC2FC5CF5DE78BC9FF4 /* libPods-Runner.a */; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 1C606A56D4651560CA7A3C82 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BDDFD2DB3B63CB501A30FEAC /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + CCAD7FC2FC5CF5DE78BC9FF4 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + F2B0EC6CCC1A17EAD07ADF7E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + 3BB7AE73B5458ADDAF753CA4 /* libPods-Runner.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 44C11147DFDD4288BF0B7929 /* Pods */ = { + isa = PBXGroup; + children = ( + BDDFD2DB3B63CB501A30FEAC /* Pods-Runner.debug.xcconfig */, + F2B0EC6CCC1A17EAD07ADF7E /* Pods-Runner.release.xcconfig */, + 1C606A56D4651560CA7A3C82 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 84EDAE55C85D750B91D24487 /* Frameworks */ = { + isa = PBXGroup; + children = ( + CCAD7FC2FC5CF5DE78BC9FF4 /* libPods-Runner.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 44C11147DFDD4288BF0B7929 /* Pods */, + 84EDAE55C85D750B91D24487 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + B391B1C80D571508E8300227 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 5E739476B133FFC8256DDE7C /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 5E739476B133FFC8256DDE7C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + B391B1C80D571508E8300227 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.appFinal; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.appFinal; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.appFinal; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000..1d526a16ed0 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000000..a28140cfdb3 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcworkspace/contents.xcworkspacedata b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000..21a3cc14c74 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/AppDelegate.h b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/AppDelegate.h new file mode 100644 index 00000000000..36e21bbf9cf --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/AppDelegate.m b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/AppDelegate.m new file mode 100644 index 00000000000..59a72e90be1 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000000..d36b1fab2d9 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d43d11e66f4de3da27ed045ca4fe38ad8b48094 GIT binary patch literal 11112 zcmeHN3sh5A)((b(k1DoWZSj%R+R=^`Y(b;ElB$1^R>iT7q6h&WAVr806i~>Gqn6rM z>3}bMG&oq%DIriqR35=rtEdos5L6z)YC*Xq0U-$_+Il@RaU zXYX%+``hR28`(B*uJ6G9&iz>|)PS%!)9N`7=LcmcxH}k69HPyT-%S zH7+jBCC<%76cg_H-n41cTqnKn`u_V9p~XaTLUe3s{KRPSTeK6apP4Jg%VQ$e#72ms zxyWzmGSRwN?=fRgpx!?W&ZsrLfuhAsRxm%;_|P@3@3~BJwY4ZVBJ3f&$5x>`^fD?d zI+z!v#$!gz%FtL*%mR^Uwa*8LJFZ_;X!y$cD??W#c)31l@ervOa_Qk86R{HJiZb$f z&&&0xYmB{@D@yl~^l5IXtB_ou{xFiYP(Jr<9Ce{jCN z<3Rf2TD%}_N?y>bgWq|{`RKd}n>P4e8Z-D+(fn^4)+|pv$DcR&i+RHNhv$71F*McT zl`phYBlb;wO`b7)*10XF6UXhY9`@UR*6-#(Zp`vyU(__*te6xYtV&N0(zjMtev{tZ zapmGin===teMXjsS0>CYxUy<2izOKOPai0}!B9+6q$s3CF8W{xUwz?A0ADO5&BsiB z{SFt|KehNd-S#eiDq!y&+mW9N_!wH-i~q|oNm=mEzkx}B?Ehe%q$tK8f=QY#*6rH9 zNHHaG(9WBqzP!!TMEktSVuh$i$4A^b25LK}&1*4W?ul*5pZYjL1OZ@X9?3W7Y|T6} z1SXx0Wn-|!A;fZGGlYn9a1Jz5^8)~v#mXhmm>um{QiGG459N}L<&qyD+sy_ixD@AP zW0XV6w#3(JW>TEV}MD=O0O>k5H>p#&|O zD2mGf0Cz7+>l7`NuzGobt;(o@vb9YiOpHN8QJ9Uva|i7R?7nnq;L_iq+ZqPv*oGu! zN@GuJ9fm;yrEFga63m?1qy|5&fd32<%$yP$llh}Udrp>~fb>M>R55I@BsGYhCj8m1 zC=ziFh4@hoytpfrJlr}FsV|C(aV4PZ^8^`G29(+!Bk8APa#PemJqkF zE{IzwPaE)I&r`OxGk*vPErm6sGKaQJ&6FODW$;gAl_4b_j!oH4yE@ zP~Cl4?kp>Ccc~Nm+0kjIb`U0N7}zrQEN5!Ju|}t}LeXi!baZOyhlWha5lq{Ld2rdo zGz7hAJQt<6^cxXTe0xZjmADL85cC&H+~Lt2siIIh{$~+U#&#^{Ub22IA|ea6 z5j12XLc`~dh$$1>3o0Cgvo*ybi$c*z>n=5L&X|>Wy1~eagk;lcEnf^2^2xB=e58Z` z@Rw{1ssK)NRV+2O6c<8qFl%efHE;uy!mq(Xi1P*H2}LMi z3EqWN2U?eW{J$lSFxDJg-=&RH!=6P9!y|S~gmjg)gPKGMxq6r9cNIhW` zS})-obO}Ao_`;=>@fAwU&=|5$J;?~!s4LN2&XiMXEl>zk9M}tVEg#kkIkbKp%Ig2QJ2aCILCM1E=aN*iuz>;q#T_I7aVM=E4$m_#OWLnXQnFUnu?~(X>$@NP zBJ@Zw>@bmErSuW7SR2=6535wh-R`WZ+5dLqwTvw}Ks8~4F#hh0$Qn^l-z=;>D~St( z-1yEjCCgd*z5qXa*bJ7H2Tk54KiX&=Vd}z?%dcc z`N8oeYUKe17&|B5A-++RHh8WQ%;gN{vf%05@jZF%wn1Z_yk#M~Cn(i@MB_mpcbLj5 zR#QAtC`k=tZ*h|){Mjz`7bNL zGWOW=bjQhX@`Vw^xn#cVwn28c2D9vOb0TLLy~-?-%gOyHSeJ9a>P}5OF5$n}k-pvUa*pvLw)KvG~>QjNWS3LY1f*OkFwPZ5qC@+3^Bt=HZbf`alKY#{pn zdY}NEIgo1sd)^TPxVzO{uvU$|Z-jkK0p1x##LexgQ$zx1^bNPOG*u2RmZkIM!zFVz zz|IsP3I?qrlmjGS2w_(azCvGTnf~flqogV@Q%mH{76uLU(>UB zQZ?*ys3BO&TV{Pj_qEa-hkH7mOMe_Bnu3%CXCgu90XNKf$N)PUc3Ei-&~@tT zI^49Lm^+=TrI=h4h=W@jW{GjWd{_kVuSzAL6Pi@HKYYnnNbtcYdIRww+jY$(30=#p8*if(mzbvau z00#}4Qf+gH&ce_&8y3Z@CZV>b%&Zr7xuPSSqOmoaP@arwPrMx^jQBQQi>YvBUdpBn zI``MZ3I3HLqp)@vk^E|~)zw$0$VI_RPsL9u(kqulmS`tnb%4U)hm{)h@bG*jw@Y*#MX;Th1wu3TrO}Srn_+YWYesEgkO1 zv?P8uWB)is;#&=xBBLf+y5e4?%y>_8$1KwkAJ8UcW|0CIz89{LydfJKr^RF=JFPi}MAv|ecbuZ!YcTSxsD$(Pr#W*oytl?@+2 zXBFb32Kf_G3~EgOS7C`8w!tx}DcCT%+#qa76VSbnHo;4(oJ7)}mm?b5V65ir`7Z}s zR2)m15b#E}z_2@rf34wo!M^CnVoi# ze+S(IK({C6u=Sm{1>F~?)8t&fZpOOPcby;I3jO;7^xmLKM(<%i-nyj9mgw9F1Lq4|DZUHZ4)V9&6fQM(ZxbG{h+}(koiTu`SQw6#6q2Yg z-d+1+MRp$zYT2neIR2cKij2!R;C~ooQ3<;^8)_Gch&ZyEtiQwmF0Mb_)6)4lVEBF< zklXS7hvtu30uJR`3OzcqUNOdYsfrKSGkIQAk|4=&#ggxdU4^Y(;)$8}fQ>lTgQdJ{ zzie8+1$3@E;|a`kzuFh9Se}%RHTmBg)h$eH;gttjL_)pO^10?!bNev6{mLMaQpY<< z7M^ZXrg>tw;vU@9H=khbff?@nu)Yw4G% zGxobPTUR2p_ed7Lvx?dkrN^>Cv$Axuwk;Wj{5Z@#$sK@f4{7SHg%2bpcS{(~s;L(mz@9r$cK@m~ef&vf%1@ z@8&@LLO2lQso|bJD6}+_L1*D^}>oqg~$NipL>QlP3 zM#ATSy@ycMkKs5-0X8nFAtMhO_=$DlWR+@EaZ}`YduRD4A2@!at3NYRHmlENea9IF zN*s>mi?zy*Vv+F+&4-o`Wj}P3mLGM*&M(z|;?d82>hQkkY?e-hJ47mWOLCPL*MO04 z3lE(n2RM=IIo;Z?I=sKJ_h=iJHbQ2<}WW0b@I6Qf-{T=Qn#@N0yG5xH&ofEy^mZMPzd22nR`t!Q)VkNgf*VOxE z$XhOunG3ZN#`Ks$Hp~}`OX5vmHP={GYUJ+-g0%PS$*Qi5+-40M47zJ24vK1#? zb$s^%r?+>#lw$mpZaMa1aO%wlPm3~cno_(S%U&-R;6eK(@`CjswAW2)HfZ>ptItaZ|XqQ z&sHVVL>WCe|E4iPb2~gS5ITs6xfg(kmt&3$YcI=zTuqj37t|+9ojCr(G^ul#p{>k) zM94pI>~5VZ$!*Qurq<@RIXgP3sx-2kL$1Q~da%rnNIh?)&+c~*&e~CYPDhPYjb+Xu zKg5w^XB3(_9{Waa4E(-J-Kq_u6t_k?a8kEHqai-N-4#`SRerO!h}!cS%SMC<)tGix zOzVP^_t!HN&HIPL-ZpcgWitHM&yFRC7!k4zSI+-<_uQ}|tX)n{Ib;X>Xx>i_d*KkH zCzogKQFpP1408_2!ofU|iBq2R8hW6G zuqJs9Tyw{u%-uWczPLkM!MfKfflt+NK9Vk8E!C>AsJwNDRoe2~cL+UvqNP|5J8t)( z0$iMa!jhudJ+fqFn+um&@Oj6qXJd_3-l`S^I1#0fnt!z3?D*hAHr*u(*wR@`4O z#avrtg%s`Fh{?$FtBFM^$@@hW!8ZfF4;=n0<8In&X}-Rp=cd0TqT_ne46$j^r}FzE z26vX^!PzScuQfFfl1HEZ{zL?G88mcc76zHGizWiykBf4m83Z${So-+dZ~YGhm*RO7 zB1gdIdqnFi?qw+lPRFW5?}CQ3Me3G^muvll&4iN+*5#_mmIu;loULMwb4lu9U*dFM z-Sr**(0Ei~u=$3<6>C-G6z4_LNCx||6YtjS)<;hf)YJTPKXW+w%hhCTUAInIse9>r zl2YU6nRb$u-FJlWN*{{%sm_gi_UP5{=?5}5^D2vPzM=oPfNw~azZQ#P zl5z8RtSSiTIpEohC15i-Q1Bk{3&ElsD0uGAOxvbk29VUDmmA0w;^v`W#0`};O3DVE z&+-ca*`YcN%z*#VXWK9Qa-OEME#fykF%|7o=1Y+eF;Rtv0W4~kKRDx9YBHOWhC%^I z$Jec0cC7o37}Xt}cu)NH5R}NT+=2Nap*`^%O)vz?+{PV<2~qX%TzdJOGeKj5_QjqR&a3*K@= P-1+_A+?hGkL;m(J7kc&K literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..28c6bf03016f6c994b70f38d1b7346e5831b531f GIT binary patch literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f091b6b0bca859a3f474b03065bef75ba58a9e4c GIT binary patch literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ef06e7edb86cdfe0d15b4b0d98334a86163658 GIT binary patch literal 1716 zcmds$`#;kQ7{|XelZftyR5~xW7?MLxS4^|Hw3&P7^y)@A9Fj{Xm1~_CIV^XZ%SLBn zA;!r`GqGHg=7>xrB{?psZQs88ZaedDoagm^KF{a*>G|dJWRSe^I$DNW008I^+;Kjt z>9p3GNR^I;v>5_`+91i(*G;u5|L+Bu6M=(afLjtkya#yZ175|z$pU~>2#^Z_pCZ7o z1c6UNcv2B3?; zX%qdxCXQpdKRz=#b*q0P%b&o)5ZrNZt7$fiETSK_VaY=mb4GK`#~0K#~9^ zcY!`#Af+4h?UMR-gMKOmpuYeN5P*RKF!(tb`)oe0j2BH1l?=>y#S5pMqkx6i{*=V9JF%>N8`ewGhRE(|WohnD59R^$_36{4>S zDFlPC5|k?;SPsDo87!B{6*7eqmMdU|QZ84>6)Kd9wNfh90=y=TFQay-0__>=<4pk& zYDjgIhL-jQ9o>z32K)BgAH+HxamL{ZL~ozu)Qqe@a`FpH=oQRA8=L-m-1dam(Ix2V z?du;LdMO+ooBelr^_y4{|44tmgH^2hSzPFd;U^!1p>6d|o)(-01z{i&Kj@)z-yfWQ)V#3Uo!_U}q3u`(fOs`_f^ueFii1xBNUB z6MecwJN$CqV&vhc+)b(p4NzGGEgwWNs z@*lUV6LaduZH)4_g!cE<2G6#+hJrWd5(|p1Z;YJ7ifVHv+n49btR}dq?HHDjl{m$T z!jLZcGkb&XS2OG~u%&R$(X+Z`CWec%QKt>NGYvd5g20)PU(dOn^7%@6kQb}C(%=vr z{?RP(z~C9DPnL{q^@pVw@|Vx~@3v!9dCaBtbh2EdtoNHm4kGxp>i#ct)7p|$QJs+U z-a3qtcPvhihub?wnJqEt>zC@)2suY?%-96cYCm$Q8R%-8$PZYsx3~QOLMDf(piXMm zB=<63yQk1AdOz#-qsEDX>>c)EES%$owHKue;?B3)8aRd}m~_)>SL3h2(9X;|+2#7X z+#2)NpD%qJvCQ0a-uzZLmz*ms+l*N}w)3LRQ*6>|Ub-fyptY(keUxw+)jfwF5K{L9 z|Cl_w=`!l_o><384d&?)$6Nh(GAm=4p_;{qVn#hI8lqewW7~wUlyBM-4Z|)cZr?Rh z=xZ&Ol>4(CU85ea(CZ^aO@2N18K>ftl8>2MqetAR53_JA>Fal`^)1Y--Am~UDa4th zKfCYpcXky$XSFDWBMIl(q=Mxj$iMBX=|j9P)^fDmF(5(5$|?Cx}DKEJa&XZP%OyE`*GvvYQ4PV&!g2|L^Q z?YG}tx;sY@GzMmsY`7r$P+F_YLz)(e}% zyakqFB<6|x9R#TdoP{R$>o7y(-`$$p0NxJ6?2B8tH)4^yF(WhqGZlM3=9Ibs$%U1w zWzcss*_c0=v_+^bfb`kBFsI`d;ElwiU%frgRB%qBjn@!0U2zZehBn|{%uNIKBA7n= zzE`nnwTP85{g;8AkYxA68>#muXa!G>xH22D1I*SiD~7C?7Za+9y7j1SHiuSkKK*^O zsZ==KO(Ua#?YUpXl{ViynyT#Hzk=}5X$e04O@fsMQjb}EMuPWFO0e&8(2N(29$@Vd zn1h8Yd>6z(*p^E{c(L0Lg=wVdupg!z@WG;E0k|4a%s7Up5C0c)55XVK*|x9RQeZ1J@1v9MX;>n34(i>=YE@Iur`0Vah(inE3VUFZNqf~tSz{1fz3Fsn_x4F>o(Yo;kpqvBe-sbwH(*Y zu$JOl0b83zu$JMvy<#oH^Wl>aWL*?aDwnS0iEAwC?DK@aT)GHRLhnz2WCvf3Ba;o=aY7 z2{Asu5MEjGOY4O#Ggz@@J;q*0`kd2n8I3BeNuMmYZf{}pg=jTdTCrIIYuW~luKecn z+E-pHY%ohj@uS0%^ z&(OxwPFPD$+#~`H?fMvi9geVLci(`K?Kj|w{rZ9JgthFHV+=6vMbK~0)Ea<&WY-NC zy-PnZft_k2tfeQ*SuC=nUj4H%SQ&Y$gbH4#2sT0cU0SdFs=*W*4hKGpuR1{)mV;Qf5pw4? zfiQgy0w3fC*w&Bj#{&=7033qFR*<*61B4f9K%CQvxEn&bsWJ{&winp;FP!KBj=(P6 z4Z_n4L7cS;ao2)ax?Tm|I1pH|uLpDSRVghkA_UtFFuZ0b2#>!8;>-_0ELjQSD-DRd z4im;599VHDZYtnWZGAB25W-e(2VrzEh|etsv2YoP#VbIZ{aFkwPrzJ#JvCvA*mXS& z`}Q^v9(W4GiSs}#s7BaN!WA2bniM$0J(#;MR>uIJ^uvgD3GS^%*ikdW6-!VFUU?JV zZc2)4cMsX@j z5HQ^e3BUzOdm}yC-xA%SY``k$rbfk z;CHqifhU*jfGM@DkYCecD9vl*qr58l6x<8URB=&%{!Cu3RO*MrKZ4VO}V6R0a zZw3Eg^0iKWM1dcTYZ0>N899=r6?+adUiBKPciJw}L$=1f4cs^bio&cr9baLF>6#BM z(F}EXe-`F=f_@`A7+Q&|QaZ??Txp_dB#lg!NH=t3$G8&06MFhwR=Iu*Im0s_b2B@| znW>X}sy~m#EW)&6E&!*0%}8UAS)wjt+A(io#wGI@Z2S+Ms1Cxl%YVE800007ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f9ed8f5cee1c98386d13b17e89f719e83555b2 GIT binary patch literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..75b2d164a5a98e212cca15ea7bf2ab5de5108680 GIT binary patch literal 3831 zcmVjJBgitF5mAp-i>4+KS_oR{|13AP->1TD4=w)g|)JHOx|a2Wk1Va z!k)vP$UcQ#mdj%wNQoaJ!w>jv_6&JPyutpQps?s5dmDQ>`%?Bvj>o<%kYG!YW6H-z zu`g$@mp`;qDR!51QaS}|ZToSuAGcJ7$2HF0z`ln4t!#Yg46>;vGG9N9{V@9z#}6v* zfP?}r6b{*-C*)(S>NECI_E~{QYzN5SXRmVnP<=gzP+_Sp(Aza_hKlZ{C1D&l*(7IKXxQC1Z9#6wx}YrGcn~g%;icdw>T0Rf^w0{ z$_wn1J+C0@!jCV<%Go5LA45e{5gY9PvZp8uM$=1}XDI+9m7!A95L>q>>oe0$nC->i zeexUIvq%Uk<-$>DiDb?!In)lAmtuMWxvWlk`2>4lNuhSsjAf2*2tjT`y;@d}($o)S zn(+W&hJ1p0xy@oxP%AM15->wPLp{H!k)BdBD$toBpJh+crWdsNV)qsHaqLg2_s|Ih z`8E9z{E3sA!}5aKu?T!#enD(wLw?IT?k-yWVHZ8Akz4k5(TZJN^zZgm&zM28sfTD2BYJ|Fde3Xzh;;S` z=GXTnY4Xc)8nYoz6&vF;P7{xRF-{|2Xs5>a5)@BrnQ}I(_x7Cgpx#5&Td^4Q9_FnQ zX5so*;#8-J8#c$OlA&JyPp$LKUhC~-e~Ij!L%uSMu!-VZG7Hx-L{m2DVR2i=GR(_% zCVD!4N`I)&Q5S`?P&fQZ=4#Dgt_v2-DzkT}K(9gF0L(owe-Id$Rc2qZVLqI_M_DyO z9@LC#U28_LU{;wGZ&))}0R2P4MhajKCd^K#D+JJ&JIXZ_p#@+7J9A&P<0kdRujtQ_ zOy>3=C$kgi6$0pW06KaLz!21oOryKM3ZUOWqppndxfH}QpgjEJ`j7Tzn5bk6K&@RA?vl##y z$?V~1E(!wB5rH`>3nc&@)|#<1dN2cMzzm=PGhQ|Yppne(C-Vlt450IXc`J4R0W@I7 zd1e5uW6juvO%ni(WX7BsKx3MLngO7rHO;^R5I~0^nE^9^E_eYLgiR9&KnJ)pBbfno zSVnW$0R+&6jOOsZ82}nJ126+c|%svPo;TeUku<2G7%?$oft zyaO;tVo}(W)VsTUhq^XmFi#2z%-W9a{7mXn{uzivYQ_d6b7VJG{77naW(vHt-uhnY zVN#d!JTqVh(7r-lhtXVU6o})aZbDt_;&wJVGl2FKYFBFpU-#9U)z#(A%=IVnqytR$SY-sO( z($oNE09{D^@OuYPz&w~?9>Fl5`g9u&ecFGhqX=^#fmR=we0CJw+5xna*@oHnkahk+ z9aWeE3v|An+O5%?4fA&$Fgu~H_YmqR!yIU!bFCk4!#pAj%(lI(A5n)n@Id#M)O9Yx zJU9oKy{sRAIV3=5>(s8n{8ryJ!;ho}%pn6hZKTKbqk=&m=f*UnK$zW3YQP*)pw$O* zIfLA^!-bmBl6%d_n$#tP8Zd_(XdA*z*WH|E_yILwjtI~;jK#v-6jMl^?<%Y%`gvpwv&cFb$||^v4D&V=aNy?NGo620jL3VZnA%s zH~I|qPzB~e(;p;b^gJr7Ure#7?8%F0m4vzzPy^^(q4q1OdthF}Fi*RmVZN1OwTsAP zn9CZP`FazX3^kG(KodIZ=Kty8DLTy--UKfa1$6XugS zk%6v$Kmxt6U!YMx0JQ)0qX*{CXwZZk$vEROidEc7=J-1;peNat!vS<3P-FT5po>iE z!l3R+<`#x|+_hw!HjQGV=8!q|76y8L7N8gP3$%0kfush|u0uU^?dKBaeRSBUpOZ0c z62;D&Mdn2}N}xHRFTRI?zRv=>=AjHgH}`2k4WK=#AHB)UFrR-J87GgX*x5fL^W2#d z=(%K8-oZfMO=i{aWRDg=FX}UubM4eotRDcn;OR#{3q=*?3mE3_oJ-~prjhxh%PgQT zyn)Qozaq0@o&|LEgS{Ind4Swsr;b`u185hZPOBLL<`d2%^Yp1?oL)=jnLi;Zo0ZDliTtQ^b5SmfIMe{T==zZkbvn$KTQGlbG8w}s@M3TZnde;1Am46P3juKb zl9GU&3F=q`>j!`?SyH#r@O59%@aMX^rx}Nxe<>NqpUp5=lX1ojGDIR*-D^SDuvCKF z?3$xG(gVUsBERef_YjPFl^rU9EtD{pt z0CXwpN7BN3!8>hajGaTVk-wl=9rxmfWtIhC{mheHgStLi^+Nz12a?4r(fz)?3A%at zMlvQmL<2-R)-@G1wJ0^zQK%mR=r4d{Y3fHp){nWXUL#|CqXl(+v+qDh>FkF9`eWrW zfr^D%LNfOcTNvtx0JXR35J0~Jpi2#P3Q&80w+nqNfc}&G0A~*)lGHKv=^FE+b(37|)zL;KLF>oiGfb(?&1 zV3XRu!Sw>@quKiab%g6jun#oZ%!>V#A%+lNc?q>6+VvyAn=kf_6z^(TZUa4Eelh{{ zqFX-#dY(EV@7l$NE&kv9u9BR8&Ojd#ZGJ6l8_BW}^r?DIS_rU2(XaGOK z225E@kH5Opf+CgD^{y29jD4gHbGf{1MD6ggQ&%>UG4WyPh5q_tb`{@_34B?xfSO*| zZv8!)q;^o-bz`MuxXk*G^}(6)ACb@=Lfs`Hxoh>`Y0NE8QRQ!*p|SH@{r8=%RKd4p z+#Ty^-0kb=-H-O`nAA3_6>2z(D=~Tbs(n8LHxD0`R0_ATFqp-SdY3(bZ3;VUM?J=O zKCNsxsgt@|&nKMC=*+ZqmLHhX1KHbAJs{nGVMs6~TiF%Q)P@>!koa$%oS zjXa=!5>P`vC-a}ln!uH1ooeI&v?=?v7?1n~P(wZ~0>xWxd_Aw;+}9#eULM7M8&E?Y zC-ZLhi3RoM92SXUb-5i-Lmt5_rfjE{6y^+24`y$1lywLyHO!)Boa7438K4#iLe?rh z2O~YGSgFUBH?og*6=r9rme=peP~ah`(8Zt7V)j5!V0KPFf_mebo3z95U8(up$-+EA^9dTRLq>Yl)YMBuch9%=e5B`Vnb>o zt03=kq;k2TgGe4|lGne&zJa~h(UGutjP_zr?a7~#b)@15XNA>Dj(m=gg2Q5V4-$)D|Q9}R#002ovPDHLkV1o7DH3k3x literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c4df70d39da7941ef3f6dcb7f06a192d8dcb308d GIT binary patch literal 1888 zcmV-m2cP(fP)x~L`~4d)Rspd&<9kFh{hn*KP1LP0~$;u(LfAu zp%fx&qLBcRHx$G|3q(bv@+b;o0*D|jwD-Q9uQR(l*ST}s+uPgQ-MeFwZ#GS?b332? z&Tk$&_miXn3IGq)AmQ)3sisq{raD4(k*bHvpCe-TdWq^NRTEVM)i9xbgQ&ccnUVx* zEY%vS%gDcSg=!tuIK8$Th2_((_h^+7;R|G{n06&O2#6%LK`a}n?h_fL18btz<@lFG za}xS}u?#DBMB> zw^b($1Z)`9G?eP95EKi&$eOy@K%h;ryrR3la%;>|o*>CgB(s>dDcNOXg}CK9SPmD? zmr-s{0wRmxUnbDrYfRvnZ@d z6johZ2sMX{YkGSKWd}m|@V7`Degt-43=2M?+jR%8{(H$&MLLmS;-|JxnX2pnz;el1jsvqQz}pGSF<`mqEXRQ5sC4#BbwnB_4` zc5bFE-Gb#JV3tox9fp-vVEN{(tOCpRse`S+@)?%pz+zVJXSooTrNCUg`R6`hxwb{) zC@{O6MKY8tfZ5@!yy=p5Y|#+myRL=^{tc(6YgAnkg3I(Cd!r5l;|;l-MQ8B`;*SCE z{u)uP^C$lOPM z5d~UhKhRRmvv{LIa^|oavk1$QiEApSrP@~Jjbg`<*dW4TO?4qG%a%sTPUFz(QtW5( zM)lA+5)0TvH~aBaOAs|}?u2FO;yc-CZ1gNM1dAxJ?%m?YsGR`}-xk2*dxC}r5j$d* zE!#Vtbo69h>V4V`BL%_&$} z+oJAo@jQ^Tk`;%xw-4G>hhb&)B?##U+(6Fi7nno`C<|#PVA%$Y{}N-?(Gc$1%tr4Pc}}hm~yY#fTOe!@v9s-ik$dX~|ygArPhByaXn8 zpI^FUjNWMsTFKTP3X7m?UK)3m zp6rI^_zxRYrx6_QmhoWoDR`fp4R7gu6;gdO)!KexaoO2D88F9x#TM1(9Bn7g;|?|o z)~$n&Lh#hCP6_LOPD>a)NmhW})LADx2kq=X7}7wYRj-0?dXr&bHaRWCfSqvzFa=sn z-8^gSyn-RmH=BZ{AJZ~!8n5621GbUJV7Qvs%JNv&$%Q17s_X%s-41vAPfIR>;x0Wlqr5?09S>x#%Qkt>?(&XjFRY}*L6BeQ3 z<6XEBh^S7>AbwGm@XP{RkeEKj6@_o%oV?hDuUpUJ+r#JZO?!IUc;r0R?>mi)*ZpQ) z#((dn=A#i_&EQn|hd)N$#A*fjBFuiHcYvo?@y1 z5|fV=a^a~d!c-%ZbMNqkMKiSzM{Yq=7_c&1H!mXk60Uv32dV;vMg&-kQ)Q{+PFtwc zj|-uQ;b^gts??J*9VxxOro}W~Q9j4Em|zSRv)(WSO9$F$s=Ydu%Q+5DOid~lwk&we zY%W(Z@ofdwPHncEZzZgmqS|!gTj3wQq9rxQy+^eNYKr1mj&?tm@wkO*9@UtnRMG>c aR{jt9+;fr}hV%pg00001^@s67{VYS000c7NklQEG_j zup^)eW&WUIApqy$=APz8jE@awGp)!bsTjDbrJO`$x^ZR^dr;>)LW>{ zs70vpsD38v)19rI=GNk1b(0?Js9~rjsQsu*K;@SD40RB-3^gKU-MYC7G!Bw{fZsqp zih4iIi;Hr_xZ033Iu{sQxLS=}yBXgLMn40d++>aQ0#%8D1EbGZp7+ z5=mK?t31BkVYbGOxE9`i748x`YgCMwL$qMsChbSGSE1`p{nSmadR zcQ#R)(?!~dmtD0+D2!K zR9%!Xp1oOJzm(vbLvT^$IKp@+W2=-}qTzTgVtQ!#Y7Gxz}stUIm<1;oBQ^Sh2X{F4ibaOOx;5ZGSNK z0maF^@(UtV$=p6DXLgRURwF95C=|U8?osGhgOED*b z7woJ_PWXBD>V-NjQAm{~T%sjyJ{5tn2f{G%?J!KRSrrGvQ1(^`YLA5B!~eycY(e5_ z*%aa{at13SxC(=7JT7$IQF~R3sy`Nn%EMv!$-8ZEAryB*yB1k&stni)=)8-ODo41g zkJu~roIgAih94tb=YsL%iH5@^b~kU9M-=aqgXIrbtxMpFy5mekFm#edF9z7RQ6V}R zBIhbXs~pMzt0VWy1Fi$^fh+1xxLDoK09&5&MJl(q#THjPm(0=z2H2Yfm^a&E)V+a5 zbi>08u;bJsDRUKR9(INSc7XyuWv(JsD+BB*0hS)FO&l&7MdViuur@-<-EHw>kHRGY zqoT}3fDv2-m{NhBG8X}+rgOEZ;amh*DqN?jEfQdqxdj08`Sr=C-KmT)qU1 z+9Cl)a1mgXxhQiHVB}l`m;-RpmKy?0*|yl?FXvJkFxuu!fKlcmz$kN(a}i*saM3nr z0!;a~_%Xqy24IxA2rz<+08=B-Q|2PT)O4;EaxP^6qixOv7-cRh?*T?zZU`{nIM-at zTKYWr9rJ=tppQ9I#Z#mLgINVB!pO-^FOcvFw6NhV0gztuO?g ztoA*C-52Q-Z-P#xB4HAY3KQVd%dz1S4PA3vHp0aa=zAO?FCt zC_GaTyVBg2F!bBr3U@Zy2iJgIAt>1sf$JWA9kh{;L+P*HfUBX1Zy{4MgNbDfBV_ly z!y#+753arsZUt@366jIC0klaC@ckuk!qu=pAyf7&QmiBUT^L1&tOHzsK)4n|pmrVT zs2($4=?s~VejTFHbFdDOwG;_58LkIj1Fh@{glkO#F1>a==ymJS$z;gdedT1zPx4Kj ztjS`y_C}%af-RtpehdQDt3a<=W5C4$)9W@QAse;WUry$WYmr51ml9lkeunUrE`-3e zmq1SgSOPNEE-Mf+AGJ$g0M;3@w!$Ej;hMh=v=I+Lpz^n%Pg^MgwyqOkNyu2c^of)C z1~ALor3}}+RiF*K4+4{(1%1j3pif1>sv0r^mTZ?5Jd-It!tfPfiG_p$AY*Vfak%FG z4z#;wLtw&E&?}w+eKG^=#jF7HQzr8rV0mY<1YAJ_uGz~$E13p?F^fPSzXSn$8UcI$ z8er9{5w5iv0qf8%70zV71T1IBB1N}R5Kp%NO0=5wJalZt8;xYp;b{1K) zHY>2wW-`Sl{=NpR%iu3(u6l&)rc%%cSA#aV7WCowfbFR4wcc{LQZv~o1u_`}EJA3>ki`?9CKYTA!rhO)if*zRdd}Kn zEPfYbhoVE~!FI_2YbC5qAj1kq;xP6%J8+?2PAs?`V3}nyFVD#sV3+uP`pi}{$l9U^ zSz}_M9f7RgnnRhaoIJgT8us!1aB&4!*vYF07Hp&}L zCRlop0oK4DL@ISz{2_BPlezc;xj2|I z23RlDNpi9LgTG_#(w%cMaS)%N`e>~1&a3<{Xy}>?WbF>OOLuO+j&hc^YohQ$4F&ze z+hwnro1puQjnKm;vFG~o>`kCeUIlkA-2tI?WBKCFLMBY=J{hpSsQ=PDtU$=duS_hq zHpymHt^uuV1q@uc4bFb{MdG*|VoW@15Osrqt2@8ll0qO=j*uOXn{M0UJX#SUztui9FN4)K3{9!y8PC-AHHvpVTU;x|-7P+taAtyglk#rjlH2 z5Gq8ik}BPaGiM{#Woyg;*&N9R2{J0V+WGB69cEtH7F?U~Kbi6ksi*`CFXsi931q7Y zGO82?whBhN%w1iDetv%~wM*Y;E^)@Vl?VDj-f*RX>{;o_=$fU!&KAXbuadYZ46Zbg z&6jMF=49$uL^73y;;N5jaHYv)BTyfh&`qVLYn?`o6BCA_z-0niZz=qPG!vonK3MW_ zo$V96zM!+kJRs{P-5-rQVse0VBH*n6A58)4uc&gfHMa{gIhV2fGf{st>E8sKyP-$8zp~wJX^A*@DI&-;8>gANXZj zU)R+Y)PB?=)a|Kj>8NXEu^S_h^7R`~Q&7*Kn!xyvzVv&^>?^iu;S~R2e-2fJx-oUb cX)(b1KSk$MOV07*qoM6N<$f&6$jw%VRuvdN2+38CZWny1cRtlsl+0_KtW)EU14Ei(F!UtWuj4IK+3{sK@>rh zs1Z;=(DD&U6+tlyL?UnHVN^&g6QhFi2#HS+*qz;(>63G(`|jRtW|nz$Pv7qTovP!^ zP_jES{mr@O-02w%!^a?^1ZP!_KmQiz0L~jZ=W@Qt`8wzOoclQsAS<5YdH;a(4bGLE zk8s}1If(PSIgVi!XE!5kA?~z*sobvNyohr;=Q_@h2@$6Flyej3J)D-6YfheRGl`HEcPk|~huT_2-U?PfL=4BPV)f1o!%rQ!NMt_MYw-5bUSwQ9Z&zC>u zOrl~UJglJNa%f50Ok}?WB{on`Ci`p^Y!xBA?m@rcJXLxtrE0FhRF3d*ir>yzO|BD$ z3V}HpFcCh6bTzY}Nt_(W%QYd3NG)jJ4<`F<1Od) zfQblTdC&h2lCz`>y?>|9o2CdvC8qZeIZt%jN;B7Hdn2l*k4M4MFEtq`q_#5?}c$b$pf_3y{Y!cRDafZBEj-*OD|gz#PBDeu3QoueOesLzB+O zxjf2wvf6Wwz>@AiOo2mO4=TkAV+g~%_n&R;)l#!cBxjuoD$aS-`IIJv7cdX%2{WT7 zOm%5rs(wqyPE^k5SIpUZ!&Lq4<~%{*>_Hu$2|~Xa;iX*tz8~G6O3uFOS?+)tWtdi| zV2b#;zRN!m@H&jd=!$7YY6_}|=!IU@=SjvGDFtL;aCtw06U;-v^0%k0FOyESt z1Wv$={b_H&8FiRV?MrzoHWd>%v6KTRU;-v^Miiz+@q`(BoT!+<37CKhoKb)|8!+RG z6BQFU^@fRW;s8!mOf2QViKQGk0TVER6EG1`#;Nm39Do^PoT!+<37AD!%oJe86(=et zZ~|sLzU>V-qYiU6V8$0GmU7_K8|Fd0B?+9Un1BhKAz#V~Fk^`mJtlCX#{^8^M8!me z8Yg;8-~>!e<-iG;h*0B1kBKm}hItVGY6WnjVpgnTTAC$rqQ^v)4KvOtpY|sIj@WYg zyw##ZZ5AC2IKNC;^hwg9BPk0wLStlmBr;E|$5GoAo$&Ui_;S9WY62n3)i49|T%C#i017z3J=$RF|KyZWnci*@lW4 z=AKhNN6+m`Q!V3Ye68|8y@%=am>YD0nG99M)NWc20%)gwO!96j7muR}Fr&54SxKP2 zP30S~lt=a*qDlbu3+Av57=9v&vr<6g0&`!8E2fq>I|EJGKs}t|{h7+KT@)LfIV-3K zK)r_fr2?}FFyn*MYoLC>oV-J~eavL2ho4a4^r{E-8m2hi>~hA?_vIG4a*KT;2eyl1 zh_hUvUJpNCFwBvRq5BI*srSle>c6%n`#VNsyC|MGa{(P&08p=C9+WUw9Hl<1o9T4M zdD=_C0F7#o8A_bRR?sFNmU0R6tW`ElnF8p53IdHo#S9(JoZCz}fHwJ6F<&?qrpVqE zte|m%89JQD+XwaPU#%#lVs-@-OL);|MdfINd6!XwP2h(eyafTUsoRkA%&@fe?9m@jw-v(yTTiV2(*fthQH9}SqmsRPVnwwbV$1E(_lkmo&S zF-truCU914_$jpqjr(>Ha4HkM4YMT>m~NosUu&UZ>zirfHo%N6PPs9^_o$WqPA0#5 z%tG>qFCL+b*0s?sZ;Sht0nE7Kl>OVXy=gjWxxK;OJ3yGd7-pZf7JYNcZo2*1SF`u6 zHJyRRxGw9mDlOiXqVMsNe#WX`fC`vrtjSQ%KmLcl(lC>ZOQzG^%iql2w-f_K@r?OE zwCICifM#L-HJyc7Gm>Ern?+Sk3&|Khmu4(~3qa$(m6Ub^U0E5RHq49za|XklN#?kP zl;EstdW?(_4D>kwjWy2f!LM)y?F94kyU3`W!6+AyId-89v}sXJpuic^NLL7GJItl~ zsiuB98AI-(#Mnm|=A-R6&2fwJ0JVSY#Q>&3$zFh|@;#%0qeF=j5Ajq@4i0tIIW z&}sk$&fGwoJpe&u-JeGLi^r?dO`m=y(QO{@h zQqAC7$rvz&5+mo3IqE?h=a~6m>%r5Quapvzq;{y~p zJpyXOBgD9VrW7@#p6l7O?o3feml(DtSL>D^R) zZUY%T2b0-vBAFN7VB;M88!~HuOXi4KcI6aRQ&h|XQ0A?m%j2=l1f0cGP}h(oVfJ`N zz#PpmFC*ieab)zJK<4?^k=g%OjPnkANzbAbmGZHoVRk*mTfm75s_cWVa`l*f$B@xu z5E*?&@seIo#*Y~1rBm!7sF9~~u6Wrj5oICUOuz}CS)jdNIznfzCA(stJ(7$c^e5wN z?lt>eYgbA!kvAR7zYSD&*r1$b|(@;9dcZ^67R0 zXAXJKa|5Sdmj!g578Nwt6d$sXuc&MWezA0Whd`94$h{{?1IwXP4)Tx4obDK%xoFZ_Z zjjHJ_P@R_e5blG@yEjnaJb`l;s%Lb2&=8$&Ct-fV`E^4CUs)=jTk!I}2d&n!f@)bm z@ z_4Dc86+3l2*p|~;o-Sb~oXb_RuLmoifDU^&Te$*FevycC0*nE3Xws8gsWp|Rj2>SM zns)qcYj?^2sd8?N!_w~4v+f-HCF|a$TNZDoNl$I1Uq87euoNgKb6&r26TNrfkUa@o zfdiFA@p{K&mH3b8i!lcoz)V{n8Q@g(vR4ns4r6w;K z>1~ecQR0-<^J|Ndg5fvVUM9g;lbu-){#ghGw(fg>L zh)T5Ljb%lWE;V9L!;Cqk>AV1(rULYF07ZBJbGb9qbSoLAd;in9{)95YqX$J43-dY7YU*k~vrM25 zxh5_IqO0LYZW%oxQ5HOzmk4x{atE*vipUk}sh88$b2tn?!ujEHn`tQLe&vo}nMb&{ zio`xzZ&GG6&ZyN3jnaQy#iVqXE9VT(3tWY$n-)uWDQ|tc{`?fq2F`oQ{;d3aWPg4Hp-(iE{ry>MIPWL> iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000000..89c2725b70f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Base.lproj/LaunchScreen.storyboard b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000000..f2e259c7c93 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Base.lproj/Main.storyboard b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000000..f3c28516fb3 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Info.plist b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Info.plist new file mode 100644 index 00000000000..1ee48cca5c8 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + app_final + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/main.m b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/main.m new file mode 100644 index 00000000000..dff6597e451 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/add_task.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/add_task.dart new file mode 100644 index 00000000000..ebd0a06461c --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/add_task.dart @@ -0,0 +1,46 @@ +import 'package:app_final/components/custom_button.dart'; + +import 'package:flutter/material.dart'; + +class AddTask extends StatelessWidget { + //final TodoList todoList; + final Function onAdd; + const AddTask({Key key, this.onAdd}) : super(key: key); + + @override + Widget build(BuildContext context) { + TextEditingController _controller = TextEditingController(); + return Container( + child: Padding( + padding: const EdgeInsets.all(18.0), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: TextFormField( + controller: _controller, + decoration: InputDecoration( + labelText: "Add task", + border: OutlineInputBorder(), + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: CustomButton( + width: 90, + height: 50, + onTap: () { + onAdd(_controller.text); + _controller.clear(); + FocusScope.of(context).requestFocus(new FocusNode()); + }, + text: "Add", + ), + ) + ], + ), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/custom_button.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/custom_button.dart new file mode 100644 index 00000000000..47aa2ed02e4 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/custom_button.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +class CustomButton extends StatelessWidget { + final Function onTap; + final String text; + final double height; + final double width; + + CustomButton({ + Key key, + @required this.onTap, + @required this.text, + @required this.height, + @required this.width, + }) : super(key: key); + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + width: width, + height: height, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(23), color: Colors.black), + child: Center( + child: Text( + text, + style: TextStyle(color: Colors.white), + ), + ), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/feed_tile.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/feed_tile.dart new file mode 100644 index 00000000000..7e6fa6a3b16 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/feed_tile.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +class FeedTile extends StatelessWidget { + final String username; + final String feed; + + FeedTile({ + Key key, + @required this.username, + @required this.feed, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Card( + child: ListTile( + title: Text(username), + subtitle: Text(feed), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/todo_item_tile.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/todo_item_tile.dart new file mode 100644 index 00000000000..532855a6229 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/todo_item_tile.dart @@ -0,0 +1,112 @@ +import 'package:app_final/model/todo_item.dart'; +import 'package:flutter/material.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +class TodoItemTile extends StatelessWidget { + final TodoItem item; + final String toggleDocument; + final Map toggleRunMutaion; + final String deleteDocument; + final Map deleteRunMutaion; + final Function refetchQuery; + + TodoItemTile({ + Key key, + this.refetchQuery, + @required this.item, + @required this.toggleDocument, + @required this.toggleRunMutaion, + @required this.deleteDocument, + @required this.deleteRunMutaion, + }) : super(key: key); + Map extractTodoData(Object data) { + final Map returning = + (data as Map)['action'] as Map; + if (returning == null) { + return null; + } + List list = returning['returning']; + return list[0] as Map; + } + + @override + Widget build(BuildContext context) { + return Container( + child: Card( + child: ListTile( + contentPadding: EdgeInsets.all(0), + title: Text(item.task, + style: TextStyle( + decoration: item.isCompleted + ? TextDecoration.lineThrough + : TextDecoration.none)), + leading: Mutation( + options: MutationOptions(document: toggleDocument), + builder: ( + RunMutation runMutation, + QueryResult result, + ) { + return InkWell( + onTap: () { + runMutation( + toggleRunMutaion, + optimisticResult: { + "action": { + "returning": [ + {"is_completed": !item.isCompleted} + ] + } + }, + ); + }, + child: Container( + height: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: Icon(!item.isCompleted + ? Icons.radio_button_unchecked + : Icons.radio_button_checked), + ), + ); + }, + update: (Cache cache, QueryResult result) { + if (result.hasErrors) { + print(result.errors); + } else { + final Map updated = + Map.from(item.toJson()) + ..addAll(extractTodoData(result.data)); + cache.write(typenameDataIdFromObject(updated), updated); + } + return cache; + }, + onCompleted: (onValue) { + refetchQuery(); + }, + ), + trailing: Mutation( + options: MutationOptions(document: deleteDocument), + builder: ( + RunMutation runMutation, + QueryResult result, + ) { + return InkWell( + onTap: () { + runMutation(deleteRunMutaion); + }, + child: Container( + decoration: BoxDecoration( + border: Border(left: BorderSide(color: Colors.grey))), + width: 60, + height: double.infinity, + child: Icon(Icons.delete)), + ); + }, + onCompleted: (onValue) { + refetchQuery(); + }, + ), + ), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/utils.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/utils.dart new file mode 100644 index 00000000000..b74bdda1cbd --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/components/utils.dart @@ -0,0 +1,9 @@ +import 'package:flutter/material.dart'; +import 'package:toast/toast.dart'; + +class UtilFs { + static showToast(String message, BuildContext context) { + Toast.show(message, context, + duration: Toast.LENGTH_LONG, gravity: Toast.BOTTOM); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/config/client.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/config/client.dart new file mode 100644 index 00000000000..1a52a079cda --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/config/client.dart @@ -0,0 +1,32 @@ +import 'package:app_final/services/shared_preferences_service.dart'; +import 'package:flutter/material.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +class Config { + static final HttpLink httpLink = HttpLink( + uri: 'https://learn.hasura.io/graphql', + ); + + static final AuthLink authLink = + AuthLink(getToken: () async => await sharedPreferenceService.token); + static final WebSocketLink websocketLink = WebSocketLink( + url: 'wss://learn.hasura.io/graphql', + config: SocketClientConfig( + autoReconnect: true, + inactivityTimeout: Duration(seconds: 30), + ), + ); + + static final Link link = + authLink.concat(httpLink as Link).concat(websocketLink); + + static ValueNotifier initailizeClient() { + ValueNotifier client = ValueNotifier( + GraphQLClient( + cache: OptimisticCache(dataIdFromObject: typenameDataIdFromObject), + link: link, + ), + ); + return client; + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/feed_fetch.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/feed_fetch.dart new file mode 100644 index 00000000000..29c64854396 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/feed_fetch.dart @@ -0,0 +1,41 @@ +class FeedFetch { + static String fetchNewNotification = """subscription fetchNewNotification { + todos(where: {is_public: {_eq: true}}, limit: 1, order_by: {created_at: desc}) { + id + } +} +"""; + + static String loadMoreTodos = """ query loadMoreTodos (\$oldestTodoId: Int!) { + todos (where: { is_public: { _eq: true}, id: {_lt: \$oldestTodoId}}, limit: 7, order_by: { created_at: desc }) { + id + title + created_at + user { + name + } + } + }"""; + static String newTodos = """query newTodos (\$latestVisibleId: Int!) { + todos(where: { is_public: { _eq: true}, id: {_gt: \$latestVisibleId}}, order_by: { created_at: desc }) { + id + title + created_at + user { + name + } + } + }"""; + static String addPublicTodo = """mutation (\$title: String!){ + insert_todos ( + objects: [{ + title: \$title, + is_public: true + }] + ){ + returning { + id + } + } + }"""; +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/feed_list.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/feed_list.dart new file mode 100644 index 00000000000..7b193c90223 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/feed_list.dart @@ -0,0 +1,20 @@ +import 'package:app_final/model/feed_item.dart'; + +class FeedList { + List list = []; + + addFeed(String id, String username, String feed) { + list.add( + FeedItem.fromElements(id, username, feed), + ); + } + + addfirstFeed(String id, String username, String feed) { + list.insert( + 0, + FeedItem.fromElements(id, username, feed), + ); + } +} + +FeedList feedList = new FeedList(); diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/online_fetch.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/online_fetch.dart new file mode 100644 index 00000000000..1f98e7021b9 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/online_fetch.dart @@ -0,0 +1,17 @@ +class OnlineFetch { + static String fetchUsers = """ + subscription fetchOnlineUsers { + online_users { + user { + name + } + } +} +"""; + static String updateStatus = + """ mutation updateLastSeen (\$now: timestamptz!) { + update_users(where: {}, _set: {last_seen: \$now}) { + affected_rows + } + }"""; +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/online_list.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/online_list.dart new file mode 100644 index 00000000000..a5ba564851b --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/online_list.dart @@ -0,0 +1,5 @@ +class OnlineList { + List list = ["User1", "User3", "User5"]; +} + +OnlineList onlineList = new OnlineList(); diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/todo_fetch.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/todo_fetch.dart new file mode 100644 index 00000000000..ba0ce77aab0 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/todo_fetch.dart @@ -0,0 +1,51 @@ +class TodoFetch { + static String fetchAll = """query getTodos(\$is_public: Boolean!) { + todos(where: { is_public: { _eq: \$is_public} }, order_by: { created_at: desc }) { + __typename + id + title + is_completed + } +}"""; + static String fetchActive = """query getActiveTodos{ + todos(where: {is_public: {_eq: false}, is_completed: {_eq: false}}, order_by: {created_at: desc}) { + __typename + is_completed + id + title + } + }"""; + static String fetchCompleted = """query getCompletedTodos{ + todos(where: {is_public: {_eq: false}, is_completed: {_eq: true}}, order_by: {created_at: desc}) { + __typename + is_completed + id + title + } + }"""; + static String addTodo = + """mutation addTodo(\$title: String!, \$isPublic: Boolean!) { + action: insert_todos(objects: { title: \$title, is_public: \$isPublic }) { + returning { + id + title + is_completed + } + } +}"""; + static String toggleTodo = + """mutation toggleTodo(\$id:Int!, \$isCompleted: Boolean!) { + action: update_todos(where: {id: {_eq: \$id}}, _set: {is_completed: \$isCompleted}) { + returning { + is_completed + } + } +}"""; + static String deleteTodo = """mutation delete(\$id:Int!) { + action: delete_todos(where: {id: {_eq: \$id}}) { + returning { + id + } + } +}"""; +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/todo_list.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/todo_list.dart new file mode 100644 index 00000000000..fc2628ae2a5 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/data/todo_list.dart @@ -0,0 +1,32 @@ +import 'package:app_final/model/todo_item.dart'; + +class TodoList { + List list = []; + int id = 0; + addTodo(String task) { + id++; + list.add( + TodoItem.fromElements( + id, + task, + false, + ), + ); + } + + removeTodo(int id) { + list.removeWhere((item) => item.id == id); + } + + toggleList(int id) { + int index = list.indexWhere((item) => item.id == id); + list[index].isCompleted = !list[index].isCompleted; + } + + List get activeList => + list.where((item) => item.isCompleted == false).toList(); + List get completeList => + list.where((item) => item.isCompleted == true).toList(); +} + +TodoList todoList = new TodoList(); diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/main.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/main.dart new file mode 100644 index 00000000000..42710a4120b --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/main.dart @@ -0,0 +1,25 @@ +import 'package:app_final/screens/dashboard.dart'; +import 'package:app_final/screens/login.dart'; +import 'package:app_final/screens/signup.dart'; +import 'package:app_final/screens/splash.dart'; +import 'package:flutter/material.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + final routes = { + "/login": (BuildContext context) => Login(), + "/dashboard": (BuildContext context) => Dashboard(), + "/signup": (BuildContext context) => Signup(), + }; + return MaterialApp( + title: 'Hasura GraphQL Demo', + theme: ThemeData(primaryColor: Colors.black), + routes: routes, + home: Splash(), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/model/feed_item.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/model/feed_item.dart new file mode 100644 index 00000000000..47d7fe9daa8 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/model/feed_item.dart @@ -0,0 +1,11 @@ +class FeedItem { + String id = ""; + String username = ""; + String feed = ""; + + FeedItem.fromElements(String id, String username, String feed) { + this.username = username; + this.feed = feed; + this.id = id; + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/model/todo_item.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/model/todo_item.dart new file mode 100644 index 00000000000..81511cfecdf --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/model/todo_item.dart @@ -0,0 +1,19 @@ +class TodoItem { + int id; + String task = ""; + bool isCompleted = false; + TodoItem.fromElements(int id, String task, bool isCompleted) { + this.id = id; + this.task = task; + this.isCompleted = isCompleted; + } + Map toJson() { + Map jsonData = { + "__typename": "todos", + "id": id, + "title": task, + "is_completed": isCompleted, + }; + return jsonData; + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/dashboard.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/dashboard.dart new file mode 100644 index 00000000000..cf1c9fa55e8 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/dashboard.dart @@ -0,0 +1,70 @@ +import 'package:app_final/config/client.dart'; +import 'package:app_final/screens/tabs/dashboard/feeds.dart'; +import 'package:app_final/screens/tabs/dashboard/online.dart'; +import 'package:app_final/screens/tabs/dashboard/todos.dart'; +import 'package:app_final/services/shared_preferences_service.dart'; +import 'package:flutter/material.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +class Dashboard extends StatelessWidget { + Dashboard({Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return GraphQLProvider( + client: Config.initailizeClient(), + child: CacheProvider( + child: DefaultTabController( + length: 3, + child: Scaffold( + appBar: AppBar( + automaticallyImplyLeading: false, + centerTitle: true, + title: Text( + "ToDo App", + ), + actions: [ + IconButton( + icon: Icon(Icons.exit_to_app), + onPressed: () async { + sharedPreferenceService.clearToken(); + Navigator.pushReplacementNamed(context, "/login"); + }, + ), + ], + ), + bottomNavigationBar: new TabBar( + tabs: [ + Tab( + text: "Todos", + icon: new Icon(Icons.edit), + ), + Tab( + text: "Feeds", + icon: new Icon(Icons.message), + ), + Tab( + text: "Online", + icon: new Icon(Icons.people), + ), + ], + labelColor: Colors.black, + unselectedLabelColor: Colors.grey, + indicatorSize: TabBarIndicatorSize.label, + indicatorPadding: EdgeInsets.all(5.0), + indicatorColor: Colors.blue, + ), + body: TabBarView( + physics: NeverScrollableScrollPhysics(), + children: [ + Todos(), + Feeds(), + Online(), + ], + ), + ), + ), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/login.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/login.dart new file mode 100644 index 00000000000..88aabe3f374 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/login.dart @@ -0,0 +1,129 @@ +import 'package:app_final/components/custom_button.dart'; +import 'package:app_final/components/utils.dart'; +import 'package:app_final/config/client.dart'; +import 'package:app_final/services/auth.dart'; +import 'package:app_final/services/shared_preferences_service.dart'; +import 'package:flutter/material.dart'; + +class Login extends StatefulWidget { + Login({Key key}) : super(key: key); + + _LoginState createState() => _LoginState(); +} + +class _LoginState extends State { + TextEditingController emailController = TextEditingController(); + TextEditingController passwordController = TextEditingController(); + final _formKey = GlobalKey(); + String _token = ""; + bool busyView = false; + + @override + Widget build(BuildContext context) { + if (!busyView) { + return Scaffold( + body: Center( + child: Form( + key: _formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + "ToDo App", + style: TextStyle(fontWeight: FontWeight.w800, fontSize: 38), + ), + Container( + width: MediaQuery.of(context).size.width / 1.3, + child: Column( + children: [ + TextFormField( + controller: emailController, + decoration: InputDecoration(labelText: "Email"), + keyboardType: TextInputType.emailAddress, + validator: (value) { + Pattern pattern = + r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'; + RegExp regex = new RegExp(pattern); + if (!regex.hasMatch(value)) + return 'Enter Valid Email'; + else + return null; + }, + ), + TextFormField( + controller: passwordController, + decoration: InputDecoration(labelText: "Password"), + validator: (value) { + return value.length < 4 + ? "Password must be at least 4 characters long" + : null; + }, + obscureText: true, + ), + ], + ), + ), + Column( + children: [ + CustomButton( + width: 180, + height: 50, + onTap: () async { + if (_formKey.currentState.validate()) { + setState(() { + busyView = true; + }); + _token = await hasuraAuth.login( + emailController.text, + passwordController.text, + ); + if (_token != null) { + UtilFs.showToast("Login Successful", context); + await sharedPreferenceService.setToken(_token); + Config.initailizeClient(); + Navigator.pushReplacementNamed( + context, "/dashboard"); + } else { + setState(() { + busyView = false; + }); + UtilFs.showToast("Login Failed", context); + FocusScope.of(context) + .requestFocus(new FocusNode()); + } + } + }, + text: "Login", + ), + Padding( + padding: const EdgeInsets.all(18.0), + child: GestureDetector( + onTap: () { + Navigator.pushNamed(context, "/signup"); + }, + child: Container( + height: 20, + child: Text( + "New? Sign Up", + style: + TextStyle(decoration: TextDecoration.underline), + ), + ), + ), + ) + ], + ) + ], + ), + ), + ), + ); + } else { + return Scaffold( + body: Center( + child: CircularProgressIndicator(), + ), + ); + } + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/signup.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/signup.dart new file mode 100644 index 00000000000..8136228f979 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/signup.dart @@ -0,0 +1,106 @@ +import 'package:app_final/components/custom_button.dart'; +import 'package:app_final/components/utils.dart'; +import 'package:app_final/services/auth.dart'; +import 'package:flutter/material.dart'; + +class Signup extends StatefulWidget { + Signup({Key key}) : super(key: key); + + _SignupState createState() => _SignupState(); +} + +class _SignupState extends State { + TextEditingController emailController = TextEditingController(); + TextEditingController passwordController = TextEditingController(); + final _formKey = GlobalKey(); + bool busyView = false; + + @override + Widget build(BuildContext context) { + if (!busyView) { + return Scaffold( + body: Center( + child: Form( + key: _formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + "ToDo App", + style: TextStyle(fontWeight: FontWeight.w800, fontSize: 38), + ), + Container( + width: MediaQuery.of(context).size.width / 1.3, + child: Column( + children: [ + TextFormField( + controller: emailController, + decoration: InputDecoration(labelText: "Email"), + keyboardType: TextInputType.emailAddress, + validator: (value) { + Pattern pattern = + r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'; + RegExp regex = new RegExp(pattern); + if (!regex.hasMatch(value)) + return 'Enter Valid Email'; + else + return null; + }, + ), + TextFormField( + controller: passwordController, + decoration: InputDecoration(labelText: "Password"), + validator: (value) { + return value.length < 4 + ? "Password must be at least 4 characters long" + : null; + }, + obscureText: true, + ), + ], + ), + ), + Column( + children: [ + CustomButton( + width: 180, + height: 50, + onTap: () async { + if (_formKey.currentState.validate()) { + setState(() { + busyView = true; + }); + if (await hasuraAuth.signup( + emailController.text, + passwordController.text, + )) { + UtilFs.showToast("SignUp Successful", context); + Navigator.pop(context); + } else { + FocusScope.of(context) + .requestFocus(new FocusNode()); + UtilFs.showToast("SignUp Failed", context); + } + setState(() { + busyView = false; + }); + } + }, + text: "SignUp", + ), + ], + ) + ], + ), + ), + ), + ); + } else { + return Scaffold( + body: Center( + child: CircularProgressIndicator(), + ), + ); + } + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/splash.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/splash.dart new file mode 100644 index 00000000000..a1bb3208b5d --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/splash.dart @@ -0,0 +1,28 @@ +import 'package:app_final/services/shared_preferences_service.dart'; +import 'package:flutter/material.dart'; + +class Splash extends StatelessWidget { + const Splash({ + Key key, + }) : super(key: key); + + initMethod(context) async { + await sharedPreferenceService.getSharedPreferencesInstance(); + String _token = await sharedPreferenceService.token; + if (_token == null || _token == "") { + Navigator.of(context).pushReplacementNamed('/login'); + } else + Navigator.of(context).pushReplacementNamed('/dashboard'); + } + + @override + Widget build(BuildContext context) { + WidgetsBinding.instance.addPostFrameCallback((_) => initMethod(context)); + + return Scaffold( + body: Center( + child: new CircularProgressIndicator(), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/feeds.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/feeds.dart new file mode 100644 index 00000000000..73aea53ead5 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/feeds.dart @@ -0,0 +1,180 @@ +import 'package:app_final/components/custom_button.dart'; +import 'package:app_final/components/feed_tile.dart'; +import 'package:app_final/data/feed_fetch.dart'; +import 'package:app_final/data/feed_list.dart'; +import 'package:flutter/material.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +class Feeds extends StatefulWidget { + const Feeds({Key key}) : super(key: key); + + @override + _FeedsState createState() => _FeedsState(); +} + +class _FeedsState extends State { + static int _lastLatestFeedId; + static int _oldestFeedId; + static int _newTodoCount = 0; + static int _previousId = 0; + static int _newId = 0; + GraphQLClient _client; + TextEditingController _controller = TextEditingController(); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + _client = GraphQLProvider.of(context).value; + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Mutation( + options: MutationOptions(document: FeedFetch.addPublicTodo), + builder: ( + RunMutation runMutation, + QueryResult result, + ) { + return Padding( + padding: const EdgeInsets.all(18.0), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: TextFormField( + controller: _controller, + decoration: InputDecoration( + labelText: "Say something ...", + border: OutlineInputBorder(), + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: CustomButton( + width: 90, + height: 50, + onTap: () { + runMutation({"title": _controller.text}); + //feedList.addFeed("You", _controller.text); + _controller.clear(); + FocusScope.of(context).requestFocus(new FocusNode()); + }, + text: "Post", + ), + ) + ], + ), + ); + }, + ), + Subscription( + "fetchNewNotification", + FeedFetch.fetchNewNotification, + builder: ({ + bool loading, + dynamic payload, + dynamic error, + }) { + if (payload != null) { + _newId = payload['todos'][0]['id']; + + if (_previousId != 0) { + _newTodoCount = _newTodoCount + (_newId - _previousId); + } else { + _lastLatestFeedId = _newId; + _client + .query( + QueryOptions( + document: FeedFetch.loadMoreTodos, + variables: {"oldestTodoId": _newId + 1}, + ), + ) + .then((onValue) { + for (var todo in onValue.data.data['todos']) { + feedList.addFeed(todo['id'].toString(), todo['title'], + todo['user']['name']); + } + setState(() {}); + // feedList.addFeed(username, feed) + }).catchError((onError) { + print(onError); + }); + } + _previousId = payload['todos'][0]['id']; + + if (_newTodoCount != 0) { + return CustomButton( + onTap: () { + _client + .query( + QueryOptions( + document: FeedFetch.newTodos, + variables: {"latestVisibleId": _lastLatestFeedId}, + ), + ) + .then((onValue) { + for (var todo in onValue.data.data['todos'].reversed) { + feedList.addfirstFeed(todo['id'].toString(), + todo['title'], todo['user']['name']); + } + _lastLatestFeedId = int.parse(feedList.list.first.id); + _newTodoCount = 0; + setState(() {}); + }).catchError((onError) { + print(onError); + }); + }, + height: 50, + text: " $_newTodoCount New Notification", + width: MediaQuery.of(context).size.width / 2, + ); + } else + return SizedBox(); + } else { + return SizedBox(); + } + }, + ), + Expanded( + child: ListView.builder( + itemCount: feedList.list.length, + itemBuilder: (context, index) { + return FeedTile( + username: feedList.list[index].username, + feed: feedList.list[index].feed); + }, + ), + ), + CustomButton( + onTap: () { + _oldestFeedId = int.parse(feedList.list.last.id); + _client + .query( + QueryOptions( + document: FeedFetch.loadMoreTodos, + variables: {"oldestTodoId": _oldestFeedId}, + ), + ) + .then((onValue) { + for (var todo in onValue.data.data['todos']) { + feedList.addFeed( + todo['id'].toString(), todo['title'], todo['user']['name']); + } + setState(() {}); + }).catchError((onError) { + print(onError); + }); + }, + height: 50, + text: "Load More", + width: MediaQuery.of(context).size.width / 3, + ) + ], + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/online.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/online.dart new file mode 100644 index 00000000000..3569aa2379c --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/online.dart @@ -0,0 +1,50 @@ +import 'package:app_final/data/online_fetch.dart'; +import 'package:app_final/data/online_list.dart'; +import 'package:flutter/material.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +class Online extends StatelessWidget { + const Online({Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: Text( + "Online Users", + style: TextStyle(fontSize: 28), + ), + ), + Subscription( + "fetchOnlineUsers", + OnlineFetch.fetchUsers, + builder: ({ + bool loading, + dynamic payload, + dynamic error, + }) { + if (payload != null) { + return Expanded( + child: ListView.builder( + itemCount: payload['online_users'].length, + itemBuilder: (context, index) { + return Card( + child: ListTile( + title: Text( + payload['online_users'][index]['user']['name']), + ), + ); + }, + ), + ); + } else { + return Text("Fetching Online Users"); + } + }, + ), + ], + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/todos.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/todos.dart new file mode 100644 index 00000000000..2ea9a737ace --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/dashboard/todos.dart @@ -0,0 +1,43 @@ +import 'package:app_final/screens/tabs/todos/active.dart'; +import 'package:app_final/screens/tabs/todos/all.dart'; +import 'package:app_final/screens/tabs/todos/completed.dart'; +import 'package:flutter/material.dart'; + +class Todos extends StatefulWidget { + Todos({Key key}) : super(key: key); + + _TodosState createState() => _TodosState(); +} + +class _TodosState extends State { + @override + Widget build(BuildContext context) { + return DefaultTabController( + length: 3, + child: Scaffold( + appBar: AppBar( + title: TabBar( + tabs: [ + Tab( + text: "All", + ), + Tab( + text: "Active", + ), + Tab( + text: "Completed", + ), + ], + ), + ), + body: TabBarView( + children: [ + All(), + Active(), + Completed(), + ], + ), + ), + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/active.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/active.dart new file mode 100644 index 00000000000..7b73adb048f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/active.dart @@ -0,0 +1,84 @@ +import 'package:app_final/components/add_task.dart'; +import 'package:app_final/components/todo_item_tile.dart'; +import 'package:app_final/data/todo_fetch.dart'; +import 'package:app_final/data/todo_list.dart'; +import 'package:app_final/model/todo_item.dart'; +import 'package:flutter/material.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +class Active extends StatefulWidget { + const Active({Key key}) : super(key: key); + + @override + _ActiveState createState() => _ActiveState(); +} + +class _ActiveState extends State { + VoidCallback refetchQuery; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Mutation( + options: MutationOptions(document: TodoFetch.addTodo), + builder: ( + RunMutation runMutation, + QueryResult result, + ) { + return AddTask( + onAdd: (value) { + runMutation({'title': value, 'isPublic': false}); + todoList.addTodo(value); + }, + ); + }, + update: (Cache cache, QueryResult result) { + return cache; + }, + onCompleted: (dynamic resultData) { + refetchQuery(); + }, + ), + Expanded( + child: Query( + options: QueryOptions( + document: TodoFetch.fetchActive, + ), + builder: (QueryResult result, {VoidCallback refetch}) { + refetchQuery = refetch; + if (result.errors != null) { + return Text(result.errors.toString()); + } + if (result.loading) { + return Text('Loading'); + } + final List todos = + (result.data['todos'] as List).cast(); + return ListView.builder( + itemCount: todos.length, + itemBuilder: (context, index) { + dynamic responseData = todos[index]; + return TodoItemTile( + item: TodoItem.fromElements(responseData["id"], + responseData['title'], responseData['is_completed']), + toggleDocument: TodoFetch.toggleTodo, + toggleRunMutaion: { + 'id': responseData["id"], + 'isCompleted': !responseData['is_completed'] + }, + deleteDocument: TodoFetch.deleteTodo, + deleteRunMutaion: { + 'id': responseData["id"], + }, + refetchQuery: refetch, + ); + }, + ); + }, + ), + ), + ], + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/all.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/all.dart new file mode 100644 index 00000000000..b0b714864b8 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/all.dart @@ -0,0 +1,106 @@ +import 'package:app_final/components/add_task.dart'; +import 'package:app_final/components/todo_item_tile.dart'; +import 'package:app_final/data/online_fetch.dart'; +import 'package:app_final/data/todo_fetch.dart'; +import 'package:app_final/model/todo_item.dart'; +import 'package:flutter/material.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +class All extends StatefulWidget { + All({Key key}) : super(key: key); + + @override + _AllState createState() => _AllState(); +} + +class _AllState extends State { + static GraphQLClient _client; + runOnlineMutation(context) { + _client = GraphQLProvider.of(context).value; + Future.doWhile( + () async { + _client.mutate( + MutationOptions( + document: OnlineFetch.updateStatus, + variables: { + 'now': DateTime.now().toUtc().toIso8601String(), + }, + ), + ); + await Future.delayed(Duration(seconds: 30)); + return true; + }, + ); + } + + @override + void initState() { + WidgetsBinding.instance + .addPostFrameCallback((_) => runOnlineMutation(context)); + super.initState(); + } + + VoidCallback refetchQuery; + @override + Widget build(BuildContext context) { + return Column( + children: [ + Mutation( + options: MutationOptions(document: TodoFetch.addTodo), + builder: ( + RunMutation runMutation, + QueryResult result, + ) { + return AddTask( + onAdd: (value) { + runMutation({'title': value, 'isPublic': false}); + }, + ); + }, + onCompleted: (dynamic resultData) { + refetchQuery(); + }, + ), + Expanded( + child: Query( + options: QueryOptions( + document: TodoFetch.fetchAll, + variables: {"is_public": false}, + ), + builder: (QueryResult result, {VoidCallback refetch}) { + refetchQuery = refetch; + if (result.errors != null) { + return Text(result.errors.toString()); + } + if (result.loading) { + return Text('Loading'); + } + final List todos = + (result.data['todos'] as List).cast(); + return ListView.builder( + itemCount: todos.length, + itemBuilder: (context, index) { + dynamic responseData = todos[index]; + return TodoItemTile( + item: TodoItem.fromElements(responseData["id"], + responseData['title'], responseData['is_completed']), + toggleDocument: TodoFetch.toggleTodo, + toggleRunMutaion: { + 'id': responseData["id"], + 'isCompleted': !responseData['is_completed'] + }, + deleteDocument: TodoFetch.deleteTodo, + deleteRunMutaion: { + 'id': responseData["id"], + }, + refetchQuery: refetchQuery, + ); + }, + ); + }, + ), + ), + ], + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/completed.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/completed.dart new file mode 100644 index 00000000000..910c8471cbb --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/screens/tabs/todos/completed.dart @@ -0,0 +1,81 @@ +import 'package:app_final/components/add_task.dart'; +import 'package:app_final/components/todo_item_tile.dart'; +import 'package:app_final/data/todo_fetch.dart'; +import 'package:app_final/data/todo_list.dart'; +import 'package:app_final/model/todo_item.dart'; +import 'package:flutter/material.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +class Completed extends StatefulWidget { + const Completed({Key key}) : super(key: key); + + @override + _CompletedState createState() => _CompletedState(); +} + +class _CompletedState extends State { + VoidCallback refetchQuery; + @override + Widget build(BuildContext context) { + return Column( + children: [ + Mutation( + options: MutationOptions( + document: TodoFetch + .addTodo // this is the mutation string you just created + ), + builder: ( + RunMutation runMutation, + QueryResult result, + ) { + return AddTask( + onAdd: (value) { + runMutation({'title': value, 'isPublic': false}); + todoList.addTodo(value); + }, + ); + }, + onCompleted: (dynamic resultData) { + refetchQuery(); + }, + ), + Expanded( + child: Query( + options: QueryOptions( + document: TodoFetch.fetchCompleted, + ), + builder: (QueryResult result, {VoidCallback refetch}) { + if (result.errors != null) { + return Text(result.errors.toString()); + } + if (result.loading) { + return Text('Loading'); + } + return ListView.builder( + itemCount: result.data['todos'].length, + itemBuilder: (context, index) { + refetchQuery = refetch; + dynamic responseData = result.data['todos'][index]; + return TodoItemTile( + item: TodoItem.fromElements(responseData["id"], + responseData['title'], responseData['is_completed']), + toggleDocument: TodoFetch.toggleTodo, + toggleRunMutaion: { + 'id': responseData["id"], + 'isCompleted': !responseData['is_completed'] + }, + deleteDocument: TodoFetch.deleteTodo, + deleteRunMutaion: { + 'id': responseData["id"], + }, + refetchQuery: refetchQuery, + ); + }, + ); + }, + ), + ), + ], + ); + } +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/services/auth.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/services/auth.dart new file mode 100644 index 00000000000..812ad7da92b --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/services/auth.dart @@ -0,0 +1,51 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; + +class HasuraAuth { + Future login(String username, String password) async { + String _token; + Map credentials = { + "username": username, + "password": password, + }; + http.Response response = await http + .post( + "https://learn.hasura.io/auth/login", + headers: {"content-type": "application/json"}, + body: jsonEncode(credentials), + ) + .catchError((onError) { + print(onError); + return null; + }); + if (response == null) { + return null; + } + _token = jsonDecode(response.body)["token"]; + return _token; + } + + Future signup(String username, String password) async { + bool success = false; + Map credentials = { + "username": username, + "password": password, + }; + http.Response response = await http + .post( + "https://learn.hasura.io/auth/signup", + headers: {"content-type": "application/json"}, + body: jsonEncode(credentials), + ) + .catchError((onError) { + return null; + }); + if (response == null) { + return success; + } + success = jsonDecode(response.body)["id"] != null; + return success; + } +} + +HasuraAuth hasuraAuth = new HasuraAuth(); diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/services/shared_preferences_service.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/services/shared_preferences_service.dart new file mode 100644 index 00000000000..386dd155de7 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/lib/services/shared_preferences_service.dart @@ -0,0 +1,25 @@ +import 'package:shared_preferences/shared_preferences.dart'; + +class SharedPreferenceService { + SharedPreferences _prefs; + + Future getSharedPreferencesInstance() async { + _prefs = await SharedPreferences.getInstance().catchError((e) { + print("shared prefrences error : $e"); + return false; + }); + return true; + } + + Future setToken(String token) async { + await _prefs.setString('token', token); + } + + Future clearToken() async { + await _prefs.clear(); + } + + Future get token async => _prefs.getString('token'); +} + +SharedPreferenceService sharedPreferenceService = SharedPreferenceService(); diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/pubspec.lock b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/pubspec.lock new file mode 100644 index 00000000000..9896acb444c --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/pubspec.lock @@ -0,0 +1,238 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.11" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + graphql: + dependency: transitive + description: + name: graphql + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + graphql_flutter: + dependency: "direct main" + description: + name: graphql_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + graphql_parser: + dependency: transitive + description: + name: graphql_parser + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.3" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.0+2" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.3" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.6+3" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.2" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.22.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.3+1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.5" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.5" + toast: + dependency: "direct main" + description: + name: toast + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" +sdks: + dart: ">=2.2.2 <3.0.0" + flutter: ">=1.5.0 <2.0.0" diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/pubspec.yaml b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/pubspec.yaml new file mode 100644 index 00000000000..11bdb45c44f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/pubspec.yaml @@ -0,0 +1,76 @@ +name: app_final +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + http: ^0.12.0+2 + toast: ^0.1.3 + shared_preferences: ^0.5.3+1 + graphql_flutter: ^1.0.1 + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/test/widget_test.dart b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/test/widget_test.dart new file mode 100644 index 00000000000..38537d0151c --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/app-final/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:app_final/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/Dockerfile b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/Dockerfile new file mode 100644 index 00000000000..fc87f035866 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/Dockerfile @@ -0,0 +1,30 @@ +FROM node:carbon + +# update this line when gatsby-gitbook-starter repo changes +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' + +# Install global dependencies +RUN npm -g install gatsby-cli + +# clone gatsby-gitbook-starter +RUN git clone https://github.com/hasura/gatsby-gitbook-starter.git + +# Create app directory +WORKDIR /gatsby-gitbook-starter + +RUN cd /gatsby-gitbook-starter + +# Install dependencies +RUN npm install + +# Remove already existing dummy content +RUN rm -R content + +# Bundle app source +COPY . . + +# Build static files +RUN npm run build + +# serve dist folder on port 8080 +CMD ["gatsby", "serve", "--verbose", "--prefix-paths", "-p", "8080", "--host", "0.0.0.0"] diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/Dockerfile.localdev b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/Dockerfile.localdev new file mode 100644 index 00000000000..553c99654cf --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/Dockerfile.localdev @@ -0,0 +1,27 @@ +FROM node:carbon + +# update this line when gatsby-gitbook-starter repo changes +RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"' + +# Install global dependencies +RUN npm -g install gatsby-cli + +# clone gatsby-gitbook-starter +RUN git clone https://github.com/hasura/gatsby-gitbook-starter.git + +# Create app directory +WORKDIR /gatsby-gitbook-starter + +RUN cd /gatsby-gitbook-starter + +# Install dependencies +RUN npm install + +# Remove already existing dummy content +RUN rm -R content + +# Bundle app source +COPY . . + +# serve on port 8080 +CMD ["gatsby", "develop", "--verbose", "-p", "8080", "--host", "0.0.0.0"] diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/README.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/README.md new file mode 100755 index 00000000000..3d4ffaa494c --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/README.md @@ -0,0 +1,18 @@ +## Development + +#### Build Docker Image +```bash +docker build -t tutorial-site:0.1 -f Dockerfile.localdev . +``` + +#### Run Container in Dev Mode + +```bash +docker run -ti -p 8080:8080 -v /path/to/graphql-engine/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content:/gatsby-gitbook-starter/content -v /path/to/graphql-engine/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/config.js:/gatsby-gitbook-starter/config.js tutorial-site:0.1 +``` + +Two volumes are mounted. One for `content` and one for `config.js`. This is required for hot-reloading. + +Restart docker container +- In case there are new files +- Gatsby cache needs to be updated diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/config.js b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/config.js new file mode 100644 index 00000000000..7a0e69b76fd --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/config.js @@ -0,0 +1,55 @@ +const config = { + "gatsby": { + "pathPrefix": "/graphql/flutter-graphql", + "siteUrl": "https://learn.hasura.io", + "gaTrackingId": "UA-59768903-1" + }, + "header": { + "logo": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/logo.png", + "logoLink": "https://learn.hasura.io", + "title": "/ graphql / flutter", + "githubUrl": "https://github.com/hasura/graphql-engine", + "helpUrl": "https://discordapp.com/invite/vBPpJkS", + "tweetText": "Check out this GraphQL course for Flutter developers by @HasuraHQ https://learn.hasura.io/graphql/flutter-graphql", + "links": [{ + "text": "hasura.io", + "link": "https://hasura.io" + }], + }, + "sidebar": { + "forcedNavOrder": [ + "/introduction", + "/intro-to-graphql", + "/setup", + "/graphql-client", + "/queries", + "/mutations", + "/update-delete-mutations", + "/subscriptions", + "/realtime-feed", + "/logout", + "/what-next" + ], + "links": [ + { + "text": "Hasura Docs", + "link": "https://docs.hasura.io" + }, + { + "text": "GraphQL Docs", + "link": "https://graphql.org/learn" + } + ], + "frontline": false, + "ignoreIndex": true + }, + "siteMetadata": { + "title": "2 hour GraphQL course for Flutter developers | Hasura", + "description": "A concise and powerful tutorial that covers fundamental concepts of both GraphQL and using GraphQL in Flutter", + "ogImage": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/social-media/twitter-card-flutter.png", + "docsLocation": "https://github.com/hasura/graphql-engine/tree/master/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content", + "favicon": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-flutter/flutter-favicon.png" + }, +}; + +module.exports = config; diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/graphql-client.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/graphql-client.md new file mode 100644 index 00000000000..d250e54a7f4 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/graphql-client.md @@ -0,0 +1,76 @@ +--- +title: "Set up a GraphQL client" +metaTitle: "Flutter GraphQL Package Setup | GraphQL Flutter Tutorial" +metaDescription: "You will learn how to configure GraphQL Package in Flutter by importing graphql_flutter dependency" +--- + +graphql_flutter plugin gives a neat abstraction layer and an interface to your GraphQL server. You don't need to worry about constructing your queries with request body, headers and options, that you might have done with `http` or `dio` say. You can directly write queries and mutations in GraphQL and they will automatically be sent to your server via your client instance. + +To setup graphql_flutter,Add `graphql_flutter: ^1.0.1` dependency to your `pubspec.yaml` + +```yaml +dependencies: + flutter: + sdk: flutter + http: ^0.12.0+2 + toast: ^0.1.3 + shared_preferences: ^0.5.3+1 ++ graphql_flutter: ^1.0.1 +``` + +Lets first create GraphQl client which we will need to configure our app. Our app requires both http link for queries, mutations and websocket link for subscriptions. + +To do this create a file named `client.dart` inside `lib/config` folder and add the following code inside it. + +```dart ++ import 'package:flutter/material.dart'; ++ import 'package:app_final/services/shared_preferences_service.dart'; ++ import 'package:graphql_flutter/graphql_flutter.dart'; ++ class Config { ++ static final HttpLink httpLink = HttpLink( ++ uri: 'https://learn.hasura.io/graphql', ++ ); ++ ++ static final AuthLink authLink = ++ AuthLink(getToken: () async => await sharedPreferenceService.token); ++ ++ static final WebSocketLink websocketLink = ++ WebSocketLink( ++ url: 'wss://learn.hasura.io/graphql', ++ config: SocketClientConfig( ++ autoReconnect: true, ++ inactivityTimeout: Duration(seconds: 30), ++ ), ++ ); ++ ++ static final Link link = ++ authLink.concat(httpLink as Link).concat(websocketLink); ++ ++ static ValueNotifier initailizeClient() { ++ ValueNotifier client = ++ ValueNotifier( ++ GraphQLClient( ++ cache: OptimisticCache(dataIdFromObject:typenameDataIdFromObject), ++ link: link, ++ ), ++ ); ++ return client; ++ } ++ } +``` + +In the above code we are creating `httpLink`, `authLink` and `websocketLink` and concatinating them to variable type `Link` link. In function named `initailizeClient` we are configuring our `client` using `GraphQLClient` widget provided by package itself and returning a instance of type `ValueNotifier`. + +Now, to add GraphQL provider to our app we have to wrap our parent widget (i.e. `DefaultTabController` inside lib/screens/dashboard.dart) with `GraphQLProvider` widget. `GraphQLProvider` takes `client` and `child` as parameter and we already created a function (`initailizeClient`) which is returning `client`. To do this modify your dashboard.dart as follows + +```dart +- return DefaultTabController( ++ return GraphQLProvider( ++ client: Config.initailizeClient(), ++ child: CacheProvider( ++ child: DefaultTabController( + . . . ++ ), ++ ), + ); +``` diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/index.mdx b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/index.mdx new file mode 100644 index 00000000000..183496bc232 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/index.mdx @@ -0,0 +1,26 @@ +--- +title: "Introduction" +--- + +This tutorial is for Flutter developers to learn what GraphQL is and how to use GraphQL in Flutter applications. +It is ideal if you follow along with code and should not take you more than a few hours to finish end to end. + +## What do I need to take this tutorial? +Your dev environment set up to build flutter apps. If you can run `flutter run` you're good to go! + +## How long will this tutorial take? +Less than 2 hours + +## What you'll be able to do after this tutorial +Use (realtime) GraphQL in your flutter app. + +## Who is this tutorial for +You should know the basics of how to build a Flutter app. + +## Topics covered in this tutorial +- Introduction to GraphQL +- Using graphql_flutter package +- GraphQL queries +- GraphQL mutations & variables +- GraphQL subscriptions +- Making direct GraphQL API calls without package higher-order-widgets diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql.md new file mode 100644 index 00000000000..77c055db4d2 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql.md @@ -0,0 +1,87 @@ +--- +title: "Intro to GraphQL" +metaTitle: "Intro to GraphQL | GraphQL Flutter Tutorial" +metaDescription: "What is GraphQL? GraphQL is a specification for how to talk to an API. This part also covers GraphQL vs REST with an example and takes you over benefits of GraphQL" +--- + +## What is GraphQL? +GraphQL is a specification for how to talk to an API. It's typically used over HTTP where the key idea is to `POST` a "query" to an HTTP endpoint, instead of hitting different HTTP endpoints for different resources. + +GraphQL is designed for developers of web/mobile apps (HTTP clients) to be able to make API calls to fetch the data they need from their backend APIs conveniently. + +## GraphQL vs REST: an example +Let's say you have an API to fetch a user's profile and their address. In a typical REST scenario, this is what the request/response would look like: + +![GraphQL API example](https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-react/rest-api.png) + +If your API server was a GraphQL server instead, this is what your API calls would look like: + +![GraphQL API example](https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-react/graphql-api.gif) + +You can see that the response JSON is different for different "queries" sent by the client. + +``` +Request1: | Response1: + +query { | { + user (id: 1) { | "user": { + id | "id": 1 + } | } +} | } + +---------------------------------------- + +Request2: | Response2: + +query { | { + user (id: 1) { | "user": { + id | "id": 1 + name | "name": "Elmo" + } | } +} | } +``` + +## Thinking in GraphQL + +We're changing the way we think about API calls. Instead of making different API +calls to different URLs to fetch data, we're making ad-hoc queries to a "single +URL endpoint" that returns data based on the query. +- Instead of 'GET'ing a resource you 'POST' a query that describes what data you + want. +- You think of the data your API returns as a "graph", this allows you to make + queries to fetch "related" pieces of data in a single shot. In the example + above, you fetch the user and the user's address (as a nested JSON object) + in the same API call, as opposed to making 2 API calls. +- The "query" you send as data in the POST request has a structure and a syntax. + This "language" is called GraphQL. + +As you can see in the example above, GraphQL queries look very neat and easy to +read! This is because the query is the "shape" of the final JSON data you desire. +This is one of the key-reasons that makes GraphQL a joy to work with! + +## GraphQL benefits + +- **Avoid over-fetching**: You avoid fetching more data than you need because you + can specify the exact **fields** you need. +- **Prevent multiple API calls**: In case you need more data, you can also avoid + making multiple calls to your API. In the case above, you don't need to make + 2 API calls to fetch `user` and `address` separately. +- **Lesser communication with API developers**: Sometimes to fetch the exact data + you need, especially if you need to fetch more data and want to avoid multiple API + calls, you will need to ask your API developers to build a new API. With GraphQL, + your work is *independent* of the API team! This allows you to work faster on your + app. +- **Self-documenting**: Every GraphQL API conforms to a "schema" which is the graph + data model and what kinds of queries a client can make. This allows the community + to build lots of cool tools to explore & visualise your API or create IDE plugins + that autocomplete your GraphQL queries and even do "codegen". We'll understand this + in more detail later! + +Here's a quick chart to show you the GraphQL analogs of typical REST-ish terms: + +| Requirement | REST | GraphQL | +| :-- | :-- | :-- | +| Fetching data objects | GET | query | +| Writing data | POST | mutation | +| Updating/deleting data | PUT/PATCH/DELETE | mutation | +| Watching/subscribing to data | - | subscription | diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/1-architecture.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/1-architecture.md new file mode 100644 index 00000000000..e8483192993 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/1-architecture.md @@ -0,0 +1,62 @@ +--- +title: "Architecture" +order: 1 +metaTitle: "GraphQL Architecture | GraphQL Flutter Tutorial" +metaDescription: "Learn about the architecture of GraphQL, GraphQL over HTTP, the client server model with an example of http request" +--- + +Before going further in understanding GraphQL, it's useful to get a sense of how +GraphQL is actually used in an HTTP client (typically a web/mobile app). + +## GraphQL over HTTP +Check out the diagram below, to get a sense of how GraphQL is typically used in +your stack: + +![GraphQL over HTTP](https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-react/graphql-on-http.png) + +### GraphQL client-server flow: + +1. Note that the GraphQL query is not really JSON; it looks like the shape of the + JSON you *want*. So when we make a 'POST' request to send our GraphQL query to + the server, it is sent as a "string" by the client. +2. The server gets the JSON object and extracts the query string. As per the + GraphQL syntax and the graph data model (GraphQL schema), the server processes + and validates the GraphQL query. +3. Just like a typical API server, the GraphQL API server then makes calls to a + database or other services to fetch the data that the client requested. +4. The server then takes the data and returns it to the client in a JSON object. + +### Example GraphQL client setup: + +In your day to day work, you don't actually need to worry about the underlying +HTTP requests & responses. + +Just like when you work with a REST API and use a HTTP +client to reduce the boilerplate in making API calls and handling responses, you +can choose a GraphQL client to make writing GraphQL queries, sending them and +handling responses much easier. + +In fact, the mechanism of how you send the GraphQL query and accept the GraphQL +response has become standard. This makes working with GraphQL very easy on the +client. + +Here's what a typical GraphQL client setup and making a query would look like: + +```javascript + +// Setup a GraphQL client to use the endpoint + +const client = new client("https://myapi.com/graphql"); + + +// Now, send your query as a string (Note that ` is used to create a multi-line +// string in javascript). + +client.query(` + query { + user { + id + name + } + }`); +``` diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/2-fetching-data-queries.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/2-fetching-data-queries.md new file mode 100644 index 00000000000..d566ff14884 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/2-fetching-data-queries.md @@ -0,0 +1,206 @@ +--- +title: Fetching data - Queries +metaTitle: "GraphQL Queries to fetch data | GraphQL Flutter Tutorial" +metaDescription: "Try out GraphQL Query using GraphiQL. A GraphQL query example with parameters, arguments and variables to fetch data dynamically" +--- + + +## Try out GraphQL queries +For this tutorial we've set up a GraphQL API for you. The most common +way to browse a GraphQL API is to use GraphiQL. GraphiQL is a tool +built by Facebook, (pronounced "graphical") that makes it easy to explore +any GraphQL API. + +When you connect GraphiQL to a GraphQL endpoint, it +queries the server for its GraphQL schema and gives you a UI to browse +and test queries, and that powers its amazing autocomplete! + +![GraphiQL demo](https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-react/graphiql.gif) + +Tools like GraphiQL make GraphQL APIs really easy +to use and integrate APIs in your app without requiring +external documentation tools. + +You can access the GraphiQL for this realtime todo app tutorial here: +[learn.hasura.io/graphql/graphiql?tutorial=react-native](https://learn.hasura.io/graphql/graphiql?tutorial=react-native) + +When you work with a GraphQL API in a project you will almost always +use a tool like GraphiQL to explore and test your GraphQL queries. + +## Basic GraphQL query + +1. Open GraphiQL at: [learn.hasura.io/graphql/graphiql?tutorial=react-native](https://learn.hasura.io/graphql/graphiql?tutorial=react-native). + You'll have to login to get an auth token to query the API. In a real-world scenario + your GraphQL APIs will be protected. +2. You'll see a URL, and headers that contain the auth + token that will be sent along with your GraphQL query. +3. Now, paste this GraphQL query in the GraphiQL window + +```graphql + query { + users { + name + } + } +``` + +4. Hit `ctrl + enter` or `cmd + enter` (mac) or click on the ▶️ icon to run the GraphQL query +5. On the right, you should see a list of users by their names that are in the system! + +Try it out in GraphiQL + +Recall that there is no magic here! The hosted GraphiQL app is sending a GraphQL query string +to the server at the given endpoint with the HTTP headers. The server then sends the response +that you see on the right hand side. + +## Fetching "graphs" + +Our todo app has users, todos and information about users that are currently online. +This is what our API "schema" looks like: + +![Schema](https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-react/schema.png) + +As you can see, it is a "graph" like schema where all the 3 models are linked to each other. + +Let's try making queries that fetch different slices of our data from the overall "graph". + +### Fetch users and their todos + +This GraphQL query will fetch all the users and their publicly visible todos: + +```graphql + query { + users { + name + todos { + title + } + } + } +``` + +Try it out in GraphiQL + + +### Fetch online users and their profile information + +This GraphQL query will fetch all the currently online users +and their profile information (which is just their name for now): + +```graphql + query { + online_users { + last_seen + user { + name + } + } + } +``` + +Try it out in GraphiQL + + +## Adding parameters (arguments) to GraphQL queries + +In most API calls, you usually use parameters. For example, to specify what data you're fetching. +If you're familiar with making `GET` calls, you would have used a query parameter. For example, +to fetch only 10 todos you might have made this API calls: `GET /api/todos?limit=10`. + +The GraphQL query analog of this is *arguments* that you can attach to a "field". + +### Basic argument: Fetch 10 todos + +This GraphQL query will fetch 10 todos and not all of them. + +```graphql +query { + todos(limit: 10) { + id + title + } +} +``` + +Try it out in GraphiQL + +The most important bit to check here is `limit: 10`. GraphQL servers will provide a list of +arguments that can be used in `()` next to specific fields. In our case, we are using +Hasura for creating the GraphQL backend which provides filter, sort and pagination arguments. +The GraphQL server or API that you use, might provide a different set of arguments that can be used. + +### Multiple arguments on multiple fields: Fetch 1 user and 5 most recent todos for each user + +```graphql +query { + users (limit: 1) { + id + name + todos(order_by: {created_at: desc}, limit: 5) { + id + title + } + } +} +``` + +Notice that we are passing arguments to different fields. This GraphQL query reads as: +> Fetch users (with limit 1), and their todos (ordered by descending creation time, and limited to 5). + +Try it out in GraphiQL + + +## GraphQL variables: Passing arguments to your queries dynamically + +This is great, but we still have a problem. If we want to create a query +where we are fetching data with arguments that are provided dynamically, we'd have to +create the entire query string again. + +This is what we don't want to do: + +```javascript +var limit = getMaxTodosFromUserInput(); +var query = "query { todos (limit: " + limit.toString() + ") {id title} }"; +``` + +Thankfully, we don't ever have to do this! GraphQL variables are extra variables +that you can send in a query so that the "arguments" can be provided dynamically! + +## Fetch $limit number of todos + +This is what our GraphQL query would look like: +```graphql +query ($limit: Int!) { + todos(limit: $limit) { + id + title + } +} +``` + +In addition to the query above, we send a variables object: +```json +{ + "limit": 10 +} +``` + +Now instead of sending just the query to the GraphQL server, from our client +we'll send both the query and the variables. The GraphQL server will use the +variable in the right place in the query automatically for us! + +Let's try this out in GraphiQL: +1. Head to GraphiQL +2. Write out this query +3. Scroll to the bottom of the page, where you see a smaller panel "Query Variables" +4. Add the query variable as a JSON object + +Try it out in GraphiQL + +## Summary + +- You can now make GraphQL queries +- You know how to pass arguments to your GraphQL queries +- You know how to make your arguments dynamic by using query variables + +Next, let's look at writing data and not just fetching data! diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/3-writing-data-mutations.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/3-writing-data-mutations.md new file mode 100644 index 00000000000..dd313529094 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/3-writing-data-mutations.md @@ -0,0 +1,122 @@ +--- +title: Writing data - Mutations +metaTitle: "GraphQL Mutations to insert data | GraphQL Flutter Tutorial" +metaDescription: "Try out GraphQL Mutation using GraphiQL. A GraphQL mutation example with dynamic arguments and variables to insert data" +--- + +import {Link} from 'gatsby'; + +These are the concepts you should know before you attack mutations (haha): + +- Using GraphiQL +- Using query variables + +Now, let's get started with seeing how we can use GraphQL to "write" data. +GraphQL mutations are types of GraphQL queries that may result in the state +of your backend "mutating" or changing, just like typical `'POST'`, +`'PUT'`, `'PATCH'`, `'DELETE'` APIs. + +## Basic mutations + +Since we're using Hasura for our GraphQL API, we get mutations for +insert, updates or deletes that we can use in our app. + +Let's try these mutations out in the context of a todo app to see +what mutations look like. Mutations that you get from another GraphQL +service, say if your API team has built their own, might be different. + +### Create a todo + +Let's make an API call to create a todo. As you would have guessed, this +will be a critical portion of our todo app. 😉 + +> **Protip**: Now let's say we don't know what the name of the mutation to +> create a todo. GraphiQL to the rescue! +> Head to GraphiQL and on the right, click on the "docs" tab. +> Type "todo" there and you'll see a list of GraphQL queries and types +> that use todo. Read through their descriptions and you'll soon +> find that `insert_todo` is what you need. + +The mutation to create todos is titled `insert_todos`. + +```graphql +mutation { + insert_todos(objects: [{ title: "new todo" }]) { + returning { + id + } + } +} +``` + + + +Try it out in GraphiQL + +## Returning data after the mutation + +Notice that the data of the todo that is to be inserted is sent as +an argument to the `insert_todos` mutation. But the "fields" of the mutation +specify the shape of the _response_ that you want from the server. + +Let's say we'd like to get the entire todo object once it's been created +as a response: + +```graphql +mutation { + insert_todos(objects: [{ title: "new todo" }]) { + returning { + id + title + is_completed + is_public + created + } + } +} +``` + + + +Try it out in GraphiQL + +## Parametrise what you insert + +For mutations, we would almost always have to paramatrise the arguments! We +would rarely, if ever, have a "hardcoded" mutation in our app. This is because +the arguments of what data to capture, how to modify or delete something is usually +dependent on some user action. + +Now that we know how to parametrise using query variables, let's use that: + +```graphql +# The parametrised GraphQL mutation +mutation($title: String!) { + insert_todos(objects: [{ title: $title, is_public: true }]) { + returning { + id + } + } +} +``` + +```javascript +# As a query variable +{ + "title": "Hello World" +} +``` + + + +Try it out in GraphiQL + +We'll explore more mutations to update or delete data a little later. +This is a good start to grokking mutations! + +## Summary + +- You can make basic GraphQL mutations +- You can pass dynamic arguments/data to mutations with query variables + +Next, let's look at GraphQL subscriptions diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/4-watching-data-subscriptions.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/4-watching-data-subscriptions.md new file mode 100644 index 00000000000..1caa65ca31c --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/intro-to-graphql/4-watching-data-subscriptions.md @@ -0,0 +1,48 @@ +--- +title: Watching data - Subscriptions +metaTitle: "GraphQL Subscriptions for realtime data | GraphQL Flutter Tutorial" +metaDescription: "Try out GraphQL Subscription using GraphiQL. A GraphQL subscriptions example to fetch live data pushed over websockets " +--- + +The GraphQL specification allows for something called subscriptions that are like GraphQL queries +but instead of returning data in one read, you get data pushed from the server. + +This is useful for your app to subscribe to "events" or "live results" from the backend, but +while allowing you to control the "shape" of the event from your app. + +GraphQL subscriptions are a critical widget for adding realtime features +to your apps easily. GraphQL clients and servers that support subscriptions are great because +they allow you to build great experiences without having to deal with websocket code! + +## Make your first GraphQL subscription + +1. Step 1: Head to https://learn.hasura.io/graphql/graphiql?tutorial=react-native +2. Step 2: Write this GraphQL query in the textarea: + +```graphql +subscription { + online_users { + id + last_seen + user { + name + } + } +} +``` + +3. Every time the set of online users change, you'll see the latest set on +the response window on the right + +## How do GraphQL subscriptions work? + +GraphQL queries and mutations are strings sent to a POST endpoint. What is a GraphQL subscription? That can't happen over a POST endpoint, because a simple HTTP endpoint would just return the response and the connection would close. + +A GraphQL subscription is a subscription query string sent to a websocket endpoint. And whenever data changes on the backend, new data is pushed over websockets from the server to the client. + +## Summary + +- You know how to make GraphQL subscriptions + +Now that you're comfortable with the basics of using GraphQL, let's start +integrating GraphQL APIs with an app! diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/introduction.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/introduction.md new file mode 100644 index 00000000000..2063c301006 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/introduction.md @@ -0,0 +1,57 @@ +--- +title: "Course introduction" +metaTitle: "Course Introduction | GraphQL Flutter Tutorial" +metaDescription: "A powerful and concise tutorial that will introduce you to GraphQL and integrating GraphQL into your Flutter app with graphql_flutter package, in the shortest amount of time possible." +--- + +import CommunityAuthor from '../src/CommunityAuthor'; + +GraphQL is becoming the new way to use APIs in modern web and mobile apps. + +However, learning new things always takes time and without getting your hands dirty, it’s very hard to understand the nuances of a new technology. + +So, we put together a powerful and concise course that will introduce you to GraphQL and integrating GraphQL into your frontend stack, in the shortest amount of time possible. + +We will explore the fundamentals of GraphQL and the things that make GraphQL especially suitable for modern applications, like its realtime capabilities! The course is light on opinions so that once you grok the fundamentals you can go on to choose your favorite libraries, tools and tailor your workflow. + +## Key topics and takeways: + +- GraphQL vs REST +- GraphQL queries, mutations, subscriptions +- Setting up a GraphQL client +- Integrating GraphQL queries in your flutter app +- Integrating GraphQL mutations in your app to change data on the server +- Updating local state after a GraphQL mutation (TextInput) using cache +- Automatic updates to local state and UI after mutations +- Using subscriptions with subscription components +- Building a real-time feed with notifications using mutations and subscriptions + +## What will we be building? + +We will be building a realtime todo app using authenticated GraphQL APIs. + +## Will this course teach Flutter as well? + +No, we will be simulating a scenario where we already have a GraphQL API and the basic UI of a flutter app built. Our task in this scenario is to integrate the GraphQL APIs into our flutter app to build a complete and working app. + +## What do I need to take this tutorial? + +You need to have flutter installation done. + +## How long will this tutorial take? + +Less than 2 hours + +## Other courses + +**Frontend**: GraphQL for: [Vue](https://learn.hasura.io/graphql/vue), [React](https://learn.hasura.io/graphql/react), [iOS](https://learn.hasura.io/graphql/ios) + +**Backend**: [Building a realtime GraphQL backend with Hasura](https://learn.hasura.io/graphql/hasura) in 30 mins (ideal for frontend, backend or fullstack developers) + + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/logout.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/logout.md new file mode 100644 index 00000000000..6483aef844c --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/logout.md @@ -0,0 +1,5 @@ +--- +title: 'Logging out' +--- + +Currently we are just navigating to login screen and clearing the shared preferences on logout. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations.md new file mode 100644 index 00000000000..f0a8a3eb4cb --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations.md @@ -0,0 +1,16 @@ +--- +title: "Mutations" +metaTitle: "Integrate Mutations with Query Variables | GraphQL Flutter Tutorial" +metaDescription: "Integrate GraphQL Mutations in Flutter app to create new personal todos using the Mutation widget and handle loading and error states" +--- + +Now, let's add the ability for our users to create new todos and add them to +their task list. + +We will learn the following concepts: + +- Creating a GraphQL mutation +- Using the `Mutation` widget +- Capturing loading/finished/error states + +Let's get started! diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations/1-create-todo.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations/1-create-todo.md new file mode 100644 index 00000000000..a58a154f4d7 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations/1-create-todo.md @@ -0,0 +1,27 @@ +--- +title: "Create todos - mutation" +metaTitle: "Mutation to create todos | GraphQL Flutter Tutorial" +metaDescription: "GraphQL Mutation to create new personal todos. Try the mutation in GraphiQL, passing the Authorization token to get authenticated results." +--- +In this part of the tutorial, you will learn how to create new todos by using GraphQL Mutations. + +Let's define a GraphQL query to do a mutation into todos. + +```graphql + mutation addTodo($title: String!, $isPublic: Boolean!) { + action: insert_todos(objects: { title: $title, is_public: $isPublic }) { + returning { + id + title + is_completed + } + } +} +``` + +You will also need to pass in the values for the variables. + +[Try](https://learn.hasura.io/graphql/graphiql?tutorial=react-native) this mutation in GraphiQL against the application database to see what the response looks like. + +Let's now integrate this GraphQL mutation into our flutter app. + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations/2-create-mutation.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations/2-create-mutation.md new file mode 100644 index 00000000000..09fd10a4469 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/mutations/2-create-mutation.md @@ -0,0 +1,60 @@ +--- +title: "Run mutation, update cache" +metaTitle: "GraphQL Mutataion Widget | GraphQL Flutter Tutorial" +metaDescription: "We will use the GraphQL Mutation widget as an example to insert new data." +--- + + +Firstly, let us define the mutation that we looked at in the previous section. Define the following mutation in `lib/data/todo_fetch.dart`. + + + +```dart ++ static String addTodo = ++ '''mutation addTodo(\$title: String!, \$isPublic: Boolean!) { ++ action: insert_todos(objects: { title: \$title, is_public: \$isPublic }) { ++ returning { ++ id ++ title ++ is_completed ++ } ++ } ++ }'''; + +``` + +Now let's do the integration part. + +We will wrap the AddTask widget with `Mutation` widget passing our graphql mutation string in Mutation Option as a document. + +```dart ++ Mutation( ++ options: MutationOptions(document: TodoFetch.addTodo), ++ builder: ( ++ RunMutation runMutation, ++ QueryResult result, ++ ) { ++ todoList.addTodo(value); + return AddTask( + onAdd: (value) { +- todoList.addTodo(value); ++ runMutation({'title': value, 'isPublic': false}); + }, + ); ++ }, ++ onCompleted: (dynamic resultData) { ++ refetchQuery(); ++ }, ++ ), +``` + +The mutation widget optionally takes various callbacks like `onCompleted` and `update`. + +We are calling the runMutation function to our Button's `onAdd` callback. We are also passing the query variables that is `title` and `isPublic` to this runMutation function so that our mutation is called with those variables. `title` is the value of the textfeild while `isPublic` is the type of the todo, and we are explicitly marking it as false as it's a private todo. + +The mutation has been integrated and the new todos will be inserted into the database. But the UI doesn't know that a new todo has been added. We need a way to tell GraphQL client to refetch the query to update list of todos. + +The `onCompleted` callback function comes in handy to update the cache for this mutation.So we will call `refetchQuery` in onCompleted callback. + +Great! That was actually easy :) + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries.md new file mode 100644 index 00000000000..10f5292ff24 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries.md @@ -0,0 +1,14 @@ +--- +title: "Queries" +metaTitle: "Integrate Queries | GraphQL Flutter Tutorial" +metaDescription: "Integrate GraphQL Queries in Flutter app to fetch personal todo data and handle loading or error state." +--- + +Let's integrate a GraphQL query to show the user their personal task list. +We will learn the following concepts: + +- Setting up a GraphQL client using the package graphql_flutter +- Fetching data with queries +- Handle loading and error states + +Let's get started! diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/1-fetch-todos-query.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/1-fetch-todos-query.md new file mode 100644 index 00000000000..47bd2bd930c --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/1-fetch-todos-query.md @@ -0,0 +1,28 @@ +--- +title: "Fetch todos - Query" +metaTitle: "Query to fetch todo | GraphQL Flutter Tutorial" +metaDescription: "GraphQL Query to fetch personal todos. Try the query in GraphiQL, passing the Authorization token to get authenticated results" +--- + + + +The first graphql query you will write will be to fetch personal todos. You will need to load the todo data from the database which belongs to the logged-in user. Let's define a graphql query to fetch the required data. + +```graphql + query getMyTodos { + todos(where: { is_public: { _eq: false} }, order_by: { created_at: desc }) { + __typename + id + title + is_completed + } +} +``` + +[Try](https://learn.hasura.io/graphql/graphiql?tutorial=react-native) this query in GraphiQL against the application database to see what the response looks like. + +**Note**: You need to pass the `Authorization: Bearer ` header before querying to get the results. The token is auto-filled in the UI after logging in via Auth0. + +Don't be surprised to see results being empty. You haven't added any todos yet! This query is just to ensure if everything works as expected. + +Now let's integrate this GraphQL query into our Flutter app. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/2-create-query.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/2-create-query.md new file mode 100644 index 00000000000..55fb44adff2 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/2-create-query.md @@ -0,0 +1,144 @@ +--- +title: "Query Widget" +metaTitle: "Flutter Query Widget | GraphQL Flutter Tutorial" +metaDescription: "We will use the GraphQl Client Query widget provided by graphql_flutter package. It is a widget to fetch, handle data and build UI" +--- + +In this section, we will implement GraphQL Queries and integrate it with the UI. + +For queries, graphql_flutter package provides a widget named `Query`. +The `Query` widget provides two parameters, options and builder. `options` takes a widget argument of type `QueryOptions`, which again provides us several parameters like `document` to pass query ,`variables` to pass query variables and `pollInterval` to add polling in the query. `builder` parameter is used to build widgets according to the data received from the query result. + +Great! Now let's define the GraphQL query to be used: + +Open `lib/data/` and add the file named `todo_fetch.dart`and add the following code: + + + +```dart +class TodoFetch { + static String fetchAll = """query getMyTodos { + todos(where: { is_public: { _eq: false} }, + order_by: { created_at: desc }) { + __typename + id + title + is_completed + } +"""; +} +``` + +We have now written the GraphQL query as a String named fetchAll and it will be passed to QueryOptions as `document` parameter. + +## What does this query do? + +The query fetches `todos` with a simple condition : `is_public` which must be false. We sort the todos in descending order using its `created_at` attribute, according to the schema. We specify the fields we need for todos node. + +[Try](https://learn.hasura.io/graphql/graphiql?tutorial=react-native) out this query now! + +## Introducing query variables + +As you see, we have explicitly mentioned that `is_public` must be false. But in order to reuse this query for private and public todos, we must parameterize this query using `query variables`. Lets define a boolean query variable called `is_public`. The GraphQL query would fetch public todos if `is_public` is true and personal todos if `is_public` is false, which in code is represented as follows: + +```graphql +query + - query getMyTodos { + + getTodos(\$is_public: Boolean!) + { + - todos(where: { is_public: { _eq: false} }, + + todos(where: { is_public: { _eq: \$is_public} }, + order_by: { created_at: desc }) { + __typename + id + title + is_completed + } +} +``` + +Cool! The query is now ready, let's integrate it. Currently, we are just using some dummy data. Let us remove this dummy data and create the UI based on our GraphQL response. + +Now, inside `lib/screens/tabs/todos/all.dart` , lets wrap our ListView with Query widget + +```dart +Expanded( ++ child: Query( ++ options: QueryOptions( ++ document: TodoFetch.fetchAll, ++ variables: {"is_public": false}, ++ ), ++ builder: (QueryResult result, {VoidCallback refetch}) { ++ refetchQuery = refetch; ++ if (result.errors != null) { ++ return Text(result.errors.toString()); ++ } ++ if (result.loading) { ++ return Text('Loading'); ++ } ++ final List todos = ++ (result.data['todos'] as List).cast(); + return ListView.builder( +- itemCount: todoList.list.length, ++ itemCount: todos.length, + itemBuilder: (context, index) { ++ dynamic responseData = todos[index]; + return TodoItemTile( +- item: todoList.list[index], ++ item: TodoItem.fromElements(responseData["id"], ++ responseData['title'], responseData['is_completed']) +- delete: () { +- setState(() { +- todoList.removeTodo(todoList.list[index].id); +- }); + }, + toggleIsCompleted: () { +- setState(() { +- todoList.toggleList(todoList.list[index].id); +- }); + }, + ); + }, + );, ++ } ++ ), +``` + +NOTE : We will be using `refetchQuery` variable afterwords. So add `VoidCallback refetchQuery;` above build method. + +`delete` and `toggleIsCompleted` will not work now as it depends on our local list. So let's leave them empty for now. + +Woot! You have written your first GraphQL integration with Flutter. Easy isn't it? + +## How does this work? + +When you wrapped your widget with `Query` widget, It provides a builder method which gives you result as `QueryResult` object which has several variables to use. Most important ones are: + +`loading`: A boolean that indicates whether the request is in flight. If loading is true, then the request hasn't finished. Typically this information can be used to display a loading spinner. + +`errors`: A runtime error with GraphQLErrors and NetworkError properties. Contains information about what went wrong with your query. + +`data`: An object containing the result of your GraphQL query. This will contain our actual data from the server. In our case, it will be the todo data. + +Using the `data`, we are parsing the results from the server. In our query, `data` has an array `todos` which can be mapped over to create `TodoItem` object which then can be used to create `TodoItemTile` widget. + +If you have noted, there has been some client side filtering to the todos that are displayed. For example to collect all active todo or completed todo. For that follow the same procedure and add following queries to your `lib/data/todo_fetch.dart` file. + +```dart +static String fetchActive = """query getActiveTodos{ + todos(where: {is_public: {_eq: false}, is_completed: {_eq: false}}, order_by: {created_at: desc}) { + __typename + is_completed + id + title + } + }"""; + static String fetchCompleted = """query getCompletedTodos{ + todos(where: {is_public: {_eq: false}, is_completed: {_eq: true}}, order_by: {created_at: desc}) { + __typename + is_completed + id + title + } + }"""; +``` diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/3-handle-errors.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/3-handle-errors.md new file mode 100644 index 00000000000..8e8df23a907 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/queries/3-handle-errors.md @@ -0,0 +1,62 @@ +--- +title: "Handle loading/errorrs" +metaTitle: "GraphQL Client Error Handling | GraphQL Flutter Tutorial" +metaDescription: "We will handle the GraphQL loading and error Flutter app" +--- + + +As we saw in the previous step, we got various variables in `QueryResult` object. Among them `loading` and `errors` are common ones that you will need to handle in your app. + +Now let's go back to the `Query` widget that you wrote in the previous step. + + +```dart + + Query( + options: QueryOptions( + document: TodoFetch.fetchAll, + variables: {"is_public": false}, + ), + builder: (QueryResult result, {VoidCallback refetch}) { + refetchQuery = refetch; + if (result.errors != null) { + return Text(result.errors.toString()); + } + if (result.loading) { + return Text('Loading'); + } + final List todos = + (result.data['todos'] as List).cast(); + return ListView.builder( + itemCount: todos.length, + itemBuilder: (context, index) { + dynamic responseData = todos[index]; + return TodoItemTile( + item: TodoItem.fromElements(responseData["id"], + responseData['title'], responseData['is_completed']), + toggleDocument: TodoFetch.toggleTodo, + toggleRunMutaion: { + 'id': responseData["id"], + 'isCompleted': !responseData['is_completed'] + }, + deleteDocument: TodoFetch.deleteTodo, + deleteRunMutaion: { + 'id': responseData["id"], + }, + refetchQuery: refetch, + ); + }, + ); + }, + ) + + +``` + + +When Query's `builder` runs you can manage states of your app like loading and error. +In loading state, typically you can do fancy things like displaying a loading spinner. + +We are just printing `error` but you can handel it also, by navigating to some screen or showing some pop up. + +All said and done, What you have written above is basic, but sufficient for this tutorial. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed.md new file mode 100644 index 00000000000..b7a00e5d4fb --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed.md @@ -0,0 +1,7 @@ +--- +title: "Realtime Feed" +metaTitle: "Realtime Public Todo Feed | GraphQL Flutter Tutorial" +metaDescription: "You will learn how to make a realtime feed that captures public todos added by other people." +--- + +In this section, you will make a realtime feed that captures public todos added by other people. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/1-subscribe-to-new-todos.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/1-subscribe-to-new-todos.md new file mode 100644 index 00000000000..076237681a3 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/1-subscribe-to-new-todos.md @@ -0,0 +1,62 @@ +--- +title: "Detect new todos" +metaTitle: "Subscribe to new todos | GraphQL Flutter Tutorial" +metaDescription: "You will learn how to make use of GraphQL Subscriptions to get notified whenever a new todo comes in Flutter app" +--- + +In this section, we will capture newly added public todos in the database. This can be done by subscribing to the last todo added in the database. The subscription query looks like: + +```graphql +subscription { + todos ( + order_by: { + id: desc + } + limit: 1 + where: { is_public: { _eq: true }} + ) { + id + } +} +``` + +What does this subscription do? +------------------------------- + +The above subscription gives only the "last added" element in the database (ordered by `id` and limit set to 1). So whenever a todo is added in the database, this subscription will receive data. + +We can treat this subscription data as an event notification saying "something has been added" and fetch all the todos from the database latest with respect to your todo present in the local cache. + +Whenever such an event notification occurs, we can fetch the newer todos with the following query: + +```graphql +query ($lastId: Int){ + todos ( + order_by: { + id: desc + }, + where: { + _and: { + is_public: { _eq: true}, + id: { _gt: $lastId} + } + } + ) { + id + title + is_completed + created_at + is_public + user { + name + } + } +} +``` + +What does this query do? +----------------------- + +This query takas a query variable called `$lastId` and fetches all the todos with `id` greater than the value of `$lastId`. + +Now let us wire up this functionality in our app. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/2-run-subscription.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/2-run-subscription.md new file mode 100644 index 00000000000..01575575274 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/2-run-subscription.md @@ -0,0 +1,84 @@ +--- +title: "Detect new todos - Integration" +metaTitle: "Fetch public todos using Subscription | GraphQL Flutter Tutorial" +metaDescription: "You will learn how to make use of GraphQL Subscriptions to get notified whenever a new todo comes in Flutter app." +--- + +Go to `lib/data/` and create a file named `feed_fetch.dart` inside that create a class named `FeedFetch` add the following subscription string. + +```dart +static String fetchNewNotification = """subscription fetchNewNotification { + todos(where: {is_public: {_eq: true}}, limit: 1, order_by: {created_at: desc}) { + id + } +} +"""; +``` + +Now wrap custom button i.e `New Notification` in subscription widget. But before that, add following variables in your `_FeedsState` class. + +```dart ++ static int _lastLatestFeedId; ++ static int _oldestFeedId; ++ static int _newTodoCount = 0; ++ static int _previousId = 0; ++ static int _newId = 0; ++ GraphQLClient _client; +``` + +And initialize \_client in initState method. + +```dart ++ @override ++ void initState() { ++ WidgetsBinding.instance.addPostFrameCallback((_) { ++ _client = GraphQLProvider.of(context).value; ++ }); ++ super.initState(); ++ } +``` + +Now let's wrap the subscription + +```dart ++ Subscription( ++ "fetchNewNotification", ++ FeedFetch.fetchNewNotification, ++ builder: ({ ++ bool loading, ++ dynamic payload, ++ dynamic error, ++ }) { ++ if (payload != null) { ++ _newId = payload['todos'][0]['id']; ++ if (_previousId != 0) { ++ _newTodoCount = _newTodoCount + (_newId - _previousId); ++ } ++ _previousId = payload['todos'][0]['id']; ++ if (_newTodoCount != 0) { +- CustomButton( ++ return CustomButton( + onTap: () { + print("loading"); + }, + height: 50, + text: " $_newTodoCount New Notification", + width: MediaQuery.of(context).size.width / 2, + ); +- } else +- return SizedBox(); +- } else { +- return SizedBox(); +- } +- }, +- ) +``` + +The `fetchNewNotification` does the following: + +1. Starts a subscription to the last todo in the database. +2. Whenever data is received, it looks at the todos and compare previous id with current id via subscription, if new id is greater then previous id, it will increase the count of notification. + +Awesome! You are now detecting new todo updates from the backend. + +Now let's make this button functional and add feeds to our list. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/3-sync-todos.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/3-sync-todos.md new file mode 100644 index 00000000000..e4b0e3f3627 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/realtime-feed/3-sync-todos.md @@ -0,0 +1,158 @@ +--- +title: "Sync new todos" +metaTitle: "Sync new todos in public feed | GraphQL Flutter Tutorial" +metaDescription: "You will learn how to sync new todos added by other people in the public feed by fetching older and newer data using GraphQL Queries" +--- + + +In the previous section, we made a button that shows up only when there are new public todos in the database. Now lets make this button functional i.e. on pressing this button, newer todos should be fetched from the backend, synced with the local todos and the button must be dismissed. + +Go to `lib/data/feed_fetch.dart`, and add following query strings in it. + +```dart ++ static String loadMoreTodos = """ query loadMoreTodos (\$oldestTodoId: Int!) { ++ todos (where: { is_public: { _eq: true}, id: {_lt: \$oldestTodoId}}, limit: 7, order_by: { ++ created_at: desc }) { ++ id ++ title ++ created_at ++ user { ++ name ++ } ++ } ++ }"""; ++ static String newTodos = """query newTodos (\$latestVisibleId: Int!) { ++ todos(where: { is_public: { _eq: true}, id: {_gt: \$latestVisibleId}}, order_by: { created_at: + desc }) { ++ id ++ title ++ created_at ++ user { ++ name ++ } ++ } ++ }"""; +``` + +Now, whenever we navigate to feeds tab, we want current todos and on pressing new notification, we want to add new todos in existing list and also on tap of load more, we want to fetch older todos. + +Let's update our code accordingly step by step + +First let's fetch current todos and new notification todos. + +```dart + Subscription( + "fetchNewNotification", + FeedFetch.fetchNewNotification, + builder: ({ + bool loading, + dynamic payload, + dynamic error, + }) { + if (payload != null) { + _newId = payload['todos'][0]['id']; + + if (_previousId != 0) { + _newTodoCount = _newTodoCount + (_newId - _previousId); + } ++ else { ++ _lastLatestFeedId = _newId; ++ _client ++ .query( ++ QueryOptions( ++ document: FeedFetch.loadMoreTodos, ++ variables: {"oldestTodoId": _newId + 1}, ++ ), ++ ) ++ .then((onValue) { ++ for (var todo in onValue.data.data['todos']) { ++ feedList.addFeed(todo['id'].toString(), todo['title'], ++ todo['user']['name']); ++ } ++ setState(() {}); ++ }).catchError((onError) { ++ print(onError); ++ }); ++ } + _previousId = payload['todos'][0]['id']; + + if (_newTodoCount != 0) { + return CustomButton( + onTap: () { ++ _client ++ .query( ++ QueryOptions( ++ document: FeedFetch.newTodos, ++ variables: {"latestVisibleId": _lastLatestFeedId}, ++ ), ++ ) ++ .then((onValue) { ++ for (var todo in onValue.data.data['todos'].reversed) { ++ feedList.addfirstFeed(todo['id'].toString(), ++ todo['title'], todo['user']['name']); ++ } ++ _lastLatestFeedId = int.parse(feedList.list.first.id); ++ _newTodoCount = 0; ++ setState(() {}); ++ }).catchError((onError) { ++ print(onError); ++ }); + }, + height: 50, + text: " $_newTodoCount New Notification", + width: MediaQuery.of(context).size.width / 2, + ); + } else + return SizedBox(); + } else { + return SizedBox(); + } + }, + ) + Expanded( + child: ListView.builder( + itemCount: feedList.list.length, + itemBuilder: (context, index) { + return FeedTile( +- feedList.list[feedList.list.length - index - 1].username, +- feed: feedList.list[feedList.list.length - index - 1].feed); ++ username: feedList.list[index].username, ++ feed: feedList.list[index].feed); + }, + ), + ), +``` + +So the above code is fetching some already existing todo from database and adding them to `feedList` to the very first time and then on tap of new notification, it is updating `feedList` with new todos. + +Now let's add functionality to our load more button by again using `_client.query`. + +```dart + CustomButton( + onTap: () { +- print("load more"); ++ _oldestFeedId = int.parse(feedList.list.last.id); ++ _client ++ .query( ++ QueryOptions( ++ document: FeedFetch.loadMoreTodos, ++ variables: {"oldestTodoId": _oldestFeedId}, ++ ), ++ ) ++ .then((onValue) { ++ for (var todo in onValue.data.data['todos']) { ++ feedList.addFeed( ++ todo['id'].toString(), todo['title'], todo['user']['name']); ++ } ++ setState(() {}); ++ }).catchError((onError) { ++ print(onError); ++ }); + }, + height: 50, + text: "Load More", + width: MediaQuery.of(context).size.width / 3, + ) +``` +And yes to add new public todo, you can follow same as adding private todo. + +With this, your fully functional realtime todo app is ready. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/setup.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/setup.md new file mode 100644 index 00000000000..88e5f4bb63f --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/setup.md @@ -0,0 +1,30 @@ +--- +title: "Tutorial & boilerplate setup" +metaTitle: "Todo app Flutter boilerplate setup | GraphQL Flutter Tutorial" +metaDescription: "The GraphQL backend is already ready. The task is to convert the static UI into a working realtime app in Flutter" +--- + +For this tutorial, the GraphQL backend and the basic app UI is already ready. +Our task will be convert the "static" UI into a working realtime app. + +### Download and run the boilerplate + + +1. Download the boilerplate at: [https://learn.hasura.io/graphql/flutter-graphql/boilerplate.zip](https://learn.hasura.io/graphql/flutter-graphql/boilerplate.zip) +2. Unzip and make sure you're in the `app-boilerplate` directory. +3. Run this app in your phone or emulator using `Flutter SDK` + - `flutter run` +4. Signup/login as a user to load the todo app screen + +After you login, you should get something like this: + +![UI after logging in](https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-flutter/ui-after-logging-in.png) + +### Load GraphiQL to play with your GraphQL APIs + +1. Head to [https://learn.hasura.io/graphql/graphiql](https://learn.hasura.io/graphql/graphiql?tutorial=react-native) +2. Log in (so that you can test the GraphQL APIs with a valid user token) + +This is what you should see after the steps above: + +![GraphiQL after login](https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-react/graphiql-after-login.png) diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions.md new file mode 100644 index 00000000000..5e7cfaaec56 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions.md @@ -0,0 +1,72 @@ +--- +title: "Subscriptions to show online users" +metaTitle: "Update last seen of user with Mutation | GraphQL Flutter Tutorial" +metaDescription: "GraphQL Mutation to update last seen of user to make them available online. Use setInterval to trigger mutation every few seconds " +--- + +import GithubLink from "../src/GithubLink.js"; + +We cruised through our GraphQL queries and mutations. We queried for todos, added a new todo item, updated an existing todo, removed an existing todo item. + +Now let's get to the exciting part. + +GraphQL Subscriptions +--------------------- + +We have a section of UI which displays the list of online users. So far we have made queries to fetch data and display them on the UI. But typically online users data is dynamic. + +We can make use of GraphQL Subscription API to get realtime data from the GraphQL server to efficiently handle this. + +But but but... + +We need to tell the server that the user who is logged in is online. We have to poll our server to do a mutation which updates the `last_seen` timestamp value of the user. + +We have to make this change to see ourself online first. Remember that we are already logged in and registered your data in the server, but not updated your `last_seen` value? + +The goal is to update it every few seconds from the client that you are online. Ideally you should do this after you have successfully authenticated. So let's do it on the entrypoint of the app i.e. `lib/screens/tabs/todos/all.dart`. We instantiate `GraphQLClient`. +First, lets define the mutation that sets `last_seen` to the current timestamp. For that create a file named `online_fetch.dart` inside `lib/data` and add the code below. + +```dart ++ static String updateStatus = ++ """ mutation updateLastSeen (\$now: timestamptz!) { ++ update_users(where: {}, _set: {last_seen: \$now}) { ++ affected_rows ++ } ++ }"""; +``` + + +Now we shall create a function `runOnlineMutation` to start polling at regular interval of 30 sec in our `All` class (or widget) itself and call that function in init method of the class. + + + +```dart ++ static GraphQLClient _client; ++ runOnlineMutation(context) { ++ _client = GraphQLProvider.of(context).value; ++ Future.doWhile( ++ () async { ++ _client.mutate( ++ MutationOptions( ++ document: OnlineFetch.updateStatus, ++ variables: { ++ 'now': DateTime.now().toUtc().toIso8601String(), ++ }, ++ ), ++ ); ++ await Future.delayed(Duration(seconds: 30)); ++ return true; ++ }, ++ ); ++ } + @override + void initState() { ++ WidgetsBinding.instance ++ .addPostFrameCallback((_) => runOnlineMutation(context)); + super.initState(); + } +``` + +Again, we are making use of `_client.mutate` to update the `users` table of the database. + +Great! Now the metadata about whether the user is online will be available in the backend. Let's now do the integration to display realtime data of online users. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/1-subscription.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/1-subscription.md new file mode 100644 index 00000000000..eb17f5aef71 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/1-subscription.md @@ -0,0 +1,7 @@ +--- +title: "Subscription" +metaTitle: "Set up GraphQL Subscriptions using GraphQL Subscription Widget | GraphQL Flutter Tutorial" +metaDescription: "You will learn how to configure GraphQL Subscriptions using GraphQL Subscription Widget" +--- + +As we have already set up our websocket in our inital steps by concatinating our link with websocket link, that's why we now can make use of that in our subscription widget. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/2-apollo-subscription.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/2-apollo-subscription.md new file mode 100644 index 00000000000..216fd76a748 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/2-apollo-subscription.md @@ -0,0 +1,7 @@ +--- +title: "Subscription Widget" +metaTitle: "GraphQL Subscription Widget | GraphQL Flutter Tutorial" +metaDescription: "The easiest way to bring live data to your UI is using the Subscription widget from GraphQL package." +--- + +The easiest way to bring live data to our UI is using the Subscription widget from GraphQL package. This gives us the stream of data using which we can build our UI! One thing to note, subscriptions are just listeners, they don’t request any data when first connected, but only open up a connection to get new data. \ No newline at end of file diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/3-create-subscription.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/3-create-subscription.md new file mode 100644 index 00000000000..476821fd582 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/subscriptions/3-create-subscription.md @@ -0,0 +1,63 @@ +--- +title: "Create Subscription and Render Result" +metaTitle: "Flutter Subscription widget | GraphQL Flutter Tutorial" +metaDescription: "Integrate Subscription widget to watch for changes in realtime data. We use GraphQL subscriptions as an example to get live data in the Flutter app" +--- + +Open `src/data/online_fetch.dart` and add the following code. + +```dart ++static String fetchUsers = """ ++ subscription fetchOnlineUsers { ++ online_users { ++ user { ++ name ++ } ++ } ++ } +"""; +``` + +Open `screens/tabs/dashboard/online.dart` +Now, Wrap the ListView with `Subscription` widget passing GraphQL subscription string. + +```dart ++ Subscription( ++ "fetchOnlineUsers", ++ OnlineFetch.fetchUsers, ++ builder: ({ ++ bool loading, ++ dynamic payload, ++ dynamic error, ++ }) { ++ if (payload != null) { +- Expanded( ++ return Expanded( ++ child: ListView.builder( +- itemCount: onlineList.list.length, ++ itemCount: payload['online_users'].length, + itemBuilder: (context, index) { + return Card( + child: ListTile( + title: Text( +- title: Text(onlineList.list[index]), ++ payload['online_users'][index]['user']['name']), + ), + ); + }, + ), + ); ++ } else { ++ return Text("Fetching Online Users"); ++ } ++ }, ++ ), +``` + +## How does this work? + +We are using the `Subscription` widget which gives payload (similar to data in the `Query` and `Mutation` widget) of the realtime data for the query we have made. + +Refresh your app and see yourself online! Don't be surprised; There could be other users online as well. + +Awesome! You have completed basic implementations of a GraphQL Query, Mutation and Subscriptions. Easy isn't it? diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/twitter-share.js b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/twitter-share.js new file mode 100644 index 00000000000..0450dbce982 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/twitter-share.js @@ -0,0 +1,11 @@ +import React from 'react'; + +const TwitterShare = () => { + return( + + {'Twitter'} + + ) +}; + +export default TwitterShare; \ No newline at end of file diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations.md new file mode 100644 index 00000000000..81d905e3b8a --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations.md @@ -0,0 +1,13 @@ +--- +title: "Update mutations and automatic cache updates" +metaTitle: "Optimistic UI updates after mutations | GraphQL Flutter Tutorial" +metaDescription: "We will use the Mutation Optimistic Response to perform UI updates after a GraphQL mutation in the Flutter" +--- + +In this section, we will learn the following concepts: + +- Creating a GraphQL mutation +- Using the `Mutation` widget +- Automatic cache updates + +Let's get started! diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/1-update-todos.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/1-update-todos.md new file mode 100644 index 00000000000..31b08fea79e --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/1-update-todos.md @@ -0,0 +1,25 @@ +--- +title: "Update todos - mutation" +metaTitle: "Mutation to update todos | GraphQL Flutter Tutorial" +metaDescription: "GraphQL Mutation to update existing personal todos. Try the mutation in GraphiQL, passing the Authorization token to mark a todo as completed" +--- + +In this part of the tutorial, you will learn how to mark an existing todo as completed by using GraphQL Mutations. + +Let's define a GraphQL query to do a mutation into todos. + +```graphql + mutation toggleTodo($id:Int!, $isCompleted: Boolean!) { + action: update_todos(where: {id: {_eq: $id}}, _set: {is_completed: $isCompleted}) { + returning { + is_completed + } + } +} +``` + +You will also need to pass in the values for the variables. + +[Try](https://learn.hasura.io/graphql/graphiql?tutorial=react-native) this mutation in GraphiQL against the application database to see what the response looks like. + +Let's now integrate this GraphQL mutation into our Flutter app. diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/2-mutation-cache.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/2-mutation-cache.md new file mode 100644 index 00000000000..efe1f517ed3 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/2-mutation-cache.md @@ -0,0 +1,97 @@ +--- +title: "Update mutation and automatic cache updates" +metaTitle: "GraphQL Mutation widget for GraphQL mutation update | GraphQL Flutter Tutorial" +metaDescription: "We will use the Mutation widget from package as an example to modify existing data and update cache automatically and handle optimisticResponse" +--- + + +Now let's do the integration part. Open `lib/data/todo_fetch` and add the following code. + +```dart ++ static String toggleTodo = ++ """mutation toggleTodo(\$id:Int!, \$isCompleted: Boolean!) { ++ action: update_todos(where: {id: {_eq: \$id}}, _set: {is_completed: \$isCompleted}) { ++ returning { ++ is_completed ++ } ++ } ++ }"""; +``` + +Now, in `TodoItemTile` widget inside `lib/component/todo_item_tile.dart`, let's modify leading widget i.e Inkwell. + +```dart ++ Mutation( ++ options: MutationOptions(document: toggleDocument), ++ builder: ( ++ RunMutation runMutation, ++ QueryResult result, ++ ) { ++ return InkWell( ++ onTap: () { +- toggleIsCompleted(); ++ runMutation( ++ toggleRunMutaion, ++ optimisticResult: { ++ "action": { ++ "returning": [ ++ {"is_completed": !item.isCompleted} ++ ] ++ } ++ }, ++ ); ++ }, + child: Container( + height: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: Icon(!item.isCompleted + ? Icons.radio_button_unchecked + : Icons.radio_button_checked), + ), ++ ); ++ }, ++ update: (Cache cache, QueryResult result) { ++ if (result.hasErrors) { ++ print(result.errors); ++ } else { ++ final Map updated = ++ Map.from(item.toJson()) ++ ..addAll(extractTodoData(result.data)); ++ cache.write(typenameDataIdFromObject(updated), updated); ++ } ++ return cache; ++ }, ++ onCompleted: (onValue) { ++ refetchQuery(); ++ }, ++ ) +``` +The above code isn't using `toggleIsCompleted` callback but it's using `toggleDocument`, `toggleRunMutaion` to pass mutation query and mutation variable repectively, So define them in constructor of `TodoItemTile` widget itself and remove `toggleIsCompleted` callback function from constructor. Pass your toggle mutation query and toggle variable document in the widget from screens i.e `all.dart` , `active.dart` and `completed.dart`. + +`runMutation` has `optimisticResult` as an argument in which we can pass as our optimistic result. +Now we have to update our cache according to optimisticResult. For this, we have to find the key of item in the cache using `typenameDataIdFromObject` function which takes the item of type map as parameter to be updated. +We get that map using `extractTodoData`function which we will define in `TodoItemTile` itself. + +Note: We are using refetchQuery inside our onCompleted function which we also get as a callback using constructor itself. + +Add this function code in your `TodoItemTile` class(or widget). + +```dart ++ Map extractTodoData(Object data) { ++ final Map returning = ++ (data as Map)['action'] as Map; ++ if (returning == null) { ++ return null; ++ } ++ List list = returning['returning']; ++ return list[0] as Map; ++ } +``` +Add finally cache.write will update the cache. + +To summarize the above code it follows that : + +1. It looks at the `id` and `__typename` of the mutation response. +2. It looks for the objects in the cache that have `id` and `__typename` similar to the ones in the mutation response. +3. If there is a match, it updates the cache with the data from the mutation response. + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/3-remove-todos.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/3-remove-todos.md new file mode 100644 index 00000000000..1d3cd9dd187 --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/3-remove-todos.md @@ -0,0 +1,23 @@ +--- +title: "Remove todos - Mutation" +metaTitle: "Mutation to delete todos | GraphQL Flutter Tutorial" +metaDescription: "GraphQL Mutation to delete existing personal todos. Try the mutation in GraphiQL, passing the Authorization token to delete a todo" +--- + +In this part of the tutorial, you will learn how to remove existing todos by using GraphQL Mutations. + +Let's define a GraphQL query to do a mutation in todos. + +```graphql +mutation delete($id:Int!) { + action: delete_todos(where: {id: {_eq: $id}}) { + returning { + id + } + } +} +``` + +[Try](https://learn.hasura.io/graphql/graphiql?tutorial=react-native) this mutation in GraphiQL against the application database to see what the response looks like. + +Let's now integrate this GraphQL mutation into our Flutter app. \ No newline at end of file diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/4-remove-todos-integration.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/4-remove-todos-integration.md new file mode 100644 index 00000000000..0146e135ecc --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/update-delete-mutations/4-remove-todos-integration.md @@ -0,0 +1,52 @@ +--- +title: "Remove todos - Integration" +metaTitle: "Mutation widget for GraphQL mutation delete | GraphQL Flutter Tutorial" +metaDescription: "We will use the Mutation Widget with variables as an example to delete existing data" +--- + +Let us integrate the remove todos feature in our Flutter app. Initially add the following mutation string in `lib/data/todo_fetch.dart`. + + + + +```dart ++ static String deleteTodo = """mutation delete(\$id:Int!) { ++ action: delete_todos(where: {id: {_eq: \$id}}) { ++ returning { ++ id ++ } ++ } ++ }"""; +``` + +Now, in `TodoItemTile` widget, update the `trailing` widget i.e InkWell and wrap it in a mutation widget. + +```dart ++ Mutation( ++ options: MutationOptions(document: deleteDocument), ++ builder: ( ++ RunMutation runMutation, ++ QueryResult result, ++ ) { + return InkWell( + onTap: () { +- delete(); ++ runMutation(deleteRunMutaion); + }, + child: Container( + decoration: BoxDecoration( + border: Border(left: BorderSide(color: Colors.grey))), + width: 60, + height: double.infinity, + child: Icon(Icons.delete)), + ); ++ }, ++ onCompleted: (onValue) { ++ refetchQuery(); ++ }, ++ ) +``` +The above code is not using `delete` callback but it's using `deleteDocument`, `deleteRunMutaion` to pass mutation query and mutation variable repectively, so define them in constructor of `TodoItemTile` class itself and remove `delete` callback function from the constructor. Pass your delete mutation query and delete variable document in the widget from screens i.e `all.dart` , `active.dart` and `completed.dart`. + +Use same refetchQuery call back in onCompleted function to update the UI. + diff --git a/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/what-next.md b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/what-next.md new file mode 100644 index 00000000000..087e51f57bd --- /dev/null +++ b/community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/content/what-next.md @@ -0,0 +1,27 @@ +--- +title: "What next?" +metaTitle: "What next? | GraphQL Flutter Tutorial" +--- + +import TwitterShare from './twitter-share'; + +Congratulations! You have successfully completed the course. + +In case you are wondering what to do next, you have the following options: + +## Take the Hasura backend course +We have an [Introduction to Hasura](https://learn.hasura.io/graphql/hasura) backend course to build the backend that you just used for your react native app. + +## Join Discord for Support +We have a Discord Channel for those who are new to GraphQL. Please post your queries or feedback regarding this course. It is a pretty active channel. + +Here's the [invite link](https://discordapp.com/invite/vBPpJkS) to join discord. + +## More sample apps +We have a bunch of sample apps created using Hasura GraphQL Engine with different frameworks. + +Check out the [sample apps](https://hasura.io/sample-apps) to get a taste of how realtime GraphQL and Auth work with Hasura. + +## Spread the word! +Liked the course? +Do spread the word on Twitter! \ No newline at end of file From e92ffcf440cc54ed31990834c3a0f8d6d18a850c Mon Sep 17 00:00:00 2001 From: Rishichandra Wawhal Date: Tue, 6 Aug 2019 14:30:30 +0530 Subject: [PATCH 27/27] refactor console codebase with customResolver -> remoteSchema (#2670) --- console/index.js | 59 -------- console/src/components/Main/Main.js | 2 +- console/src/components/Main/Tooltips.js | 4 +- .../Common/Landing/TopicDescription.js | 2 +- .../Services/Common/Landing/TryItOut.js | 2 +- .../Services/CustomResolver/index.js | 9 -- .../components/Services/Metadata/Actions.js | 4 +- .../Actions.js} | 54 +++---- .../Add/Add.js | 10 +- .../Add/addRemoteSchemaReducer.js} | 132 +++++++++--------- .../Common/Common.js | 6 +- .../Edit/Edit.js | 70 +++++----- .../Edit/View.js | 58 ++++---- .../Edit/tabInfo.js | 0 .../Landing/RemoteSchema.js} | 17 ++- .../RemoteSchema.scss} | 6 +- .../RemoteSchemaPageContainer.js} | 10 +- .../RemoteSchemaRouter.js} | 41 +++--- .../RemoteSchemaSubSidebar.js} | 10 +- .../constants.js | 0 .../components/Services/RemoteSchema/index.js | 9 ++ .../remoteSchemaReducer.js} | 10 +- .../{CustomResolver => RemoteSchema}/state.js | 4 +- console/src/reducer.js | 4 +- console/src/routes.js | 6 +- 25 files changed, 241 insertions(+), 288 deletions(-) delete mode 100644 console/index.js delete mode 100644 console/src/components/Services/CustomResolver/index.js rename console/src/components/Services/{CustomResolver/customActions.js => RemoteSchema/Actions.js} (77%) rename console/src/components/Services/{CustomResolver => RemoteSchema}/Add/Add.js (84%) rename console/src/components/Services/{CustomResolver/Add/addResolverReducer.js => RemoteSchema/Add/addRemoteSchemaReducer.js} (77%) rename console/src/components/Services/{CustomResolver => RemoteSchema}/Common/Common.js (97%) rename console/src/components/Services/{CustomResolver => RemoteSchema}/Edit/Edit.js (76%) rename console/src/components/Services/{CustomResolver => RemoteSchema}/Edit/View.js (76%) rename console/src/components/Services/{CustomResolver => RemoteSchema}/Edit/tabInfo.js (100%) rename console/src/components/Services/{CustomResolver/Landing/CustomResolver.js => RemoteSchema/Landing/RemoteSchema.js} (87%) rename console/src/components/Services/{CustomResolver/CustomResolver.scss => RemoteSchema/RemoteSchema.scss} (98%) rename console/src/components/Services/{CustomResolver/CustomResolverPageContainer.js => RemoteSchema/RemoteSchemaPageContainer.js} (82%) rename console/src/components/Services/{CustomResolver/CustomResolverRouter.js => RemoteSchema/RemoteSchemaRouter.js} (62%) rename console/src/components/Services/{CustomResolver/CustomResolverSubSidebar.js => RemoteSchema/RemoteSchemaSubSidebar.js} (91%) rename console/src/components/Services/{CustomResolver => RemoteSchema}/constants.js (100%) create mode 100644 console/src/components/Services/RemoteSchema/index.js rename console/src/components/Services/{CustomResolver/customResolverReducer.js => RemoteSchema/remoteSchemaReducer.js} (51%) rename console/src/components/Services/{CustomResolver => RemoteSchema}/state.js (92%) diff --git a/console/index.js b/console/index.js deleted file mode 100644 index 0016527b519..00000000000 --- a/console/index.js +++ /dev/null @@ -1,59 +0,0 @@ -// import GraphiQL parts -import GraphiQLWrapper from './src/components/Services/ApiExplorer/GraphiQLWrapper/GraphiQLWrapper'; - -// import Data Tab parts -import dataRouter from './src/components/Services/Data/DataRouter'; -import { dataReducer } from './src/components/Services/Data'; -import dataHeaders from './src/components/Services/Data/Common/Headers'; -import { handleMigrationErrors } from './src/components/Services/Data/TableModify/ModifyActions'; -import { - fetchSchemaList, - updateSchemaInfo, - UPDATE_CURRENT_SCHEMA, - UPDATE_DATA_HEADERS, - ACCESS_KEY_ERROR, -} from './src/components/Services/Data/DataActions'; - -// import Event Tab parts -import eventRouterUtils from './src/components/Services/EventTrigger/EventRouter'; -import { eventReducer } from './src/components/Services/EventTrigger'; - -// import Remote Schema parts -import getCustomResolverRouter from './src/components/Services/CustomResolver/CustomResolverRouter.js'; -import customResolverReducer from './src/components/Services/CustomResolver/customResolverReducer.js'; - -// import other globals -import routes from './src/routes'; -import globals from './src/Globals'; -import endpoints from './src/Endpoints'; -import mainState from './src/components/Main/State'; -import { changeRequestHeader } from './src/components/Services/ApiExplorer/Actions'; -import { validateLogin } from './src/components/Main/Actions'; - -const filterQueryScss = require('./src/components/Common/FilterQuery/FilterQuery.scss'); -const tableScss = require('./src/components/Common/TableCommon/Table.scss'); - -// export GraphiQL parts -export { GraphiQLWrapper }; - -// export Data Tab parts -export { dataRouter, dataReducer }; -export { fetchSchemaList, updateSchemaInfo }; -export { UPDATE_CURRENT_SCHEMA, UPDATE_DATA_HEADERS, ACCESS_KEY_ERROR }; -export { dataHeaders }; - -// export Event Tab parts -export { eventRouterUtils, eventReducer }; - -// export Remote Schema parts -export { getCustomResolverRouter, customResolverReducer }; - -// export other globals -export default routes; -export { globals, endpoints, mainState }; -export { changeRequestHeader }; -export { validateLogin }; -export { handleMigrationErrors }; - -// export styles -export { filterQueryScss, tableScss }; diff --git a/console/src/components/Main/Main.js b/console/src/components/Main/Main.js index ad06d21da5c..06c989cb8c4 100644 --- a/console/src/components/Main/Main.js +++ b/console/src/components/Main/Main.js @@ -479,7 +479,7 @@ class Main extends React.Component {
  • Manage Event Triggers ); -export const customresolver = ( - Manage Remote Schemas +export const remoteSchema = ( + Manage Remote Schemas ); export const secureEndpoint = ( diff --git a/console/src/components/Services/Common/Landing/TopicDescription.js b/console/src/components/Services/Common/Landing/TopicDescription.js index 1cc06b43964..fc925e50ab3 100644 --- a/console/src/components/Services/Common/Landing/TopicDescription.js +++ b/console/src/components/Services/Common/Landing/TopicDescription.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; class TopicDescription extends React.Component { render() { const Rectangle = require('./images/Rectangle.svg'); - const styles = require('../../CustomResolver/CustomResolver.scss'); + const styles = require('../../RemoteSchema/RemoteSchema.scss'); const { title, imgUrl, imgAlt, description } = this.props; return (
    diff --git a/console/src/components/Services/Common/Landing/TryItOut.js b/console/src/components/Services/Common/Landing/TryItOut.js index 3a263957d0a..65aabd7ec67 100644 --- a/console/src/components/Services/Common/Landing/TryItOut.js +++ b/console/src/components/Services/Common/Landing/TryItOut.js @@ -14,7 +14,7 @@ class TryItOut extends React.Component { } render() { const Rectangle = require('./images/Rectangle.svg'); - const styles = require('../../CustomResolver/CustomResolver.scss'); + const styles = require('../../RemoteSchema/RemoteSchema.scss'); const glitch = require('./images/glitch.png'); const googleCloud = require('./images/google_cloud.svg'); const MicrosoftAzure = require('./images/Microsoft_Azure_Logo.svg'); diff --git a/console/src/components/Services/CustomResolver/index.js b/console/src/components/Services/CustomResolver/index.js deleted file mode 100644 index 1b6ee03b891..00000000000 --- a/console/src/components/Services/CustomResolver/index.js +++ /dev/null @@ -1,9 +0,0 @@ -export customResolverPageConnector from './CustomResolverPageContainer'; -export landingConnector from './Landing/CustomResolver'; -export addConnector from './Add/Add'; -export editConnector from './Edit/Edit'; -export viewConnector from './Edit/View'; - -export getCustomResolverRouter from './CustomResolverRouter'; - -export customResolverReducer from './customResolverReducer'; diff --git a/console/src/components/Services/Metadata/Actions.js b/console/src/components/Services/Metadata/Actions.js index cf5fd74e143..9c72f8f600c 100644 --- a/console/src/components/Services/Metadata/Actions.js +++ b/console/src/components/Services/Metadata/Actions.js @@ -9,7 +9,7 @@ import { setConsistentSchema, setConsistentFunctions, } from '../Data/DataActions'; -import { setConsistentRemoteSchemas } from '../CustomResolver/customActions'; +import { setConsistentRemoteSchemas } from '../RemoteSchema/Actions'; import { showSuccessNotification, showErrorNotification, @@ -72,7 +72,7 @@ const handleInconsistentObjects = inconsistentObjects => { return (dispatch, getState) => { const allSchemas = getState().tables.allSchemas; const functions = getState().tables.trackedFunctions; - const remoteSchemas = getState().customResolverData.listData.resolvers; + const remoteSchemas = getState().remoteSchemas.listData.remoteSchemas; dispatch({ type: LOAD_INCONSISTENT_OBJECTS, diff --git a/console/src/components/Services/CustomResolver/customActions.js b/console/src/components/Services/RemoteSchema/Actions.js similarity index 77% rename from console/src/components/Services/CustomResolver/customActions.js rename to console/src/components/Services/RemoteSchema/Actions.js index d701d910486..96d39b4bc03 100644 --- a/console/src/components/Services/CustomResolver/customActions.js +++ b/console/src/components/Services/RemoteSchema/Actions.js @@ -16,18 +16,20 @@ import { filterInconsistentMetadataObjects } from '../Metadata/utils'; /* Action constants */ -const FETCH_RESOLVERS = '@customResolver/FETCH_RESOLVERS'; -const RESOLVERS_FETCH_SUCCESS = '@customResolver/RESOLVERS_FETCH_SUCCESS'; -const FILTER_RESOLVER = '@customResolver/FILTER_RESOLVER'; -const RESOLVERS_FETCH_FAIL = '@customResolver/RESOLVERS_FETCH_FAIL'; -const RESET = '@customResolver/RESET'; -const SET_CONSISTENT_RESOLVERS = '@customResolver/SET_CONSISTENT_RESOLVERS'; +const FETCH_REMOTE_SCHEMAS = '@remoteSchema/FETCH_REMOTE_SCHEMAS'; +const REMOTE_SCHEMAS_FETCH_SUCCESS = + '@remoteSchema/REMOTE_SCHEMAS_FETCH_SUCCESS'; +const FILTER_REMOTE_SCHEMAS = '@remoteSchema/FILTER_REMOTE_SCHEMAS'; +const REMOTE_SCHEMAS_FETCH_FAIL = '@remoteSchema/REMOTE_SCHEMAS_FETCH_FAIL'; +const RESET = '@remoteSchema/RESET'; +const SET_CONSISTENT_REMOTE_SCHEMAS = + '@remoteSchema/SET_CONSISTENT_REMOTE_SCHEMAS'; -const VIEW_RESOLVER = '@customResolver/VIEW_RESOLVER'; +const VIEW_REMOTE_SCHEMA = '@remoteSchema/VIEW_REMOTE_SCHEMA'; /* */ -const fetchResolvers = () => { +const fetchRemoteSchemas = () => { return (dispatch, getState) => { const url = Endpoints.getSchema; const options = { @@ -46,7 +48,7 @@ const fetchResolvers = () => { }, }), }; - dispatch({ type: FETCH_RESOLVERS }); + dispatch({ type: FETCH_REMOTE_SCHEMAS }); return dispatch(requestAction(url, options)).then( data => { let consistentRemoteSchemas = data; @@ -61,14 +63,14 @@ const fetchResolvers = () => { } dispatch({ - type: RESOLVERS_FETCH_SUCCESS, + type: REMOTE_SCHEMAS_FETCH_SUCCESS, data: consistentRemoteSchemas, }); return Promise.resolve(); }, error => { - console.error('Failed to load triggers' + JSON.stringify(error)); - dispatch({ type: RESOLVERS_FETCH_FAIL, data: error }); + console.error('Failed to load remote schemas' + JSON.stringify(error)); + dispatch({ type: REMOTE_SCHEMAS_FETCH_FAIL, data: error }); return Promise.reject(); } ); @@ -76,35 +78,35 @@ const fetchResolvers = () => { }; const setConsistentRemoteSchemas = data => ({ - type: SET_CONSISTENT_RESOLVERS, + type: SET_CONSISTENT_REMOTE_SCHEMAS, data, }); const listReducer = (state = listState, action) => { switch (action.type) { - case FETCH_RESOLVERS: + case FETCH_REMOTE_SCHEMAS: return { ...state, isRequesting: true, isError: false, }; - case RESOLVERS_FETCH_SUCCESS: + case REMOTE_SCHEMAS_FETCH_SUCCESS: return { ...state, - resolvers: action.data, + remoteSchemas: action.data, isRequesting: false, isError: false, }; - case RESOLVERS_FETCH_FAIL: + case REMOTE_SCHEMAS_FETCH_FAIL: return { ...state, - resolvers: [], + remoteSchemas: [], isRequesting: false, isError: action.data, }; - case FILTER_RESOLVER: + case FILTER_REMOTE_SCHEMAS: return { ...state, ...action.data, @@ -113,15 +115,15 @@ const listReducer = (state = listState, action) => { return { ...listState, }; - case VIEW_RESOLVER: + case VIEW_REMOTE_SCHEMA: return { ...state, - viewResolver: action.data, + viewRemoteSchema: action.data, }; - case SET_CONSISTENT_RESOLVERS: + case SET_CONSISTENT_REMOTE_SCHEMAS: return { ...state, - resolvers: action.data, + remoteSchemas: action.data, }; default: return { @@ -199,9 +201,9 @@ const makeRequest = ( /* */ export { - fetchResolvers, - FILTER_RESOLVER, - VIEW_RESOLVER, + fetchRemoteSchemas, + FILTER_REMOTE_SCHEMAS, + VIEW_REMOTE_SCHEMA, makeRequest, setConsistentRemoteSchemas, }; diff --git a/console/src/components/Services/CustomResolver/Add/Add.js b/console/src/components/Services/RemoteSchema/Add/Add.js similarity index 84% rename from console/src/components/Services/CustomResolver/Add/Add.js rename to console/src/components/Services/RemoteSchema/Add/Add.js index 1638b8ac39f..3f7badd9b1f 100644 --- a/console/src/components/Services/CustomResolver/Add/Add.js +++ b/console/src/components/Services/RemoteSchema/Add/Add.js @@ -1,7 +1,7 @@ import React from 'react'; import Common from '../Common/Common'; -import { addResolver, RESET } from './addResolverReducer'; +import { addRemoteSchema, RESET } from './addRemoteSchemaReducer'; import Helmet from 'react-helmet'; import Button from '../../../Common/Button/Button'; @@ -13,7 +13,7 @@ class Add extends React.Component { } render() { - const styles = require('../CustomResolver.scss'); + const styles = require('../RemoteSchema.scss'); const { isRequesting, dispatch } = this.props; @@ -24,7 +24,7 @@ class Add extends React.Component {
    { e.preventDefault(); - dispatch(addResolver()); + dispatch(addRemoteSchema()); }} > @@ -50,8 +50,8 @@ class Add extends React.Component { const mapStateToProps = state => { return { - ...state.customResolverData.addData, - ...state.customResolverData.headerData, + ...state.remoteSchemas.addData, + ...state.remoteSchemas.headerData, }; }; diff --git a/console/src/components/Services/CustomResolver/Add/addResolverReducer.js b/console/src/components/Services/RemoteSchema/Add/addRemoteSchemaReducer.js similarity index 77% rename from console/src/components/Services/CustomResolver/Add/addResolverReducer.js rename to console/src/components/Services/RemoteSchema/Add/addRemoteSchemaReducer.js index b016cd88a56..32efa947575 100644 --- a/console/src/components/Services/CustomResolver/Add/addResolverReducer.js +++ b/console/src/components/Services/RemoteSchema/Add/addRemoteSchemaReducer.js @@ -6,10 +6,10 @@ import Endpoints, { globalCookiePolicy } from '../../../../Endpoints'; import requestAction from '../../../../utils/requestAction'; import dataHeaders from '../../Data/Common/Headers'; import { push } from 'react-router-redux'; -import { fetchResolvers } from '../customActions'; +import { fetchRemoteSchemas } from '../Actions'; import { generateHeaderSyms } from '../../../Common/Layout/ReusableHeader/HeaderReducer'; -import { makeRequest } from '../customActions'; +import { makeRequest } from '../Actions'; // import { UPDATE_MIGRATION_STATUS_ERROR } from '../../../Main/Actions'; import { appPrefix } from '../constants'; @@ -18,28 +18,28 @@ import globals from '../../../../Globals'; const prefixUrl = globals.urlPrefix + appPrefix; /* */ -const MANUAL_URL_CHANGED = '@addResolver/MANUAL_URL_CHANGED'; -const ENV_URL_CHANGED = '@addResolver/ENV_URL_CHANGED'; -const NAME_CHANGED = '@addResolver/NAME_CHANGED'; -// const HEADER_CHANGED = '@addResolver/HEADER_CHANGED'; -const ADDING_RESOLVER = '@addResolver/ADDING_RESOLVER'; -const ADD_RESOLVER_FAIL = '@addResolver/ADD_RESOLVER_FAIL'; -const RESET = '@addResolver/RESET'; -const FETCHING_INDIV_RESOLVER = '@addResolver/FETCHING_INDIV_RESOLVER'; -const RESOLVER_FETCH_SUCCESS = '@addResolver/RESOLVER_FETCH_SUCCESS'; -const RESOLVER_FETCH_FAIL = '@addResolver/RESOLVER_FETCH_FAIL'; +const MANUAL_URL_CHANGED = '@addRemoteSchema/MANUAL_URL_CHANGED'; +const ENV_URL_CHANGED = '@addRemoteSchema/ENV_URL_CHANGED'; +const NAME_CHANGED = '@addRemoteSchema/NAME_CHANGED'; +// const HEADER_CHANGED = '@addRemoteSchema/HEADER_CHANGED'; +const ADDING_REMOTE_SCHEMA = '@addRemoteSchema/ADDING_REMOTE_SCHEMA'; +const ADD_REMOTE_SCHEMA_FAIL = '@addRemoteSchema/ADD_REMOTE_SCHEMA_FAIL'; +const RESET = '@addRemoteSchema/RESET'; +const FETCHING_INDIV_REMOTE_SCHEMA = '@addRemoteSchema/FETCHING_INDIV_REMOTE_SCHEMA'; +const REMOTE_SCHEMA_FETCH_SUCCESS = '@addRemoteSchema/REMOTE_SCHEMA_FETCH_SUCCESS'; +const REMOTE_SCHEMA_FETCH_FAIL = '@addRemoteSchema/REMOTE_SCHEMA_FETCH_FAIL'; -const DELETING_RESOLVER = '@addResolver/DELETING_RESOLVER'; -const DELETE_RESOLVER_FAIL = '@addResolver/DELETE_RESOLVER_FAIL'; +const DELETING_REMOTE_SCHEMA = '@addRemoteSchema/DELETING_REMOTE_SCHEMA'; +const DELETE_REMOTE_SCHEMA_FAIL = '@addRemoteSchema/DELETE_REMOTE_SCHEMA_FAIL'; -const MODIFY_RESOLVER_FAIL = '@addResolver/MODIFY_RESOLVER_FAIL'; -const MODIFYING_RESOLVER = '@addResolver/MODIFYING_RESOLVER'; +const MODIFY_REMOTE_SCHEMA_FAIL = '@addRemoteSchema/MODIFY_REMOTE_SCHEMA_FAIL'; +const MODIFYING_REMOTE_SCHEMA = '@addRemoteSchema/MODIFYING_REMOTE_SCHEMA'; const UPDATE_FORWARD_CLIENT_HEADERS = - '@addResolver/UPDATE_FORWARD_CLIENT_HEADERS'; + '@addRemoteSchema/UPDATE_FORWARD_CLIENT_HEADERS'; /* */ -const TOGGLE_MODIFY = '@editResolver/TOGGLE_MODIFY'; +const TOGGLE_MODIFY = '@editRemoteSchema/TOGGLE_MODIFY'; /* */ /* */ @@ -54,7 +54,7 @@ const inputChange = (type, data) => { return dispatch => dispatch({ type: inputEventMap[type], data }); }; -const getHeaderEvents = generateHeaderSyms('CUSTOM_RESOLVER'); +const getHeaderEvents = generateHeaderSyms('CUSTOM_REMOTE_SCHEMA'); /* */ const getReqHeader = headers => { @@ -80,7 +80,7 @@ const getReqHeader = headers => { return requestHeaders; }; -const fetchResolver = resolver => { +const fetchRemoteSchema = remoteSchema => { return (dispatch, getState) => { const url = Endpoints.getSchema; const options = { @@ -96,16 +96,16 @@ const fetchResolver = resolver => { }, columns: ['*'], where: { - name: resolver, + name: remoteSchema, }, }, }), }; - dispatch({ type: FETCHING_INDIV_RESOLVER }); + dispatch({ type: FETCHING_INDIV_REMOTE_SCHEMA }); return dispatch(requestAction(url, options)).then( data => { if (data.length > 0) { - dispatch({ type: RESOLVER_FETCH_SUCCESS, data: data }); + dispatch({ type: REMOTE_SCHEMA_FETCH_SUCCESS, data: data }); const headerObj = []; data[0].definition.headers.forEach(d => { headerObj.push({ @@ -128,16 +128,16 @@ const fetchResolver = resolver => { return dispatch(push(`${prefixUrl}`)); }, error => { - console.error('Failed to fetch resolver' + JSON.stringify(error)); - return dispatch({ type: RESOLVER_FETCH_FAIL, data: error }); + console.error('Failed to fetch remoteSchema' + JSON.stringify(error)); + return dispatch({ type: REMOTE_SCHEMA_FETCH_FAIL, data: error }); } ); }; }; -const addResolver = () => { +const addRemoteSchema = () => { return (dispatch, getState) => { - const currState = getState().customResolverData.addData; + const currState = getState().remoteSchemas.addData; // const url = Endpoints.getSchema; const resolveObj = { name: currState.name.trim().replace(/ +/g, ''), @@ -150,7 +150,7 @@ const addResolver = () => { }; resolveObj.definition.headers = [ - ...getReqHeader(getState().customResolverData.headerData.headers), + ...getReqHeader(getState().remoteSchemas.headerData.headers), ]; if (resolveObj.definition.url) { delete resolveObj.definition.url_from_env; @@ -197,7 +197,7 @@ const addResolver = () => { const customOnSuccess = data => { Promise.all([ dispatch({ type: RESET }), - dispatch(fetchResolvers()).then(() => { + dispatch(fetchRemoteSchemas()).then(() => { dispatch(push(`${prefixUrl}/manage/${resolveObj.name}/details`)); }), dispatch({ type: getHeaderEvents.RESET_HEADER, data: data }), @@ -205,11 +205,11 @@ const addResolver = () => { }; const customOnError = err => { console.error('Failed to create remote schema' + JSON.stringify(err)); - dispatch({ type: ADD_RESOLVER_FAIL, data: err }); + dispatch({ type: ADD_REMOTE_SCHEMA_FAIL, data: err }); // dispatch({ type: UPDATE_MIGRATION_STATUS_ERROR, data: err }); // alert(JSON.stringify(err)); }; - dispatch({ type: ADDING_RESOLVER }); + dispatch({ type: ADDING_REMOTE_SCHEMA }); return dispatch( makeRequest( upQuery.args, @@ -225,9 +225,9 @@ const addResolver = () => { }; }; -const deleteResolver = () => { +const deleteRemoteSchema = () => { return (dispatch, getState) => { - const currState = getState().customResolverData.addData; + const currState = getState().remoteSchemas.addData; // const url = Endpoints.getSchema; const resolveObj = { name: currState.editState.originalName, @@ -279,14 +279,14 @@ const deleteResolver = () => { Promise.all([ dispatch({ type: RESET }), dispatch(push(prefixUrl)), - dispatch(fetchResolvers()), + dispatch(fetchRemoteSchemas()), ]); }; const customOnError = error => { - Promise.all([dispatch({ type: DELETE_RESOLVER_FAIL, data: error })]); + Promise.all([dispatch({ type: DELETE_REMOTE_SCHEMA_FAIL, data: error })]); }; - dispatch({ type: DELETING_RESOLVER }); + dispatch({ type: DELETING_REMOTE_SCHEMA }); return dispatch( makeRequest( upQuery.args, @@ -302,15 +302,15 @@ const deleteResolver = () => { }; }; -const modifyResolver = () => { +const modifyRemoteSchema = () => { return (dispatch, getState) => { - const currState = getState().customResolverData.addData; + const currState = getState().remoteSchemas.addData; const remoteSchemaName = currState.name.trim().replace(/ +/g, ''); // const url = Endpoints.getSchema; const upQueryArgs = []; const downQueryArgs = []; const migrationName = 'update_remote_schema_' + remoteSchemaName; - const deleteResolverUp = { + const deleteRemoteSchemaUp = { type: 'remove_remote_schema', args: { name: currState.editState.originalName, @@ -327,7 +327,7 @@ const modifyResolver = () => { }; resolveObj.definition.headers = [ - ...getReqHeader(getState().customResolverData.headerData.headers), + ...getReqHeader(getState().remoteSchemas.headerData.headers), ]; if (resolveObj.definition.url) { delete resolveObj.definition.url_from_env; @@ -335,17 +335,17 @@ const modifyResolver = () => { delete resolveObj.definition.url; } - const createResolverUp = { + const createRemoteSchemaUp = { type: 'add_remote_schema', args: { ...resolveObj, }, }; - upQueryArgs.push(deleteResolverUp); - upQueryArgs.push(createResolverUp); + upQueryArgs.push(deleteRemoteSchemaUp); + upQueryArgs.push(createRemoteSchemaUp); // Delete the new one and create the old one - const deleteResolverDown = { + const deleteRemoteSchemaDown = { type: 'remove_remote_schema', args: { name: remoteSchemaName, @@ -371,14 +371,14 @@ const modifyResolver = () => { delete resolveDownObj.definition.url; } - const createResolverDown = { + const createRemoteSchemaDown = { type: 'add_remote_schema', args: { ...resolveDownObj, }, }; - downQueryArgs.push(deleteResolverDown); - downQueryArgs.push(createResolverDown); + downQueryArgs.push(deleteRemoteSchemaDown); + downQueryArgs.push(createRemoteSchemaDown); // End of down const upQuery = { @@ -397,16 +397,16 @@ const modifyResolver = () => { // dispatch({ type: REQUEST_SUCCESS }); dispatch({ type: RESET, data: data }); dispatch(push(`${prefixUrl}/manage/schemas`)); // to avoid 404 - dispatch(fetchResolvers()).then(() => { + dispatch(fetchRemoteSchemas()).then(() => { dispatch(push(`${prefixUrl}/manage/${remoteSchemaName}/details`)); }); - dispatch(fetchResolver(remoteSchemaName)); + dispatch(fetchRemoteSchema(remoteSchemaName)); }; const customOnError = error => { - Promise.all([dispatch({ type: MODIFY_RESOLVER_FAIL, data: error })]); + Promise.all([dispatch({ type: MODIFY_REMOTE_SCHEMA_FAIL, data: error })]); }; - dispatch({ type: MODIFYING_RESOLVER }); + dispatch({ type: MODIFYING_REMOTE_SCHEMA }); return dispatch( makeRequest( upQuery.args, @@ -422,7 +422,7 @@ const modifyResolver = () => { }; }; -const addResolverReducer = (state = addState, action) => { +const addRemoteSchemaReducer = (state = addState, action) => { switch (action.type) { case MANUAL_URL_CHANGED: return { @@ -441,13 +441,13 @@ const addResolverReducer = (state = addState, action) => { envName: action.data, manualUrl: null, }; - case ADDING_RESOLVER: + case ADDING_REMOTE_SCHEMA: return { ...state, isRequesting: true, isError: null, }; - case ADD_RESOLVER_FAIL: + case ADD_REMOTE_SCHEMA_FAIL: return { ...state, isRequesting: false, @@ -467,13 +467,13 @@ const addResolverReducer = (state = addState, action) => { return { ...addState, }; - case FETCHING_INDIV_RESOLVER: + case FETCHING_INDIV_REMOTE_SCHEMA: return { ...state, isFetching: true, isFetchError: null, }; - case RESOLVER_FETCH_SUCCESS: + case REMOTE_SCHEMA_FETCH_SUCCESS: return { ...state, name: action.data[0].name, @@ -495,31 +495,31 @@ const addResolverReducer = (state = addState, action) => { isFetching: false, isFetchError: null, }; - case RESOLVER_FETCH_FAIL: + case REMOTE_SCHEMA_FETCH_FAIL: return { ...state, isFetching: false, isFetchError: action.data, }; - case DELETE_RESOLVER_FAIL: + case DELETE_REMOTE_SCHEMA_FAIL: return { ...state, isRequesting: false, isError: action.data, }; - case DELETING_RESOLVER: + case DELETING_REMOTE_SCHEMA: return { ...state, isRequesting: true, isError: null, }; - case MODIFY_RESOLVER_FAIL: + case MODIFY_REMOTE_SCHEMA_FAIL: return { ...state, isRequesting: false, isError: action.data, }; - case MODIFYING_RESOLVER: + case MODIFYING_REMOTE_SCHEMA: return { ...state, isRequesting: true, @@ -539,14 +539,14 @@ const addResolverReducer = (state = addState, action) => { export { inputChange, - addResolver, - fetchResolver, - deleteResolver, - modifyResolver, + addRemoteSchema, + fetchRemoteSchema, + deleteRemoteSchema, + modifyRemoteSchema, RESET, TOGGLE_MODIFY, UPDATE_FORWARD_CLIENT_HEADERS, getHeaderEvents, }; -export default addResolverReducer; +export default addRemoteSchemaReducer; diff --git a/console/src/components/Services/CustomResolver/Common/Common.js b/console/src/components/Services/RemoteSchema/Common/Common.js similarity index 97% rename from console/src/components/Services/CustomResolver/Common/Common.js rename to console/src/components/Services/RemoteSchema/Common/Common.js index 0184ec1c7f4..ef197527856 100644 --- a/console/src/components/Services/CustomResolver/Common/Common.js +++ b/console/src/components/Services/RemoteSchema/Common/Common.js @@ -7,7 +7,7 @@ import DropdownButton from '../../../Common/DropdownButton/DropdownButton'; import { inputChange, UPDATE_FORWARD_CLIENT_HEADERS, -} from '../Add/addResolverReducer'; +} from '../Add/addRemoteSchemaReducer'; import CommonHeader from '../../../Common/Layout/ReusableHeader/Header'; @@ -34,7 +34,7 @@ class Common extends React.Component { } render() { - const styles = require('../CustomResolver.scss'); + const styles = require('../RemoteSchema.scss'); const { name, manualUrl, envName, forwardClientHeaders } = this.props; const { isModify, id } = this.props.editState; @@ -163,7 +163,7 @@ class Common extends React.Component {
    r.name === this.props.params.resolverName + const currentRemoteSchema = this.props.allRemoteSchemas.find( + r => r.name === this.props.params.remoteSchemaName ); - if (!currentResolver) { + if (!currentRemoteSchema) { // throw a 404 exception throw new NotFoundError(); } - const styles = require('../CustomResolver.scss'); + const styles = require('../RemoteSchema.scss'); const { isFetching, isRequesting, editState } = this.props; - const { resolverName } = this.props.params; + const { remoteSchemaName } = this.props.params; const generateMigrateBtns = () => { return 'isModify' in editState && !editState.isModify ? ( @@ -150,7 +154,7 @@ class Edit extends React.Component { size="sm" onClick={e => { e.preventDefault(); - this.handleDeleteResolver(e); + this.handleDeleteRemoteSchema(e); }} disabled={isRequesting} data-test={'remote-schema-edit-delete-btn'} @@ -205,15 +209,15 @@ class Edit extends React.Component { }, ]; - if (resolverName) { + if (remoteSchemaName) { breadCrumbs.push({ - title: resolverName.trim(), + title: remoteSchemaName.trim(), url: appPrefix + '/' + 'manage' + '/' + - resolverName.trim() + + remoteSchemaName.trim() + '/' + 'details', }); @@ -226,15 +230,15 @@ class Edit extends React.Component { return (
    {isFetching ? null : ( @@ -254,9 +258,9 @@ class Edit extends React.Component { } const mapStateToProps = state => { return { - ...state.customResolverData.addData, - ...state.customResolverData.headerData, - allResolvers: state.customResolverData.listData.resolvers, + ...state.remoteSchemas.addData, + ...state.remoteSchemas.headerData, + allRemoteSchemas: state.remoteSchemas.listData.remoteSchemas, dataHeaders: { ...state.tables.dataHeaders }, }; }; diff --git a/console/src/components/Services/CustomResolver/Edit/View.js b/console/src/components/Services/RemoteSchema/Edit/View.js similarity index 76% rename from console/src/components/Services/CustomResolver/Edit/View.js rename to console/src/components/Services/RemoteSchema/Edit/View.js index f0e909d8975..3a40853ab6b 100644 --- a/console/src/components/Services/CustomResolver/Edit/View.js +++ b/console/src/components/Services/RemoteSchema/Edit/View.js @@ -7,12 +7,12 @@ import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; import { push } from 'react-router-redux'; import { - fetchResolver, + fetchRemoteSchema, RESET, getHeaderEvents, -} from '../Add/addResolverReducer'; +} from '../Add/addRemoteSchemaReducer'; -import { VIEW_RESOLVER } from '../customActions'; +import { VIEW_REMOTE_SCHEMA } from '../Actions'; import ReloadRemoteSchema from '../../Metadata/MetadataOptions/ReloadRemoteSchema'; import { appPrefix } from '../constants'; @@ -25,23 +25,27 @@ const prefixUrl = globals.urlPrefix + appPrefix; class ViewStitchedSchema extends React.Component { componentDidMount() { - const { resolverName } = this.props.params; - if (!resolverName) { + const { remoteSchemaName } = this.props.params; + if (!remoteSchemaName) { this.props.dispatch(push(prefixUrl)); } Promise.all([ - this.props.dispatch(fetchResolver(resolverName)), - this.props.dispatch({ type: VIEW_RESOLVER, data: resolverName }), + this.props.dispatch(fetchRemoteSchema(remoteSchemaName)), + this.props.dispatch({ type: VIEW_REMOTE_SCHEMA, data: remoteSchemaName }), ]); } componentWillReceiveProps(nextProps) { - if (nextProps.params.resolverName !== this.props.params.resolverName) { + if ( + nextProps.params.remoteSchemaName !== this.props.params.remoteSchemaName + ) { Promise.all([ - this.props.dispatch(fetchResolver(nextProps.params.resolverName)), + this.props.dispatch( + fetchRemoteSchema(nextProps.params.remoteSchemaName) + ), this.props.dispatch({ - type: VIEW_RESOLVER, - data: nextProps.params.resolverName, + type: VIEW_REMOTE_SCHEMA, + data: nextProps.params.remoteSchemaName, }), ]); } @@ -60,23 +64,23 @@ class ViewStitchedSchema extends React.Component { }, ], }), - this.props.dispatch({ type: VIEW_RESOLVER, data: '' }), + this.props.dispatch({ type: VIEW_REMOTE_SCHEMA, data: '' }), ]); } render() { - const currentResolver = this.props.allResolvers.find( - r => r.name === this.props.params.resolverName + const currentRemoteSchema = this.props.allRemoteSchemas.find( + r => r.name === this.props.params.remoteSchemaName ); - if (!currentResolver) { + if (!currentRemoteSchema) { // throw a 404 exception throw new NotFoundError(); } - const styles = require('../CustomResolver.scss'); + const styles = require('../RemoteSchema.scss'); - const { resolverName } = this.props.params; + const { remoteSchemaName } = this.props.params; const { manualUrl, envName, headers } = this.props; const filterHeaders = headers.filter(h => !!h.name); @@ -92,15 +96,15 @@ class ViewStitchedSchema extends React.Component { }, ]; - if (resolverName) { + if (remoteSchemaName) { breadCrumbs.push({ - title: resolverName.trim(), + title: remoteSchemaName.trim(), url: appPrefix + '/' + 'manage' + '/' + - resolverName.trim() + + remoteSchemaName.trim() + '/' + 'details', }); @@ -118,12 +122,12 @@ class ViewStitchedSchema extends React.Component { ); const showReloadRemoteSchema = - resolverName && resolverName.length > 0 ? ( + remoteSchemaName && remoteSchemaName.length > 0 ? (
    @@ -141,10 +145,10 @@ class ViewStitchedSchema extends React.Component {
    @@ -197,9 +201,9 @@ class ViewStitchedSchema extends React.Component { const mapStateToProps = state => { return { - ...state.customResolverData.addData, - ...state.customResolverData.headerData, - allResolvers: state.customResolverData.listData.resolvers, + ...state.remoteSchemas.addData, + ...state.remoteSchemas.headerData, + allRemoteSchemas: state.remoteSchemas.listData.remoteSchemas, dataHeaders: { ...state.tables.dataHeaders }, }; }; diff --git a/console/src/components/Services/CustomResolver/Edit/tabInfo.js b/console/src/components/Services/RemoteSchema/Edit/tabInfo.js similarity index 100% rename from console/src/components/Services/CustomResolver/Edit/tabInfo.js rename to console/src/components/Services/RemoteSchema/Edit/tabInfo.js diff --git a/console/src/components/Services/CustomResolver/Landing/CustomResolver.js b/console/src/components/Services/RemoteSchema/Landing/RemoteSchema.js similarity index 87% rename from console/src/components/Services/CustomResolver/Landing/CustomResolver.js rename to console/src/components/Services/RemoteSchema/Landing/RemoteSchema.js index ce60b0be8df..f7fea7fd694 100644 --- a/console/src/components/Services/CustomResolver/Landing/CustomResolver.js +++ b/console/src/components/Services/RemoteSchema/Landing/RemoteSchema.js @@ -8,12 +8,12 @@ import Button from '../../../Common/Button/Button'; import TopicDescription from '../../Common/Landing/TopicDescription'; import TryItOut from '../../Common/Landing/TryItOut'; -class CustomResolver extends React.Component { +class RemoteSchema extends React.Component { render() { - const styles = require('../CustomResolver.scss'); + const styles = require('../RemoteSchema.scss'); - const { dispatch, customResolverList } = this.props; - const showIntroSection = !customResolverList.resolvers.length; + const { dispatch, remoteSchemaList } = this.props; + const showIntroSection = !remoteSchemaList.remoteSchemas.length; const getIntroSection = () => { if (!showIntroSection) { return null; @@ -58,7 +58,7 @@ class CustomResolver extends React.Component { return (
    @@ -95,11 +95,10 @@ class CustomResolver extends React.Component { const mapStateToProps = state => { return { - customResolverList: state.customResolverData.listData, + remoteSchemaList: state.remoteSchemas.listData, }; }; -const customResolverConnector = connect => - connect(mapStateToProps)(CustomResolver); +const remoteSchemaConnector = connect => connect(mapStateToProps)(RemoteSchema); -export default customResolverConnector; +export default remoteSchemaConnector; diff --git a/console/src/components/Services/CustomResolver/CustomResolver.scss b/console/src/components/Services/RemoteSchema/RemoteSchema.scss similarity index 98% rename from console/src/components/Services/CustomResolver/CustomResolver.scss rename to console/src/components/Services/RemoteSchema/RemoteSchema.scss index e4383136835..aa815bcd459 100644 --- a/console/src/components/Services/CustomResolver/CustomResolver.scss +++ b/console/src/components/Services/RemoteSchema/RemoteSchema.scss @@ -29,16 +29,16 @@ padding-top: 10px !important; } -.resolverWrapper { +.remoteSchemaWrapper { // padding: 10px 0; - .resolverContent { + .remoteSchemaContent { text-align: center; padding-bottom: 10px; font-weight: 600; } - .resolverImg { + .remoteSchemaImg { width: 100%; padding: 20px; text-align: center; diff --git a/console/src/components/Services/CustomResolver/CustomResolverPageContainer.js b/console/src/components/Services/RemoteSchema/RemoteSchemaPageContainer.js similarity index 82% rename from console/src/components/Services/CustomResolver/CustomResolverPageContainer.js rename to console/src/components/Services/RemoteSchema/RemoteSchemaPageContainer.js index 066405668a9..6b52f2c4f43 100644 --- a/console/src/components/Services/CustomResolver/CustomResolverPageContainer.js +++ b/console/src/components/Services/RemoteSchema/RemoteSchemaPageContainer.js @@ -4,9 +4,9 @@ import PropTypes from 'prop-types'; import LeftContainer from '../../Common/Layout/LeftContainer/LeftContainer'; import PageContainer from '../../Common/Layout/PageContainer/PageContainer'; -import CustomResolverSubSidebar from './CustomResolverSubSidebar'; +import RemoteSchemaSubSidebar from './RemoteSchemaSubSidebar'; -class CustomResolverPageContainer extends React.Component { +class RemoteSchemaPageContainer extends React.Component { render() { const styles = require('../../Common/TableCommon/Table.scss'); const { appPrefix, children } = this.props; @@ -26,7 +26,7 @@ class CustomResolverPageContainer extends React.Component { Manage - +
  • ); @@ -43,7 +43,7 @@ class CustomResolverPageContainer extends React.Component { } } -CustomResolverPageContainer.propTypes = { +RemoteSchemaPageContainer.propTypes = { appPrefix: PropTypes.string.isRequired, }; @@ -51,4 +51,4 @@ export default (connect, mapStateToProps, mapDispatchToProps) => connect( mapStateToProps, mapDispatchToProps - )(CustomResolverPageContainer); + )(RemoteSchemaPageContainer); diff --git a/console/src/components/Services/CustomResolver/CustomResolverRouter.js b/console/src/components/Services/RemoteSchema/RemoteSchemaRouter.js similarity index 62% rename from console/src/components/Services/CustomResolver/CustomResolverRouter.js rename to console/src/components/Services/RemoteSchema/RemoteSchemaRouter.js index a670f0c90f0..a9e9d5f98da 100644 --- a/console/src/components/Services/CustomResolver/CustomResolverRouter.js +++ b/console/src/components/Services/RemoteSchema/RemoteSchemaRouter.js @@ -4,18 +4,18 @@ import { Route, IndexRedirect } from 'react-router'; import { rightContainerConnector } from '../../Common/Layout'; import globals from '../../../Globals'; import { - customResolverPageConnector, + remoteSchemaPageConnector, landingConnector, addConnector, editConnector, viewConnector, } from '.'; -import { fetchResolvers, FILTER_RESOLVER } from './customActions'; +import { fetchRemoteSchemas, FILTER_REMOTE_SCHEMAS } from './Actions'; -// Objective is to render list of custom resolvers on the +// Objective is to render list of custom remoteSchemas on the // left nav bar. -// Custom resolvers list is fetched from hdb_catalog/custom_resolver -// Whenever any operation happens like add resolver/delete resolver, this state should update automatically. +// Custom remoteSchemas list is fetched from hdb_catalog/custom_remoteSchema +// Whenever any operation happens like add remoteSchema/delete remoteSchema, this state should update automatically. import { appPrefix } from './constants'; @@ -30,7 +30,7 @@ const filterItem = dispatch => { ); }); dispatch({ - type: FILTER_RESOLVER, + type: FILTER_REMOTE_SCHEMAS, data: { filtered: matchedTables, searchQuery: searchVal, @@ -42,12 +42,12 @@ const filterItem = dispatch => { const leftNavMapStateToProps = state => { return { ...state, - dataList: [...state.customResolverData.listData.resolvers], - isError: state.customResolverData.listData.isError, - isRequesting: state.customResolverData.listData.isRequesting, - filtered: [...state.customResolverData.listData.filtered], - searchQuery: state.customResolverData.listData.searchQuery, - viewResolver: state.customResolverData.listData.viewResolver, + dataList: [...state.remoteSchemas.listData.remoteSchemas], + isError: state.remoteSchemas.listData.isError, + isRequesting: state.remoteSchemas.listData.isRequesting, + filtered: [...state.remoteSchemas.listData.filtered], + searchQuery: state.remoteSchemas.listData.searchQuery, + viewRemoteSchema: state.remoteSchemas.listData.viewRemoteSchema, appPrefix, }; }; @@ -62,14 +62,14 @@ const fetchInitialData = ({ dispatch }) => { return (nextState, replaceState, cb) => { /* const currState = getState(); - const dataList = currState.customResolverData.listData.resolvers; + const dataList = currState.remoteSchemas.listData.remoteSchemas; if (dataList.length) { cb(); return; } */ - Promise.all([dispatch(fetchResolvers())]).then( + Promise.all([dispatch(fetchRemoteSchemas())]).then( () => { cb(); }, @@ -82,11 +82,11 @@ const fetchInitialData = ({ dispatch }) => { }; }; -const getCustomResolverRouter = (connect, store, composeOnEnterHooks) => { +const getRemoteSchemaRouter = (connect, store, composeOnEnterHooks) => { return ( { - + ); }; -export default getCustomResolverRouter; +export default getRemoteSchemaRouter; export { appPrefix }; diff --git a/console/src/components/Services/CustomResolver/CustomResolverSubSidebar.js b/console/src/components/Services/RemoteSchema/RemoteSchemaSubSidebar.js similarity index 91% rename from console/src/components/Services/CustomResolver/CustomResolverSubSidebar.js rename to console/src/components/Services/RemoteSchema/RemoteSchemaSubSidebar.js index 923e01e8465..f14299d4153 100644 --- a/console/src/components/Services/CustomResolver/CustomResolverSubSidebar.js +++ b/console/src/components/Services/RemoteSchema/RemoteSchemaSubSidebar.js @@ -3,14 +3,14 @@ import { Link } from 'react-router'; import LeftSubSidebar from '../../Common/Layout/LeftSubSidebar/LeftSubSidebar'; -const CustomResolverSubSidebar = ({ +const RemoteSchemaSubSidebar = ({ appPrefix, dataList, filtered, searchQuery, location, filterItem, - viewResolver, + viewRemoteSchema, }) => { const styles = require('../../Common/Layout/LeftSubSidebar/LeftSubSidebar.scss'); @@ -48,8 +48,8 @@ const CustomResolverSubSidebar = ({ childList = _dataList.map((d, i) => { let activeTableClass = ''; if ( - d.name === viewResolver && - location.pathname.includes(viewResolver) + d.name === viewRemoteSchema && + location.pathname.includes(viewRemoteSchema) ) { activeTableClass = styles.activeTable; } @@ -93,4 +93,4 @@ const CustomResolverSubSidebar = ({ ); }; -export default CustomResolverSubSidebar; +export default RemoteSchemaSubSidebar; diff --git a/console/src/components/Services/CustomResolver/constants.js b/console/src/components/Services/RemoteSchema/constants.js similarity index 100% rename from console/src/components/Services/CustomResolver/constants.js rename to console/src/components/Services/RemoteSchema/constants.js diff --git a/console/src/components/Services/RemoteSchema/index.js b/console/src/components/Services/RemoteSchema/index.js new file mode 100644 index 00000000000..90f43a2d0fd --- /dev/null +++ b/console/src/components/Services/RemoteSchema/index.js @@ -0,0 +1,9 @@ +export remoteSchemaPageConnector from './RemoteSchemaPageContainer'; +export landingConnector from './Landing/RemoteSchema'; +export addConnector from './Add/Add'; +export editConnector from './Edit/Edit'; +export viewConnector from './Edit/View'; + +export getRemoteSchemaRouter from './RemoteSchemaRouter'; + +export remoteSchemaReducer from './remoteSchemaReducer'; diff --git a/console/src/components/Services/CustomResolver/customResolverReducer.js b/console/src/components/Services/RemoteSchema/remoteSchemaReducer.js similarity index 51% rename from console/src/components/Services/CustomResolver/customResolverReducer.js rename to console/src/components/Services/RemoteSchema/remoteSchemaReducer.js index 435fc57decc..a0e9e193aea 100644 --- a/console/src/components/Services/CustomResolver/customResolverReducer.js +++ b/console/src/components/Services/RemoteSchema/remoteSchemaReducer.js @@ -1,13 +1,13 @@ import { combineReducers } from 'redux'; -import listReducer from './customActions'; -import addReducer from './Add/addResolverReducer'; +import listReducer from './Actions'; +import addReducer from './Add/addRemoteSchemaReducer'; import headerReducer from '../../Common/Layout/ReusableHeader/HeaderReducer'; -const customResolverReducer = combineReducers({ +const remoteSchemaReducer = combineReducers({ addData: addReducer, listData: listReducer, - headerData: headerReducer('CUSTOM_RESOLVER', [ + headerData: headerReducer('REMOTE_SCHEMA', [ { name: '', type: 'static', @@ -16,4 +16,4 @@ const customResolverReducer = combineReducers({ ]), }); -export default customResolverReducer; +export default remoteSchemaReducer; diff --git a/console/src/components/Services/CustomResolver/state.js b/console/src/components/Services/RemoteSchema/state.js similarity index 92% rename from console/src/components/Services/CustomResolver/state.js rename to console/src/components/Services/RemoteSchema/state.js index 89b8bc073a2..205c28abe6b 100644 --- a/console/src/components/Services/CustomResolver/state.js +++ b/console/src/components/Services/RemoteSchema/state.js @@ -6,10 +6,10 @@ const asyncState = { }; const listState = { - resolvers: [], + remoteSchemas: [], filtered: [], searchQuery: '', - viewResolver: '', + viewRemoteSchema: '', ...asyncState, }; diff --git a/console/src/reducer.js b/console/src/reducer.js index 157cb698d25..01e20cc3251 100644 --- a/console/src/reducer.js +++ b/console/src/reducer.js @@ -2,7 +2,7 @@ import { combineReducers } from 'redux'; import { routerReducer } from 'react-router-redux'; import { dataReducer } from './components/Services/Data'; import { eventReducer } from './components/Services/EventTrigger'; -import { customResolverReducer } from './components/Services/CustomResolver'; +import { remoteSchemaReducer } from './components/Services/RemoteSchema'; import mainReducer from './components/Main/Actions'; import apiExplorerReducer from 'components/Services/ApiExplorer/Actions'; import progressBarReducer from 'components/App/Actions'; @@ -18,7 +18,7 @@ const reducer = combineReducers({ apiexplorer: apiExplorerReducer, main: mainReducer, routing: routerReducer, - customResolverData: customResolverReducer, + remoteSchemas: remoteSchemaReducer, telemetry: telemetryReducer, notifications, metadata: metadataReducer, diff --git a/console/src/routes.js b/console/src/routes.js index ab4393aceaa..9dc4683a062 100644 --- a/console/src/routes.js +++ b/console/src/routes.js @@ -17,7 +17,7 @@ import { dataRouterUtils } from './components/Services/Data'; import { eventRouterUtils } from './components/Services/EventTrigger'; -import { getCustomResolverRouter } from './components/Services/CustomResolver'; +import { getRemoteSchemaRouter } from './components/Services/RemoteSchema'; import generatedApiExplorer from './components/Services/ApiExplorer/ApiExplorerGenerator'; @@ -77,7 +77,7 @@ const routes = store => { ); const eventRouter = _eventRouterUtils.makeEventRouter; - const customResolverRouter = getCustomResolverRouter( + const remoteSchemaRouter = getRemoteSchemaRouter( connect, store, composeOnEnterHooks @@ -116,7 +116,7 @@ const routes = store => { {dataRouter} {eventRouter} - {customResolverRouter} + {remoteSchemaRouter}